59 std::vector<unsigned int> &,
71 std::vector<unsigned int> &,
84 std::vector<unsigned int> &,
95 std::vector<unsigned int> &,
105 template <
int dim,
int spacedim>
108 const unsigned int level,
120 dofs.get_triangulation().n_raw_lines() :
121 dofs.get_triangulation().n_raw_quads());
133 for (
const auto &cell : dofs.cell_iterators_on_level(
level))
161 const unsigned int face_no = 0;
163 Assert(fe.reference_cell() == ReferenceCells::get_hypercube<dim>(),
166 unsigned int increment =
167 fe.n_dofs_per_cell() - dim * fe.n_dofs_per_face(
face_no);
168 while (i < fe.get_first_line_index())
182 fe.n_dofs_per_cell() - (dim - 1) * fe.n_dofs_per_face(
face_no) :
183 fe.n_dofs_per_cell() -
185 while (i < fe.get_first_quad_index(
face_no))
191 fe.n_dofs_per_cell() - (dim - 2) * fe.n_dofs_per_face(
face_no) :
192 fe.n_dofs_per_cell() -
194 while (i < fe.get_first_hex_index())
199 while (i < fe.n_dofs_per_cell())
219 neighbor = cell->neighbor(
iface);
220 if (
static_cast<unsigned int>(neighbor->level()) !=
level)
290 template <
int dim,
int spacedim>
293 const unsigned int level,
306 dofs.get_triangulation().n_raw_lines() :
307 dofs.get_triangulation().n_raw_quads());
316 std::vector<Table<2, DoFTools::Coupling>>
couple_cell;
317 std::vector<Table<2, DoFTools::Coupling>>
couple_face;
328 for (
const auto &cell : dofs.cell_iterators_on_level(
level))
331 const unsigned int fe_index = cell->active_fe_index();
335 const unsigned int face_no = 0;
336 Assert(fe.reference_cell() == ReferenceCells::get_hypercube<dim>(),
374 unsigned int increment;
375 while (i < fe.get_first_line_index())
377 for (
unsigned int base = 0; base < fe.n_base_elements(); ++base)
378 for (
unsigned int mult = 0; mult < fe.element_multiplicity(base);
380 if (
couple_cell[fe_index](fe.system_to_block_index(i).first,
381 fe.first_block_of_base(base) +
385 fe.base_element(base).n_dofs_per_cell() -
386 dim * fe.base_element(base).n_dofs_per_face(
face_no);
401 while (i < fe.get_first_quad_index(
face_no))
403 for (
unsigned int base = 0; base < fe.n_base_elements(); ++base)
404 for (
unsigned int mult = 0; mult < fe.element_multiplicity(base);
406 if (
couple_cell[fe_index](fe.system_to_block_index(i).first,
407 fe.first_block_of_base(base) +
411 fe.base_element(base).n_dofs_per_cell() -
412 ((dim > 1) ? (dim - 1) :
414 fe.base_element(base).n_dofs_per_face(
face_no);
421 while (i < fe.get_first_hex_index())
423 for (
unsigned int base = 0; base < fe.n_base_elements(); ++base)
424 for (
unsigned int mult = 0; mult < fe.element_multiplicity(base);
426 if (
couple_cell[fe_index](fe.system_to_block_index(i).first,
427 fe.first_block_of_base(base) +
431 fe.base_element(base).n_dofs_per_cell() -
432 ((dim > 2) ? (dim - 2) :
434 fe.base_element(base).n_dofs_per_face(
face_no);
441 while (i < fe.n_dofs_per_cell())
443 for (
unsigned int base = 0; base < fe.n_base_elements(); ++base)
444 for (
unsigned int mult = 0; mult < fe.element_multiplicity(base);
446 if (
couple_cell[fe_index](fe.system_to_block_index(i).first,
447 fe.first_block_of_base(base) +
451 fe.base_element(base).n_dofs_per_cell() -
453 fe.base_element(base).n_dofs_per_face(
face_no);
476 neighbor = cell->neighbor(
iface);
477 if (
static_cast<unsigned int>(neighbor->level()) !=
level)
503 for (
unsigned int base = 0; base <
nfe.n_base_elements(); ++base)
504 for (
unsigned int mult = 0; mult <
nfe.element_multiplicity(base);
510 fe.system_to_block_index(
local_dof).first,
514 nfe.base_element(base).n_dofs_per_cell() -
515 nfe.base_element(base).n_dofs_per_face(
face_no);
546 for (
unsigned int base = 0; base <
nfe.n_base_elements(); ++base)
547 for (
unsigned int mult = 0; mult <
nfe.element_multiplicity(base);
553 fe.system_to_component_index(
local_dof).first,
556 nfe.base_element(base).n_dofs_per_face(
face_no);
557 for (
unsigned int base = 0; base < fe.n_base_elements(); ++base)
558 for (
unsigned int mult = 0; mult < fe.element_multiplicity(base);
567 fe.base_element(base).n_dofs_per_face(
face_no);
574 template <
int dim,
int spacedim,
typename number>
578 const unsigned int level,
590 const unsigned int dofs_per_cell = dof.get_fe().n_dofs_per_cell();
592 for (
const auto &cell : dof.cell_iterators_on_level(
level))
593 if (cell->is_locally_owned_on_level())
604 template <
int dim,
int spacedim,
typename number>
608 const unsigned int level,
620 const unsigned int dofs_per_cell = dof.get_fe().n_dofs_per_cell();
623 for (
const auto &cell : dof.cell_iterators_on_level(
level))
625 if (!cell->is_locally_owned_on_level())
637 bool use_face =
false;
638 if ((!cell->at_boundary(face)) &&
639 (
static_cast<unsigned int>(cell->neighbor_level(face)) ==
642 else if (cell->has_periodic_neighbor(face) &&
643 (
static_cast<unsigned int>(
644 cell->periodic_neighbor_level(face)) ==
level))
650 cell->neighbor_or_periodic_neighbor(face);
660 if (neighbor->is_locally_owned_on_level() ==
false)
662 constraints.add_entries_local_to_global(
665 constraints.add_entries_local_to_global(
678 template <
int dim,
int spacedim>
682 const unsigned int level)
699 const unsigned int dofs_per_cell = dof.get_fe().n_dofs_per_cell();
702 for (
const auto &cell : dof.cell_iterators_on_level(
level))
704 if (!cell->is_locally_owned_on_level())
712 bool use_face =
false;
713 if ((!cell->at_boundary(face)) &&
714 (
static_cast<unsigned int>(cell->neighbor_level(face)) !=
717 else if (cell->has_periodic_neighbor(face) &&
718 (
static_cast<unsigned int>(
719 cell->periodic_neighbor_level(face)) !=
level))
725 cell->neighbor_or_periodic_neighbor(face);
729 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
740 template <
int dim,
int spacedim>
744 const unsigned int level,
750 const unsigned int n_comp = fe.n_components();
767 const unsigned int total_dofs = fe.n_dofs_per_cell();
770 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
787 dof.get_triangulation().n_raw_lines() :
788 dof.get_triangulation().n_raw_quads());
790 for (
const auto &cell : dof.cell_iterators_on_level(
level))
792 if (!cell->is_locally_owned_on_level())
811 if (cell->at_boundary(face) && !cell->has_periodic_neighbor(face))
833 cell->neighbor_or_periodic_neighbor(face);
835 if (neighbor->level() < cell->level())
839 cell->has_periodic_neighbor(face) ?
840 cell->periodic_neighbor_of_periodic_neighbor(face) :
841 cell->neighbor_of_neighbor(face);
918 template <
int dim,
int spacedim>
922 const unsigned int level,
926 const unsigned int n_comp = fe.n_components();
948 const unsigned int dofs_per_cell = dof.get_fe().n_dofs_per_cell();
951 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
960 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
964 for (
const auto &cell : dof.cell_iterators_on_level(
level))
966 if (!cell->is_locally_owned_on_level())
974 bool use_face =
false;
975 if ((!cell->at_boundary(face)) &&
976 (
static_cast<unsigned int>(cell->neighbor_level(face)) !=
979 else if (cell->has_periodic_neighbor(face) &&
980 (
static_cast<unsigned int>(
981 cell->periodic_neighbor_level(face)) !=
level))
987 cell->neighbor_or_periodic_neighbor(face);
990 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
992 for (
unsigned int j = 0;
j < dofs_per_cell; ++
j)
1012 template <
int dim,
int spacedim>
1017 const unsigned int level)
1027 const unsigned int dofs_per_cell = dof.get_fe().n_dofs_per_cell();
1029 std::vector<types::global_dof_index> cols;
1030 cols.reserve(dofs_per_cell);
1032 for (
const auto &cell : dof.cell_iterators_on_level(
level))
1033 if (cell->is_locally_owned_on_level())
1037 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1039 for (
unsigned int j = 0;
j < dofs_per_cell; ++
j)
1053 template <
int dim,
int spacedim>
1057 std::vector<std::vector<types::global_dof_index>> &
result,
1059 std::vector<unsigned int> target_component)
1062 const unsigned int n_components = fe.n_components();
1064 dof_handler.get_triangulation().n_global_levels();
1069 if (target_component.size() == 0)
1071 target_component.resize(n_components);
1072 for (
unsigned int i = 0; i < n_components; ++i)
1073 target_component[i] = i;
1076 Assert(target_component.size() == n_components,
1079 for (
unsigned int l = 0; l <
nlevels; ++l)
1081 result[l].resize(n_components);
1088 if (n_components == 1)
1090 result[l][0] = dof_handler.n_dofs(l);
1098 n_components, std::vector<bool>(dof_handler.n_dofs(l),
false));
1101 for (
unsigned int i = 0; i < n_components; ++i)
1106 std::vector<bool> &) =
1107 &DoFTools::extract_level_dofs<dim, spacedim>;
1109 std::vector<bool> tmp(n_components,
false);
1122 unsigned int component = 0;
1123 for (
unsigned int b = 0; b < fe.n_base_elements(); ++b)
1127 unsigned int d = base.n_components();
1129 for (
unsigned int m = 0; m < fe.element_multiplicity(b); ++m)
1131 for (
unsigned int dd = 0;
dd < d; ++
dd)
1133 if (base.is_primitive() || (!
only_once ||
dd == 0))
1134 result[l][target_component[component]] +=
1143 Assert(!dof_handler.get_fe().is_primitive() ||
1147 dof_handler.n_dofs(l),
1155 template <
int dim,
int spacedim>
1159 std::vector<std::vector<types::global_dof_index>> &
dofs_per_block,
1163 const unsigned int n_blocks = fe.n_blocks();
1164 const unsigned int n_levels =
1165 dof_handler.get_triangulation().n_global_levels();
1169 for (
unsigned int l = 0; l < n_levels; ++l)
1177 for (
unsigned int i = 0; i < n_blocks; ++i)
1188 for (
unsigned int l = 0; l < n_levels; ++l)
1197 for (
unsigned int l = 0; l < n_levels; ++l)
1204 for (
unsigned int l = 0; l < n_levels; ++l)
1207 n_blocks, std::vector<bool>(dof_handler.n_dofs(l),
false));
1210 for (
unsigned int i = 0; i < n_blocks; ++i)
1215 std::vector<bool> &) =
1216 &DoFTools::extract_level_dofs<dim, spacedim>;
1218 std::vector<bool> tmp(n_blocks,
false);
1228 for (
unsigned int block = 0; block < fe.n_blocks(); ++block)
1238 template <
int dim,
int spacedim>
1244 std::vector<std::set<types::global_dof_index>> &boundary_indices,
1247 Assert(boundary_indices.size() == dof.get_triangulation().n_global_levels(),
1249 dof.get_triangulation().n_global_levels()));
1251 std::set<types::boundary_id> boundary_ids;
1257 for (
unsigned int i = 0; i < dof.get_triangulation().n_global_levels(); ++i)
1263 template <
int dim,
int spacedim>
1268 std::vector<IndexSet> &boundary_indices,
1271 Assert(boundary_indices.size() == dof.get_triangulation().n_global_levels(),
1273 dof.get_triangulation().n_global_levels()));
1275 std::set<types::boundary_id> boundary_ids;
1284 template <
int dim,
int spacedim>
1287 const std::set<types::boundary_id> &boundary_ids,
1288 std::vector<IndexSet> & boundary_indices,
1291 boundary_indices.resize(dof.get_triangulation().n_global_levels());
1294 if (boundary_ids.size() == 0)
1297 for (
unsigned int i = 0; i < dof.get_triangulation().n_global_levels(); ++i)
1298 if (boundary_indices[i].size() == 0)
1299 boundary_indices[i] =
IndexSet(dof.n_dofs(i));
1301 const unsigned int n_components = dof.get_fe_collection().n_components();
1304 std::vector<types::global_dof_index>
local_dofs;
1305 local_dofs.reserve(dof.get_fe_collection().max_dofs_per_face());
1308 std::vector<std::vector<types::global_dof_index>>
dofs_by_level(
1309 dof.get_triangulation().n_levels());
1315 for (
const auto &cell : dof.cell_iterators())
1317 if (cell->is_artificial_on_level())
1320 const unsigned int level = cell->level();
1323 if (cell->at_boundary(
face_no) ==
true)
1329 if (boundary_ids.find(
bi) != boundary_ids.end())
1344 "It's probably worthwhile to select at least one component."));
1346 for (
const auto &cell : dof.cell_iterators())
1347 if (!cell->is_artificial_on_level())
1350 if (cell->at_boundary(
face_no) ==
false)
1354 const unsigned int level = cell->level();
1359 face->boundary_id();
1363 for (
unsigned int i = 0;
1364 i < cell->get_fe().n_dofs_per_cell();
1368 cell->get_fe().get_nonzero_components(i);
1372 bool selected =
false;
1373 for (
unsigned int c = 0; c < n_components; ++c)
1375 component_mask[c] ==
true)
1381 for (
unsigned int c = 0; c < n_components; ++c)
1384 component_mask[c] ==
true,
1386 "You are using a non-primitive FiniteElement "
1387 "and try to constrain just some of its components!"));
1398 unsigned int component =
1400 if (fe.is_primitive())
1402 fe.face_system_to_component_index(i,
face_no)
1410 cell->get_fe().get_nonzero_components(i);
1411 for (
unsigned int c = 0; c < n_components; ++c)
1420 if (component_mask[component] ==
true)
1431 for (
unsigned int level = 0;
level < dof.get_triangulation().n_levels();
1435 boundary_indices[
level].add_indices(
1444 template <
int dim,
int spacedim>
1447 std::vector<IndexSet> & interface_dofs)
1449 Assert(interface_dofs.size() ==
1452 interface_dofs.size(),
1456 interface_dofs.size());
1460 const unsigned int dofs_per_cell = fe.n_dofs_per_cell();
1462 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1464 std::vector<bool>
cell_dofs(dofs_per_cell,
false);
1470 if (cell->is_artificial_on_level())
1481 if (!face->at_boundary() || cell->has_periodic_neighbor(
face_nr))
1485 cell->neighbor_or_periodic_neighbor(
face_nr);
1489 if (neighbor->is_artificial_on_level())
1493 if (neighbor->level() < cell->level())
1495 for (
unsigned int j = 0;
j < fe.n_dofs_per_face(
face_nr);
1507 const unsigned int level = cell->level();
1508 cell->get_mg_dof_indices(local_dof_indices);
1510 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1517 for (
unsigned int l = 0;
1521 interface_dofs[l].clear();
1526 interface_dofs[l].compress();
1532 template <
int dim,
int spacedim>
1541 unsigned int min_level =
tria.n_global_levels();
1542 for (
const auto &cell :
tria.active_cell_iterators())
1543 if (cell->is_locally_owned())
1545 min_level = cell->level();
1584 static_cast<double>(
n_proc);
1599 std::pair<types::global_dof_index, types::global_dof_index>> &cells,
1602 std::vector<types::global_dof_index>
cells_local(cells.size());
1603 std::vector<types::global_dof_index>
cells_remote(cells.size());
1605 for (
unsigned int i = 0; i < cells.size(); ++i)
1630 template <
int dim,
int spacedim>
1631 std::vector<types::global_dof_index>
1638 tr->is_multilevel_hierarchy_constructed(),
1640 "We can only compute the workload imbalance if the multilevel hierarchy has been constructed!"));
1642 const unsigned int n_global_levels =
tria.n_global_levels();
1646 for (
unsigned int lvl = 0;
lvl < n_global_levels; ++
lvl)
1647 for (
const auto &cell :
tria.cell_iterators_on_level(
lvl))
1648 if (cell->is_locally_owned_on_level())
1656 template <
int dim,
int spacedim>
1657 std::vector<types::global_dof_index>
1662 const unsigned int n_global_levels =
trias.
size();
1666 for (
unsigned int lvl = 0;
lvl < n_global_levels; ++
lvl)
1667 for (
const auto &cell :
trias[
lvl]->active_cell_iterators())
1668 if (cell->is_locally_owned())
1676 template <
int dim,
int spacedim>
1681 tria.get_communicator());
1686 template <
int dim,
int spacedim>
1693 trias.back()->get_communicator());
1698 template <
int dim,
int spacedim>
1699 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1702 const unsigned int n_global_levels =
tria.n_global_levels();
1704 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1705 cells(n_global_levels);
1711 for (
unsigned int lvl = 0;
lvl < n_global_levels - 1; ++
lvl)
1712 for (
const auto &cell :
tria.cell_iterators_on_level(
lvl))
1713 if (cell->is_locally_owned_on_level() && cell->has_children())
1717 const auto level_subdomain_id =
1718 cell->child(i)->level_subdomain_id();
1719 if (level_subdomain_id == my_rank)
1720 ++cells[
lvl + 1].first;
1722 ++cells[
lvl + 1].second;
1732 template <
int dim,
int spacedim>
1733 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1738 const unsigned int n_global_levels =
trias.
size();
1740 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1741 cells(n_global_levels);
1743 const MPI_Comm communicator =
trias.back()->get_communicator();
1747 for (
unsigned int lvl = 0;
lvl < n_global_levels - 1; ++
lvl)
1752 const unsigned int n_coarse_cells =
tria_fine.n_global_coarse_cells();
1753 const unsigned int n_global_levels =
tria_fine.n_global_levels();
1756 n_coarse_cells, n_global_levels);
1761 for (
const auto &cell :
tria_fine.active_cell_iterators())
1762 if (!cell->is_artificial() && cell->is_locally_owned())
1765 for (
const auto &cell :
tria_coarse.active_cell_iterators())
1766 if (!cell->is_artificial() && cell->is_locally_owned())
1768 if (cell->level() + 1u ==
tria_fine.n_global_levels())
1771 for (
unsigned int i = 0;
1790 std::pair<types::global_cell_index, types::global_cell_index>>,
1791 std::vector<unsigned int>>
1797 ++cells[
lvl + 1].first;
1799 ++cells[
lvl + 1].second;
1807 template <
int dim,
int spacedim>
1817 template <
int dim,
int spacedim>
1825 trias.back()->get_communicator());
1832#include "mg_tools.inst"
ArrayView< typename std::remove_reference< typename std::iterator_traits< Iterator >::reference >::type, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
unsigned int n_selected_components(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
bool is_interface_matrix_entry(const unsigned int level, const types::global_dof_index i, const types::global_dof_index j) const
virtual void add_entries(const ArrayView< const std::pair< size_type, size_type > > &entries)
virtual void add_row_entries(const size_type &row, const ArrayView< const size_type > &columns, const bool indices_are_sorted=false)=0
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#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::cell_iterator cell_iterator
typename ActiveSelector::face_iterator face_iterator
Task< RT > new_task(const std::function< RT()> &function)
T sum(const T &t, const MPI_Comm mpi_communicator)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
T max(const T &t, const MPI_Comm mpi_communicator)
T min(const T &t, const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
static const unsigned int invalid_unsigned_int
const types::global_dof_index invalid_dof_index
static std_cxx20::ranges::iota_view< unsigned int, unsigned int > face_indices()
const ::Triangulation< dim, spacedim > & tria