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 (
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 (
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 (
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 (std::set<types::global_dof_index>::iterator it =
887 dofs_with_support_on_halo_cells.begin();
888 it != dofs_with_support_on_halo_cells.end();
895 const unsigned int line_size = line_ptr->size();
896 for (
unsigned int j = 0; j < line_size; ++j)
897 extra_halo.insert((*line_ptr)[j].first);
900 dofs_with_support_on_halo_cells.insert(extra_halo.begin(),
906 IndexSet support_set(dof_handler.n_dofs());
907 support_set.
add_indices(predicate_dofs.begin(), predicate_dofs.end());
908 support_set.compress();
910 IndexSet halo_set(dof_handler.n_dofs());
911 halo_set.
add_indices(dofs_with_support_on_halo_cells.begin(),
912 dofs_with_support_on_halo_cells.end());
915 support_set.subtract_set(halo_set);
927 template <
int spacedim>
930 const ::DoFHandler<1, spacedim> &dof_handler)
933 return IndexSet(dof_handler.n_dofs());
937 template <
int spacedim>
940 const ::DoFHandler<2, spacedim> &dof_handler)
942 const unsigned int dim = 2;
944 IndexSet selected_dofs(dof_handler.n_dofs());
950 for (
auto cell : dof_handler.active_cell_iterators())
951 if (!cell->is_artificial())
953 for (
unsigned int face = 0;
954 face < GeometryInfo<dim>::faces_per_cell;
956 if (cell->face(face)->has_children())
958 const typename ::DoFHandler<dim,
959 spacedim>::line_iterator
960 line = cell->face(face);
962 for (
unsigned int dof = 0; dof != fe.dofs_per_vertex; ++dof)
963 selected_dofs.add_index(
964 line->child(0)->vertex_dof_index(1, dof));
966 for (
unsigned int child = 0; child < 2; ++child)
968 if (cell->neighbor_child_on_subface(face, child)
971 for (
unsigned int dof = 0; dof != fe.dofs_per_line;
973 selected_dofs.add_index(
974 line->child(child)->dof_index(dof));
979 selected_dofs.compress();
980 return selected_dofs;
984 template <
int spacedim>
987 const ::DoFHandler<3, spacedim> &dof_handler)
989 const unsigned int dim = 3;
991 IndexSet selected_dofs(dof_handler.n_dofs());
992 IndexSet unconstrained_dofs(dof_handler.n_dofs());
996 for (
auto cell : dof_handler.active_cell_iterators())
997 if (!cell->is_artificial())
998 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
1000 const typename ::DoFHandler<dim, spacedim>::face_iterator
1001 face = cell->face(f);
1002 if (cell->face(f)->has_children())
1004 for (
unsigned int child = 0; child < 4; ++child)
1005 if (!cell->neighbor_child_on_subface(f, child)
1009 std::vector<types::global_dof_index> ldi(
1011 face->child(child)->get_dof_indices(ldi);
1012 selected_dofs.add_indices(ldi.begin(), ldi.end());
1017 for (
unsigned int vertex = 0; vertex < 4; ++vertex)
1018 for (
unsigned int dof = 0; dof != fe.dofs_per_vertex;
1020 unconstrained_dofs.add_index(
1021 face->vertex_dof_index(vertex, dof));
1024 selected_dofs.subtract_set(unconstrained_dofs);
1025 return selected_dofs;
1032 template <
int dim,
int spacedim>
1035 std::vector<bool> & selected_dofs)
1037 const IndexSet selected_dofs_as_index_set =
1042 std::fill(selected_dofs.begin(), selected_dofs.end(),
false);
1043 for (
const auto index : selected_dofs_as_index_set)
1044 selected_dofs[index] =
true;
1049 template <
int dim,
int spacedim>
1053 return internal::extract_hanging_node_dofs(dof_handler);
1058 template <
typename DoFHandlerType>
1062 std::vector<bool> & selected_dofs)
1064 Assert(selected_dofs.size() == dof_handler.n_dofs(),
1068 std::fill_n(selected_dofs.begin(), dof_handler.n_dofs(),
false);
1070 std::vector<types::global_dof_index> local_dof_indices;
1075 typename DoFHandlerType::active_cell_iterator cell =
1076 dof_handler.begin_active(),
1077 endc = dof_handler.end();
1078 for (; cell != endc; ++cell)
1079 if (cell->subdomain_id() == subdomain_id)
1081 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
1082 local_dof_indices.resize(dofs_per_cell);
1083 cell->get_dof_indices(local_dof_indices);
1084 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1085 selected_dofs[local_dof_indices[i]] =
true;
1091 template <
typename DoFHandlerType>
1097 dof_set = dof_handler.locally_owned_dofs();
1103 template <
typename DoFHandlerType>
1109 dof_set = dof_handler.locally_owned_dofs();
1114 std::vector<types::global_dof_index> dof_indices;
1115 std::set<types::global_dof_index> global_dof_indices;
1117 typename DoFHandlerType::active_cell_iterator cell =
1118 dof_handler.begin_active(),
1119 endc = dof_handler.
end();
1120 for (; cell != endc; ++cell)
1121 if (cell->is_locally_owned())
1123 dof_indices.resize(cell->get_fe().dofs_per_cell);
1124 cell->get_dof_indices(dof_indices);
1126 for (std::vector<types::global_dof_index>::iterator it =
1127 dof_indices.begin();
1128 it != dof_indices.end();
1131 global_dof_indices.insert(*it);
1134 dof_set.
add_indices(global_dof_indices.begin(), global_dof_indices.end());
1141 template <
typename DoFHandlerType>
1147 dof_set = dof_handler.locally_owned_dofs();
1157 std::vector<types::global_dof_index> dof_indices;
1158 std::vector<types::global_dof_index> dofs_on_ghosts;
1160 typename DoFHandlerType::active_cell_iterator cell =
1161 dof_handler.begin_active(),
1162 endc = dof_handler.
end();
1163 for (; cell != endc; ++cell)
1164 if (cell->is_ghost())
1166 dof_indices.resize(cell->get_fe().dofs_per_cell);
1167 cell->get_dof_indices(dof_indices);
1168 for (
unsigned int i = 0; i < dof_indices.size(); ++i)
1170 dofs_on_ghosts.push_back(dof_indices[i]);
1174 std::sort(dofs_on_ghosts.begin(), dofs_on_ghosts.end());
1176 std::unique(dofs_on_ghosts.begin(),
1177 dofs_on_ghosts.end()));
1183 template <
typename DoFHandlerType>
1186 const unsigned int level,
1190 dof_set = dof_handler.locally_owned_mg_dofs(level);
1200 std::vector<types::global_dof_index> dof_indices;
1201 std::vector<types::global_dof_index> dofs_on_ghosts;
1203 typename DoFHandlerType::cell_iterator cell = dof_handler.
begin(level),
1204 endc = dof_handler.end(level);
1205 for (; cell != endc; ++cell)
1210 if (
id == dof_handler.get_triangulation().locally_owned_subdomain() ||
1214 dof_indices.resize(cell->get_fe().dofs_per_cell);
1215 cell->get_mg_dof_indices(dof_indices);
1216 for (
unsigned int i = 0; i < dof_indices.size(); ++i)
1218 dofs_on_ghosts.push_back(dof_indices[i]);
1222 std::sort(dofs_on_ghosts.begin(), dofs_on_ghosts.end());
1224 std::unique(dofs_on_ghosts.begin(),
1225 dofs_on_ghosts.end()));
1232 template <
typename DoFHandlerType>
1236 std::vector<std::vector<bool>> &constant_modes)
1238 const unsigned int n_components = dof_handler.get_fe(0).n_components();
1242 std::vector<unsigned char> dofs_by_component(
1243 dof_handler.n_locally_owned_dofs());
1244 internal::get_component_association(dof_handler,
1247 unsigned int n_selected_dofs = 0;
1249 if (component_mask[i] ==
true)
1251 std::count(dofs_by_component.begin(), dofs_by_component.end(), i);
1254 const IndexSet &locally_owned_dofs = dof_handler.locally_owned_dofs();
1255 std::vector<unsigned int> component_numbering(
1257 for (
unsigned int i = 0, count = 0; i < locally_owned_dofs.n_elements();
1259 if (component_mask[dofs_by_component[i]])
1260 component_numbering[i] = count++;
1267 const ::hp::FECollection<DoFHandlerType::dimension,
1268 DoFHandlerType::space_dimension>
1269 & fe_collection = dof_handler.get_fe_collection();
1270 std::vector<Table<2, bool>> element_constant_modes;
1271 std::vector<std::vector<std::pair<unsigned int, unsigned int>>>
1272 constant_mode_to_component_translation(n_components);
1273 unsigned int n_constant_modes = 0;
1274 for (
unsigned int f = 0; f < fe_collection.size(); ++f)
1276 std::pair<Table<2, bool>, std::vector<unsigned int>> data =
1277 fe_collection[f].get_constant_modes();
1278 element_constant_modes.push_back(data.first);
1280 for (
unsigned int i = 0; i < data.second.size(); ++i)
1281 if (component_mask[data.second[i]])
1282 constant_mode_to_component_translation[data.second[i]]
1283 .emplace_back(n_constant_modes++, i);
1285 element_constant_modes[0].n_rows());
1289 constant_modes.clear();
1290 constant_modes.resize(n_constant_modes,
1291 std::vector<bool>(n_selected_dofs,
false));
1295 typename DoFHandlerType::active_cell_iterator cell =
1296 dof_handler.begin_active(),
1297 endc = dof_handler.end();
1298 std::vector<types::global_dof_index> dof_indices;
1299 for (; cell != endc; ++cell)
1300 if (cell->is_locally_owned())
1302 dof_indices.resize(cell->get_fe().dofs_per_cell);
1303 cell->get_dof_indices(dof_indices);
1305 for (
unsigned int i = 0; i < dof_indices.size(); ++i)
1306 if (locally_owned_dofs.is_element(dof_indices[i]))
1308 const unsigned int loc_index =
1309 locally_owned_dofs.index_within_set(dof_indices[i]);
1310 const unsigned int comp = dofs_by_component[loc_index];
1311 if (component_mask[comp])
1312 for (
unsigned int j = 0;
1313 j < constant_mode_to_component_translation[comp].size();
1316 [constant_mode_to_component_translation[comp][j].first]
1317 [component_numbering[loc_index]] =
1318 element_constant_modes[cell->active_fe_index()](
1319 constant_mode_to_component_translation[comp][j]
1328 template <
typename DoFHandlerType>
1331 std::vector<unsigned int> &active_fe_indices)
1334 dof_handler.get_triangulation().n_active_cells());
1336 typename DoFHandlerType::active_cell_iterator cell =
1337 dof_handler.begin_active(),
1338 endc = dof_handler.end();
1339 for (; cell != endc; ++cell)
1340 active_fe_indices[cell->active_cell_index()] = cell->active_fe_index();
1343 template <
typename DoFHandlerType>
1344 std::vector<IndexSet>
1347 Assert(dof_handler.n_dofs() > 0,
1348 ExcMessage(
"The given DoFHandler has no DoFs."));
1353 DoFHandlerType::dimension,
1354 DoFHandlerType::space_dimension
> *>(
1355 &dof_handler.get_triangulation()) ==
nullptr),
1357 "For parallel::distributed::Triangulation objects and " 1358 "associated DoF handler objects, asking for any information " 1359 "related to a subdomain other than the locally owned one does " 1360 "not make sense."));
1364 std::vector<::types::subdomain_id> subdomain_association(
1365 dof_handler.n_dofs());
1366 ::DoFTools::get_subdomain_association(dof_handler,
1367 subdomain_association);
1381 const unsigned int n_subdomains =
1384 DoFHandlerType::space_dimension
> *>(
1385 &dof_handler.get_triangulation()) ==
nullptr ?
1387 unsigned int max_subdomain_id = 0;
1388 for (
auto cell : dof_handler.active_cell_iterators())
1390 std::max(max_subdomain_id, cell->subdomain_id());
1391 return max_subdomain_id + 1;
1396 DoFHandlerType::space_dimension
> *>(
1397 &dof_handler.get_triangulation())
1398 ->get_communicator()));
1399 Assert(n_subdomains > *std::max_element(subdomain_association.begin(),
1400 subdomain_association.end()),
1403 std::vector<::IndexSet> index_sets(
1404 n_subdomains, ::
IndexSet(dof_handler.n_dofs()));
1412 index < subdomain_association.size();
1416 if (subdomain_association[index] != this_subdomain)
1418 index_sets[this_subdomain].add_range(i_min, index);
1420 this_subdomain = subdomain_association[index];
1425 if (i_min == subdomain_association.size() - 1)
1427 index_sets[this_subdomain].add_index(i_min);
1433 index_sets[this_subdomain].add_range(i_min,
1434 subdomain_association.size());
1437 for (
unsigned int i = 0; i < n_subdomains; i++)
1438 index_sets[i].compress();
1443 template <
typename DoFHandlerType>
1444 std::vector<IndexSet>
1450 DoFHandlerType::dimension,
1451 DoFHandlerType::space_dimension
> *>(
1452 &dof_handler.get_triangulation()) ==
nullptr),
1454 "For parallel::distributed::Triangulation objects and " 1455 "associated DoF handler objects, asking for any information " 1456 "related to a subdomain other than the locally owned one does " 1457 "not make sense."));
1465 std::vector<IndexSet> dof_set =
1467 const ::types::subdomain_id n_subdomains = dof_set.size();
1473 subdomain_id < n_subdomains;
1478 const typename DoFHandlerType::active_cell_iterator &)>
1480 const std::vector<typename DoFHandlerType::active_cell_iterator>
1485 std::vector<types::global_dof_index> local_dof_indices;
1486 std::set<types::global_dof_index> subdomain_halo_global_dof_indices;
1487 for (
typename std::vector<
1488 typename DoFHandlerType::active_cell_iterator>::const_iterator
1489 it_cell = active_halo_layer.begin();
1490 it_cell != active_halo_layer.end();
1493 const typename DoFHandlerType::active_cell_iterator &cell =
1496 cell->subdomain_id() != subdomain_id,
1498 "The subdomain ID of the halo cell should not match that of the vector entry."));
1500 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
1501 cell->get_dof_indices(local_dof_indices);
1503 for (std::vector<types::global_dof_index>::iterator it =
1504 local_dof_indices.begin();
1505 it != local_dof_indices.end();
1507 subdomain_halo_global_dof_indices.insert(*it);
1510 dof_set[subdomain_id].add_indices(
1511 subdomain_halo_global_dof_indices.begin(),
1512 subdomain_halo_global_dof_indices.end());
1514 dof_set[subdomain_id].compress();
1520 template <
typename DoFHandlerType>
1523 const DoFHandlerType & dof_handler,
1524 std::vector<types::subdomain_id> &subdomain_association)
1529 DoFHandlerType::dimension,
1530 DoFHandlerType::space_dimension
> *>(
1531 &dof_handler.get_triangulation()) ==
nullptr),
1533 "For parallel::distributed::Triangulation objects and " 1534 "associated DoF handler objects, asking for any subdomain other " 1535 "than the locally owned one does not make sense."));
1537 Assert(subdomain_association.size() == dof_handler.n_dofs(),
1539 dof_handler.n_dofs()));
1551 std::vector<types::subdomain_id> cell_owners(
1552 dof_handler.get_triangulation().n_active_cells());
1554 DoFHandlerType::space_dimension>
1556 DoFHandlerType::dimension,
1557 DoFHandlerType::space_dimension
> *>(
1558 &dof_handler.get_triangulation())))
1560 cell_owners = tr->get_true_subdomain_ids_of_cells();
1561 Assert(tr->get_true_subdomain_ids_of_cells().size() ==
1562 tr->n_active_cells(),
1567 for (
typename DoFHandlerType::active_cell_iterator cell =
1568 dof_handler.begin_active();
1569 cell != dof_handler.end();
1571 if (cell->is_locally_owned())
1572 cell_owners[cell->active_cell_index()] = cell->subdomain_id();
1576 std::fill_n(subdomain_association.begin(),
1577 dof_handler.n_dofs(),
1580 std::vector<types::global_dof_index> local_dof_indices;
1585 typename DoFHandlerType::active_cell_iterator cell =
1586 dof_handler.begin_active(),
1587 endc = dof_handler.end();
1588 for (; cell != endc; ++cell)
1591 cell_owners[cell->active_cell_index()];
1592 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
1593 local_dof_indices.resize(dofs_per_cell);
1594 cell->get_dof_indices(local_dof_indices);
1600 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1601 if (subdomain_association[local_dof_indices[i]] ==
1603 subdomain_association[local_dof_indices[i]] = subdomain_id;
1604 else if (subdomain_association[local_dof_indices[i]] > subdomain_id)
1606 subdomain_association[local_dof_indices[i]] = subdomain_id;
1610 Assert(std::find(subdomain_association.begin(),
1611 subdomain_association.end(),
1613 subdomain_association.end(),
1619 template <
typename DoFHandlerType>
1624 std::vector<types::subdomain_id> subdomain_association(
1625 dof_handler.n_dofs());
1628 return std::count(subdomain_association.begin(),
1629 subdomain_association.end(),
1635 template <
typename DoFHandlerType>
1642 Assert((dof_handler.get_triangulation().locally_owned_subdomain() ==
1645 dof_handler.get_triangulation().locally_owned_subdomain()),
1647 "For parallel::distributed::Triangulation objects and " 1648 "associated DoF handler objects, asking for any subdomain other " 1649 "than the locally owned one does not make sense."));
1651 IndexSet index_set(dof_handler.n_dofs());
1653 std::vector<types::global_dof_index> local_dof_indices;
1661 std::vector<types::global_dof_index> subdomain_indices;
1663 typename DoFHandlerType::active_cell_iterator cell =
1664 dof_handler.begin_active(),
1665 endc = dof_handler.
end();
1666 for (; cell != endc; ++cell)
1667 if ((cell->is_artificial() ==
false) &&
1668 (cell->subdomain_id() == subdomain))
1670 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
1671 local_dof_indices.resize(dofs_per_cell);
1672 cell->get_dof_indices(local_dof_indices);
1673 subdomain_indices.insert(subdomain_indices.end(),
1674 local_dof_indices.begin(),
1675 local_dof_indices.end());
1678 std::sort(subdomain_indices.begin(), subdomain_indices.end());
1679 subdomain_indices.erase(std::unique(subdomain_indices.begin(),
1680 subdomain_indices.end()),
1681 subdomain_indices.end());
1684 index_set.add_indices(subdomain_indices.begin(), subdomain_indices.end());
1685 index_set.compress();
1692 template <
typename DoFHandlerType>
1695 const DoFHandlerType & dof_handler,
1697 std::vector<unsigned int> &n_dofs_on_subdomain)
1699 Assert(n_dofs_on_subdomain.size() == dof_handler.get_fe(0).n_components(),
1701 dof_handler.get_fe(0).n_components()));
1702 std::fill(n_dofs_on_subdomain.begin(), n_dofs_on_subdomain.end(), 0);
1710 DoFHandlerType::dimension,
1711 DoFHandlerType::space_dimension>::active_cell_iterator cell =
1713 cell != dof_handler.get_triangulation().end();
1715 if (cell->subdomain_id() == subdomain)
1721 ExcMessage(
"There are no cells for the given subdomain!"));
1725 std::vector<types::subdomain_id> subdomain_association(
1726 dof_handler.n_dofs());
1729 std::vector<unsigned char> component_association(dof_handler.n_dofs());
1730 internal::get_component_association(dof_handler,
1731 std::vector<bool>(),
1732 component_association);
1734 for (
unsigned int c = 0; c < dof_handler.get_fe(0).n_components(); ++c)
1737 if ((subdomain_association[i] == subdomain) &&
1738 (component_association[i] ==
static_cast<unsigned char>(c)))
1739 ++n_dofs_on_subdomain[c];
1751 template <
int dim,
int spacedim>
1754 const std::vector<unsigned char> & dofs_by_component,
1755 const std::vector<unsigned int> & target_component,
1756 const bool only_once,
1757 std::vector<types::global_dof_index> &dofs_per_component,
1758 unsigned int & component)
1769 resolve_components(base,
1777 for (
unsigned int dd = 0; dd < d; ++dd, ++component)
1778 dofs_per_component[target_component[component]] +=
1779 std::count(dofs_by_component.begin(),
1780 dofs_by_component.end(),
1787 for (
unsigned int dd = 1; dd < d; ++dd)
1788 dofs_per_component[target_component[component - d + dd]] =
1789 dofs_per_component[target_component[component - d]];
1796 template <
int dim,
int spacedim>
1799 const std::vector<unsigned char> & dofs_by_component,
1800 const std::vector<unsigned int> & target_component,
1801 const bool only_once,
1802 std::vector<types::global_dof_index> &dofs_per_component,
1803 unsigned int & component)
1808 for (
unsigned int fe = 1; fe < fe_collection.
size(); ++fe)
1813 Assert(fe_collection[fe].n_base_elements() ==
1814 fe_collection[0].n_base_elements(),
1816 for (
unsigned int b = 0; b < fe_collection[0].n_base_elements(); ++b)
1821 Assert(fe_collection[fe].base_element(b).n_base_elements() ==
1822 fe_collection[0].base_element(b).n_base_elements(),
1827 resolve_components(fe_collection[0],
1845 template <
int dim,
int spacedim>
1857 template <
int dim,
int spacedim>
1859 all_elements_are_primitive(
1860 const ::hp::FECollection<dim, spacedim> &fe_collection)
1862 for (
unsigned int i = 0; i < fe_collection.size(); ++i)
1863 if (fe_collection[i].is_primitive() ==
false)
1871 template <
typename DoFHandlerType>
1874 const DoFHandlerType & dof_handler,
1875 std::vector<types::global_dof_index> &dofs_per_component,
1877 std::vector<unsigned int> target_component)
1879 const unsigned int n_components = dof_handler.get_fe(0).n_components();
1881 std::fill(dofs_per_component.begin(),
1882 dofs_per_component.end(),
1887 if (target_component.size() == 0)
1889 target_component.resize(n_components);
1891 target_component[i] = i;
1898 const unsigned int max_component =
1899 *std::max_element(target_component.begin(), target_component.end());
1900 const unsigned int n_target_components = max_component + 1;
1901 (void)n_target_components;
1907 if (n_components == 1)
1909 dofs_per_component[0] = dof_handler.n_locally_owned_dofs();
1916 std::vector<unsigned char> dofs_by_component(
1917 dof_handler.n_locally_owned_dofs());
1918 internal::get_component_association(dof_handler,
1923 unsigned int component = 0;
1924 internal::resolve_components(dof_handler.get_fe_collection(),
1934 Assert((internal::all_elements_are_primitive(
1935 dof_handler.get_fe_collection()) ==
false) ||
1936 (std::accumulate(dofs_per_component.begin(),
1937 dofs_per_component.end(),
1939 dof_handler.n_locally_owned_dofs()),
1943 #ifdef DEAL_II_WITH_MPI 1944 const unsigned int dim = DoFHandlerType::dimension;
1945 const unsigned int spacedim = DoFHandlerType::space_dimension;
1949 &dof_handler.get_triangulation())))
1951 std::vector<types::global_dof_index> local_dof_count =
1954 const int ierr = MPI_Allreduce(local_dof_count.data(),
1955 dofs_per_component.data(),
1956 n_target_components,
1957 DEAL_II_DOF_INDEX_MPI_TYPE,
1959 tria->get_communicator());
1967 template <
typename DoFHandlerType>
1970 std::vector<types::global_dof_index> &dofs_per_block,
1971 const std::vector<unsigned int> & target_block_)
1973 std::vector<unsigned int> target_block = target_block_;
1975 const ::hp::FECollection<DoFHandlerType::dimension,
1976 DoFHandlerType::space_dimension>
1977 &fe_collection = dof_handler.get_fe_collection();
1980 for (
unsigned int this_fe = 0; this_fe < fe_collection.size(); ++this_fe)
1983 DoFHandlerType::space_dimension> &fe =
1984 fe_collection[this_fe];
1985 std::fill(dofs_per_block.begin(),
1986 dofs_per_block.end(),
1991 if (target_block.size() == 0)
1993 target_block.resize(fe.n_blocks());
1994 for (
unsigned int i = 0; i < fe.n_blocks(); ++i)
1995 target_block[i] = i;
1998 Assert(target_block.size() == fe.n_blocks(),
2003 const unsigned int max_block =
2004 *std::max_element(target_block.begin(), target_block.end());
2005 const unsigned int n_target_blocks = max_block + 1;
2006 (void)n_target_blocks;
2008 const unsigned int n_blocks = fe.n_blocks();
2016 dofs_per_block[0] = dof_handler.n_dofs();
2020 std::vector<unsigned char> dofs_by_block(
2021 dof_handler.n_locally_owned_dofs());
2022 internal::get_block_association(dof_handler, dofs_by_block);
2025 for (
unsigned int block = 0; block < fe.n_blocks(); ++block)
2026 dofs_per_block[target_block[block]] +=
2027 std::count(dofs_by_block.begin(), dofs_by_block.end(), block);
2029 #ifdef DEAL_II_WITH_MPI 2033 DoFHandlerType::space_dimension>
2035 DoFHandlerType::dimension,
2036 DoFHandlerType::space_dimension
> *>(
2037 &dof_handler.get_triangulation())))
2039 std::vector<types::global_dof_index> local_dof_count =
2041 const int ierr = MPI_Allreduce(local_dof_count.data(),
2042 dofs_per_block.data(),
2044 DEAL_II_DOF_INDEX_MPI_TYPE,
2046 tria->get_communicator());
2055 template <
typename DoFHandlerType>
2058 std::vector<types::global_dof_index> &mapping)
2061 mapping.insert(mapping.end(),
2062 dof_handler.n_dofs(),
2065 std::vector<types::global_dof_index> dofs_on_face;
2075 typename DoFHandlerType::active_cell_iterator cell =
2076 dof_handler.begin_active(),
2077 endc = dof_handler.end();
2078 for (; cell != endc; ++cell)
2079 for (
unsigned int f = 0;
2080 f < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
2082 if (cell->at_boundary(f))
2084 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
2085 dofs_on_face.resize(dofs_per_face);
2086 cell->face(f)->get_dof_indices(dofs_on_face,
2087 cell->active_fe_index());
2088 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2090 mapping[dofs_on_face[i]] = next_boundary_index++;
2098 template <
typename DoFHandlerType>
2101 const std::set<types::boundary_id> &boundary_ids,
2102 std::vector<types::global_dof_index> &mapping)
2109 mapping.insert(mapping.end(),
2110 dof_handler.n_dofs(),
2114 if (boundary_ids.size() == 0)
2117 std::vector<types::global_dof_index> dofs_on_face;
2121 typename DoFHandlerType::active_cell_iterator cell =
2122 dof_handler.begin_active(),
2123 endc = dof_handler.end();
2124 for (; cell != endc; ++cell)
2125 for (
unsigned int f = 0;
2126 f < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
2128 if (boundary_ids.find(cell->face(f)->boundary_id()) !=
2131 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
2132 dofs_on_face.resize(dofs_per_face);
2133 cell->face(f)->get_dof_indices(dofs_on_face,
2134 cell->active_fe_index());
2135 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2137 mapping[dofs_on_face[i]] = next_boundary_index++;
2141 dof_handler.n_boundary_dofs(boundary_ids));
2148 template <
typename DoFHandlerType>
2152 DoFHandlerType::space_dimension> &mapping,
2153 const DoFHandlerType & dof_handler,
2157 const unsigned int dim = DoFHandlerType::dimension;
2158 const unsigned int spacedim = DoFHandlerType::space_dimension;
2161 dof_handler.get_fe_collection();
2164 for (
unsigned int fe_index = 0; fe_index < fe_collection.
size();
2168 Assert(fe_collection[fe_index].has_support_points(),
2171 fe_collection[fe_index].get_unit_support_points()));
2185 typename DoFHandlerType::active_cell_iterator cell = dof_handler
2187 endc = dof_handler.end();
2189 std::vector<types::global_dof_index> local_dof_indices;
2190 for (; cell != endc; ++cell)
2192 if (cell->is_artificial() ==
false)
2194 hp_fe_values.
reinit(cell);
2198 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
2199 cell->get_dof_indices(local_dof_indices);
2201 const std::vector<Point<spacedim>> &points =
2203 for (
unsigned int i = 0; i < cell->get_fe().dofs_per_cell; ++i)
2205 support_points[local_dof_indices[i]] = points[i];
2210 template <
typename DoFHandlerType>
2214 DoFHandlerType::space_dimension> &mapping,
2215 const DoFHandlerType & dof_handler,
2226 for (types::global_dof_index i = 0; i < dof_handler.n_dofs(); ++i)
2228 Assert(x_support_points.find(i) != x_support_points.end(),
2230 support_points[i] = x_support_points[i];
2236 template <
int dim,
int spacedim>
2247 "This function can not be used with distributed triangulations." 2248 "See the documentation for more information."));
2254 internal::map_dofs_to_support_points(mapping_collection,
2260 template <
int dim,
int spacedim>
2272 "This function can not be used with distributed triangulations." 2273 "See the documentation for more information."));
2277 internal::map_dofs_to_support_points(mapping, dof_handler, support_points);
2281 template <
int dim,
int spacedim>
2288 support_points.clear();
2294 internal::map_dofs_to_support_points(mapping_collection,
2300 template <
int dim,
int spacedim>
2307 support_points.clear();
2311 internal::map_dofs_to_support_points(mapping, dof_handler, support_points);
2314 template <
int spacedim>
2322 using dof_map_t = std::map<types::global_dof_index, Point<spacedim>>;
2324 using point_map_t = std::map<Point<spacedim>,
2325 std::vector<types::global_dof_index>,
2328 point_map_t point_map;
2331 for (
typename dof_map_t::const_iterator it = support_points.begin();
2332 it != support_points.end();
2335 std::vector<types::global_dof_index> &v = point_map[it->second];
2336 v.push_back(it->first);
2340 for (
typename point_map_t::iterator it = point_map.begin();
2341 it != point_map.end();
2344 out << it->first <<
" \"";
2345 const std::vector<types::global_dof_index> &v = it->second;
2346 for (
unsigned int i = 0; i < v.size(); ++i)
2360 template <
int dim,
int spacedim>
2367 const unsigned int nb = fe.
n_blocks();
2369 tables_by_block.resize(1);
2370 tables_by_block[0].reinit(nb, nb);
2371 tables_by_block[0].fill(
none);
2379 tables_by_block[0](ib, jb) |= table(i, j);
2385 template <
int dim,
int spacedim>
2393 tables_by_block.resize(fe_collection.
size());
2395 for (
unsigned int f = 0; f < fe_collection.
size(); ++f)
2399 const unsigned int nb = fe.
n_blocks();
2400 tables_by_block[f].reinit(nb, nb);
2401 tables_by_block[f].fill(
none);
2408 tables_by_block[f](ib, jb) |= table(i, j);
2416 template <
int dim,
int spacedim>
2420 const unsigned int level,
2421 const std::vector<bool> & selected_dofs,
2424 typename DoFHandler<dim, spacedim>::level_cell_iterator cell;
2425 typename DoFHandler<dim, spacedim>::level_cell_iterator endc =
2426 dof_handler.
end(level);
2427 std::vector<types::global_dof_index> indices;
2431 for (cell = dof_handler.
begin(level); cell != endc; ++cell)
2432 if (cell->is_locally_owned_on_level())
2436 dof_handler.
get_fe().dofs_per_cell);
2438 for (cell = dof_handler.
begin(level); cell != endc; ++cell)
2439 if (cell->is_locally_owned_on_level())
2441 indices.resize(cell->
get_fe().dofs_per_cell);
2442 cell->get_mg_dof_indices(indices);
2444 if (selected_dofs.size() != 0)
2449 if (selected_dofs.size() == 0)
2450 block_list.
add(i, indices[j] - offset);
2453 if (selected_dofs[j])
2454 block_list.
add(i, indices[j] - offset);
2462 template <
typename DoFHandlerType>
2465 const DoFHandlerType &dof_handler,
2466 const unsigned int level,
2467 const bool interior_only)
2470 block_list.
reinit(1, dof_handler.n_dofs(level), dof_handler.n_dofs(level));
2471 typename DoFHandlerType::level_cell_iterator cell;
2472 typename DoFHandlerType::level_cell_iterator endc = dof_handler.end(level);
2474 std::vector<types::global_dof_index> indices;
2475 std::vector<bool> exclude;
2477 for (cell = dof_handler.begin(level); cell != endc; ++cell)
2479 indices.resize(cell->get_fe().dofs_per_cell);
2480 cell->get_mg_dof_indices(indices);
2486 std::fill(exclude.begin(), exclude.end(),
false);
2489 for (
unsigned int face = 0;
2490 face < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
2492 if (cell->at_boundary(face) ||
2493 cell->neighbor(face)->level() != cell->level())
2494 for (
unsigned int i = 0; i < dpf; ++i)
2498 block_list.
add(0, indices[j]);
2503 block_list.
add(0, indices[j]);
2509 template <
typename DoFHandlerType>
2512 const DoFHandlerType &dof_handler,
2513 const unsigned int level,
2514 const bool interior_dofs_only,
2515 const bool boundary_dofs)
2517 Assert(level > 0 && level < dof_handler.get_triangulation().n_levels(),
2518 ExcIndexRange(level, 1, dof_handler.get_triangulation().n_levels()));
2520 typename DoFHandlerType::level_cell_iterator pcell =
2521 dof_handler.begin(level - 1);
2522 typename DoFHandlerType::level_cell_iterator endc =
2523 dof_handler.end(level - 1);
2525 std::vector<types::global_dof_index> indices;
2526 std::vector<bool> exclude;
2528 for (
unsigned int block = 0; pcell != endc; ++pcell)
2530 if (!pcell->has_children())
2533 for (
unsigned int child = 0; child < pcell->n_children(); ++child)
2535 const typename DoFHandlerType::level_cell_iterator cell =
2536 pcell->child(child);
2540 dof_handler.get_fe();
2542 indices.resize(n_dofs);
2543 exclude.resize(n_dofs);
2544 std::fill(exclude.begin(), exclude.end(),
false);
2545 cell->get_mg_dof_indices(indices);
2547 if (interior_dofs_only)
2553 for (
unsigned int d = 0; d < DoFHandlerType::dimension; ++d)
2556 DoFHandlerType::dimension>::vertex_to_face[child][d];
2557 for (
unsigned int i = 0; i < dpf; ++i)
2564 for (
unsigned int face = 0;
2568 if (cell->at_boundary(face))
2569 for (
unsigned int i = 0; i < dpf; ++i)
2573 for (
unsigned int i = 0; i < n_dofs; ++i)
2575 block_list.
add(block, indices[i]);
2581 template <
typename DoFHandlerType>
2582 std::vector<unsigned int>
2584 const DoFHandlerType &dof_handler,
2585 const unsigned int level,
2586 const bool interior_only,
2587 const bool boundary_patches,
2588 const bool level_boundary_patches,
2589 const bool single_cell_patches,
2590 const bool invert_vertex_mapping)
2592 const unsigned int n_blocks = dof_handler.get_fe().n_blocks();
2597 exclude_boundary_dofs,
2599 level_boundary_patches,
2600 single_cell_patches,
2601 invert_vertex_mapping);
2604 template <
typename DoFHandlerType>
2605 std::vector<unsigned int>
2607 const DoFHandlerType &dof_handler,
2608 const unsigned int level,
2609 const BlockMask & exclude_boundary_dofs,
2610 const bool boundary_patches,
2611 const bool level_boundary_patches,
2612 const bool single_cell_patches,
2613 const bool invert_vertex_mapping)
2615 typename DoFHandlerType::level_cell_iterator cell;
2616 typename DoFHandlerType::level_cell_iterator endc = dof_handler.end(level);
2620 std::vector<unsigned int> vertex_cell_count(
2621 dof_handler.get_triangulation().n_vertices(), 0);
2624 std::vector<bool> vertex_boundary(
2625 dof_handler.get_triangulation().n_vertices(),
false);
2627 std::vector<unsigned int> vertex_mapping(
2628 dof_handler.get_triangulation().n_vertices(),
2632 std::vector<unsigned int> vertex_dof_count(
2633 dof_handler.get_triangulation().n_vertices(), 0);
2637 for (cell = dof_handler.begin(level); cell != endc; ++cell)
2638 for (
unsigned int v = 0;
2639 v < GeometryInfo<DoFHandlerType::dimension>::vertices_per_cell;
2642 const unsigned int vg = cell->vertex_index(v);
2643 vertex_dof_count[vg] += cell->get_fe().dofs_per_cell;
2644 ++vertex_cell_count[vg];
2645 for (
unsigned int d = 0; d < DoFHandlerType::dimension; ++d)
2647 const unsigned int face =
2649 if (cell->at_boundary(face))
2650 vertex_boundary[vg] =
true;
2651 else if ((!level_boundary_patches) &&
2652 (cell->neighbor(face)->level() != (int)level))
2653 vertex_boundary[vg] =
true;
2659 for (
unsigned int vg = 0; vg < vertex_dof_count.size(); ++vg)
2660 if ((!single_cell_patches && vertex_cell_count[vg] < 2) ||
2661 (!boundary_patches && vertex_boundary[vg]))
2662 vertex_dof_count[vg] = 0;
2665 unsigned int n_vertex_count = 0;
2666 for (
unsigned int vg = 0; vg < vertex_mapping.size(); ++vg)
2667 if (vertex_dof_count[vg] != 0)
2668 vertex_mapping[vg] = n_vertex_count++;
2671 for (
unsigned int vg = 0; vg < vertex_mapping.size(); ++vg)
2672 if (vertex_dof_count[vg] != 0)
2673 vertex_dof_count[vertex_mapping[vg]] = vertex_dof_count[vg];
2677 vertex_dof_count.resize(n_vertex_count);
2681 block_list.
reinit(vertex_dof_count.size(),
2682 dof_handler.n_dofs(level),
2685 std::vector<types::global_dof_index> indices;
2686 std::vector<bool> exclude;
2688 for (cell = dof_handler.begin(level); cell != endc; ++cell)
2692 cell->get_mg_dof_indices(indices);
2694 for (
unsigned int v = 0;
2695 v < GeometryInfo<DoFHandlerType::dimension>::vertices_per_cell;
2698 const unsigned int vg = cell->vertex_index(v);
2699 const unsigned int block = vertex_mapping[vg];
2705 if (exclude_boundary_dofs.
size() == 0 ||
2711 std::fill(exclude.begin(), exclude.end(),
false);
2714 for (
unsigned int d = 0; d < DoFHandlerType::dimension; ++d)
2717 DoFHandlerType::dimension>::vertex_to_face[v][d];
2719 DoFHandlerType::dimension>::opposite_face[a_face];
2720 for (
unsigned int i = 0; i < dpf; ++i)
2731 for (
unsigned int j = 0; j < indices.size(); ++j)
2733 block_list.
add(block, indices[j]);
2737 for (
unsigned int j = 0; j < indices.size(); ++j)
2738 block_list.
add(block, indices[j]);
2743 if (invert_vertex_mapping)
2746 unsigned int n_vertex_count = 0;
2747 for (
unsigned int vg = 0; vg < vertex_mapping.size(); ++vg)
2749 vertex_mapping[n_vertex_count++] = vg;
2752 vertex_mapping.resize(n_vertex_count);
2755 return vertex_mapping;
2759 template <
typename DoFHandlerType>
2762 const std::vector<typename DoFHandlerType::active_cell_iterator> &patch)
2764 std::set<types::global_dof_index> dofs_on_patch;
2765 std::vector<types::global_dof_index> local_dof_indices;
2770 for (
unsigned int i = 0; i < patch.size(); ++i)
2772 const typename DoFHandlerType::active_cell_iterator cell = patch[i];
2773 Assert(cell->is_artificial() ==
false,
2774 ExcMessage(
"This function can not be called with cells that are " 2775 "not either locally owned or ghost cells."));
2776 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
2777 cell->get_dof_indices(local_dof_indices);
2778 dofs_on_patch.insert(local_dof_indices.begin(),
2779 local_dof_indices.end());
2783 return dofs_on_patch.size();
2788 template <
typename DoFHandlerType>
2789 std::vector<types::global_dof_index>
2791 const std::vector<typename DoFHandlerType::active_cell_iterator> &patch)
2793 std::set<types::global_dof_index> dofs_on_patch;
2794 std::vector<types::global_dof_index> local_dof_indices;
2799 for (
unsigned int i = 0; i < patch.size(); ++i)
2801 const typename DoFHandlerType::active_cell_iterator cell = patch[i];
2802 Assert(cell->is_artificial() ==
false,
2803 ExcMessage(
"This function can not be called with cells that are " 2804 "not either locally owned or ghost cells."));
2805 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
2806 cell->get_dof_indices(local_dof_indices);
2807 dofs_on_patch.insert(local_dof_indices.begin(),
2808 local_dof_indices.end());
2811 Assert(dofs_on_patch.size() == count_dofs_on_patch<DoFHandlerType>(patch),
2818 return std::vector<types::global_dof_index>(dofs_on_patch.begin(),
2819 dofs_on_patch.end());
2829 #include "dof_tools.inst" 2833 DEAL_II_NAMESPACE_CLOSE
static const unsigned int invalid_unsigned_int
std::pair< unsigned int, types::global_dof_index > system_to_block_index(const unsigned int component) const
#define AssertDimension(dim1, dim2)
const types::subdomain_id invalid_subdomain_id
void add_index(const size_type index)
types::global_dof_index n_dofs() const
static::ExceptionBase & ExcIO()
unsigned int n_selected_components(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
#define AssertIndexRange(index, range)
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
unsigned int size() const
Transformed quadrature points.
unsigned int size() const
#define AssertThrow(cond, exc)
const Triangulation< dim, spacedim > & get_triangulation() const
bool is_primitive() const
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
unsigned int n_active_cells() const
unsigned long long int global_dof_index
active_cell_iterator begin_active(const unsigned int level=0) const
bool represents_n_components(const unsigned int n) const
unsigned int element_multiplicity(const unsigned int index) const
static::ExceptionBase & ExcMessage(std::string arg1)
const std::vector< Point< spacedim > > & get_quadrature_points() const
unsigned int subdomain_id
const Triangulation< dim, spacedim > & get_triangulation() const
void add(const size_type i, const size_type j)
#define Assert(cond, exc)
types::global_dof_index n_dofs() const
unsigned int component_to_block_index(const unsigned int component) const
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
Abstract base class for mapping classes.
unsigned int n_locally_owned_dofs() const
unsigned int size() const
const ComponentMask & get_nonzero_components(const unsigned int i) const
const hp::FECollection< dim, spacedim > & get_fe() const
unsigned int n_base_elements() const
bool represents_the_all_selected_mask() const
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType, lda >> cell, const unsigned int q_index=numbers::invalid_unsigned_int, const unsigned int mapping_index=numbers::invalid_unsigned_int, const unsigned int fe_index=numbers::invalid_unsigned_int)
unsigned int n_components() const
cell_iterator end() const
unsigned int first_selected_component(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
const unsigned int dofs_per_cell
ElementIterator begin() const
void reinit(const size_type m, const size_type n, const unsigned int max_per_row)
void set_size(const size_type size)
const types::subdomain_id artificial_subdomain_id
cell_iterator begin(const unsigned int level=0) 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
#define AssertThrowMPI(error_code)
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
unsigned int n_selected_blocks(const unsigned int overall_number_of_blocks=numbers::invalid_unsigned_int) const
unsigned int n_blocks() const
const unsigned int dofs_per_face
static::ExceptionBase & ExcInvalidBoundaryIndicator()
bool is_element(const size_type index) const
static::ExceptionBase & ExcNotImplemented()
const hp::FECollection< dim, spacedim > & get_fe_collection() const
const ::FEValues< dim, spacedim > & get_present_fe_values() const
ElementIterator end() const
const types::boundary_id internal_face_boundary_id
const std::vector< std::pair< size_type, number > > * get_constraint_entries(const size_type line) const
const types::global_dof_index invalid_dof_index
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
void push_back(const Quadrature< dim > &new_quadrature)
static::ExceptionBase & ExcInternalError()
size_type n_constraints() const
Triangulation< dim, spacedim > & get_triangulation()