58 std::vector<unsigned int> &,
70 std::vector<unsigned int> &,
83 std::vector<unsigned int> &,
94 std::vector<unsigned int> &,
104 template <
int dim,
int spacedim>
107 const unsigned int level,
108 std::vector<unsigned int> &row_lengths,
116 std::fill(row_lengths.begin(), row_lengths.end(), 0);
118 std::vector<bool> face_touched(dim == 2 ?
122 std::vector<types::global_dof_index> cell_indices;
123 std::vector<types::global_dof_index> neighbor_indices;
136 cell->get_mg_dof_indices(cell_indices);
160 const unsigned int face_no = 0;
165 unsigned int increment =
168 row_lengths[cell_indices[i++]] += increment;
185 row_lengths[cell_indices[i++]] += increment;
194 row_lengths[cell_indices[i++]] += increment;
199 row_lengths[cell_indices[i++]] += increment;
214 bool level_boundary = cell->at_boundary(iface);
218 neighbor = cell->neighbor(iface);
219 if (
static_cast<unsigned int>(neighbor->level()) !=
level)
220 level_boundary =
true;
225 for (
unsigned int local_dof = 0;
228 row_lengths[cell_indices[local_dof]] +=
247 const unsigned int dof_increment =
249 for (
unsigned int local_dof = 0;
252 row_lengths[cell_indices[local_dof]] += dof_increment;
257 if (face_touched[face->index()])
259 face_touched[face->index()] =
true;
274 neighbor->get_mg_dof_indices(neighbor_indices);
277 row_lengths[cell_indices[local_dof]] +=
281 row_lengths[neighbor_indices[local_dof]] +=
289 template <
int dim,
int spacedim>
292 const unsigned int level,
293 std::vector<unsigned int> &row_lengths,
302 std::fill(row_lengths.begin(), row_lengths.end(), 0);
304 std::vector<bool> face_touched(dim == 2 ?
308 std::vector<types::global_dof_index> cell_indices;
309 std::vector<types::global_dof_index> neighbor_indices;
315 std::vector<Table<2, DoFTools::Coupling>> couple_cell;
316 std::vector<Table<2, DoFTools::Coupling>> couple_face;
330 const unsigned int fe_index = cell->active_fe_index();
334 const unsigned int face_no = 0;
350 cell->get_mg_dof_indices(cell_indices);
373 unsigned int increment;
386 row_lengths[cell_indices[i]] += increment;
411 ((dim > 1) ? (dim - 1) :
414 row_lengths[cell_indices[i]] += increment;
431 ((dim > 2) ? (dim - 2) :
434 row_lengths[cell_indices[i]] += increment;
453 row_lengths[cell_indices[i]] += increment;
471 bool level_boundary = cell->at_boundary(iface);
475 neighbor = cell->neighbor(iface);
476 if (
static_cast<unsigned int>(neighbor->level()) !=
level)
477 level_boundary =
true;
482 for (
unsigned int local_dof = 0;
485 row_lengths[cell_indices[local_dof]] +=
505 for (
unsigned int local_dof = 0;
508 if (couple_face[fe_index](
512 const unsigned int dof_increment =
515 row_lengths[cell_indices[local_dof]] += dof_increment;
519 if (face_touched[face->index()])
521 face_touched[face->index()] =
true;
544 neighbor->get_mg_dof_indices(neighbor_indices);
548 for (
unsigned int local_dof = 0;
551 if (couple_cell[fe_index](
554 row_lengths[cell_indices[local_dof]] +=
559 for (
unsigned int local_dof = 0;
562 if (couple_cell[fe_index](
565 row_lengths[neighbor_indices[local_dof]] +=
573 template <
int dim,
int spacedim,
typename number>
577 const unsigned int level,
579 const bool keep_constrained_dofs)
590 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
592 if (cell->is_locally_owned_on_level())
594 cell->get_mg_dof_indices(dofs_on_this_cell);
597 keep_constrained_dofs);
603 template <
int dim,
int spacedim,
typename number>
607 const unsigned int level,
609 const bool keep_constrained_dofs)
620 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
621 std::vector<types::global_dof_index> dofs_on_other_cell(dofs_per_cell);
624 if (!cell->is_locally_owned_on_level())
627 cell->get_mg_dof_indices(dofs_on_this_cell);
631 keep_constrained_dofs);
636 bool use_face =
false;
637 if ((!cell->at_boundary(face)) &&
638 (
static_cast<unsigned int>(cell->neighbor_level(face)) ==
641 else if (cell->has_periodic_neighbor(face) &&
642 (
static_cast<unsigned int>(
643 cell->periodic_neighbor_level(face)) ==
level))
649 cell->neighbor_or_periodic_neighbor(face);
650 neighbor->get_mg_dof_indices(dofs_on_other_cell);
657 keep_constrained_dofs);
659 if (neighbor->is_locally_owned_on_level() ==
false)
662 dofs_on_other_cell, sparsity, keep_constrained_dofs);
668 keep_constrained_dofs);
677 template <
int dim,
int spacedim>
681 const unsigned int level)
699 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
700 std::vector<types::global_dof_index> dofs_on_other_cell(dofs_per_cell);
703 if (!cell->is_locally_owned_on_level())
706 cell->get_mg_dof_indices(dofs_on_this_cell);
711 bool use_face =
false;
712 if ((!cell->at_boundary(face)) &&
713 (
static_cast<unsigned int>(cell->neighbor_level(face)) !=
716 else if (cell->has_periodic_neighbor(face) &&
717 (
static_cast<unsigned int>(
718 cell->periodic_neighbor_level(face)) !=
level))
724 cell->neighbor_or_periodic_neighbor(face);
725 neighbor->get_mg_dof_indices(dofs_on_other_cell);
727 std::sort(dofs_on_this_cell.begin(), dofs_on_this_cell.end());
728 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
739 template <
int dim,
int spacedim>
743 const unsigned int level,
757 Assert(int_mask.n_rows() == n_comp,
759 Assert(int_mask.n_cols() == n_comp,
761 Assert(flux_mask.n_rows() == n_comp,
763 Assert(flux_mask.n_cols() == n_comp,
767 std::vector<types::global_dof_index> dofs_on_this_cell(total_dofs);
768 std::vector<types::global_dof_index> dofs_on_other_cell(total_dofs);
769 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
781 for (
unsigned int i = 0; i < total_dofs; ++i)
785 std::vector<bool> face_touched(dim == 2 ?
791 if (!cell->is_locally_owned_on_level())
794 cell->get_mg_dof_indices(dofs_on_this_cell);
796 for (
unsigned int i = 0; i < total_dofs; ++i)
797 for (
unsigned int j = 0; j < total_dofs; ++j)
799 cell_entries.emplace_back(dofs_on_this_cell[i],
800 dofs_on_this_cell[j]);
807 if (face_touched[cell_face->index()])
810 if (cell->at_boundary(face) && !cell->has_periodic_neighbor(face))
812 for (
unsigned int i = 0; i < total_dofs; ++i)
814 const bool i_non_zero_i = support_on_face(i, face);
815 for (
unsigned int j = 0; j < total_dofs; ++j)
817 const bool j_non_zero_i = support_on_face(j, face);
820 cell_entries.emplace_back(dofs_on_this_cell[i],
821 dofs_on_this_cell[j]);
823 i_non_zero_i && j_non_zero_i)
824 cell_entries.emplace_back(dofs_on_this_cell[i],
825 dofs_on_this_cell[j]);
832 cell->neighbor_or_periodic_neighbor(face);
834 if (neighbor->level() < cell->level())
837 unsigned int neighbor_face =
838 cell->has_periodic_neighbor(face) ?
839 cell->periodic_neighbor_of_periodic_neighbor(face) :
840 cell->neighbor_of_neighbor(face);
842 neighbor->get_mg_dof_indices(dofs_on_other_cell);
843 for (
unsigned int i = 0; i < total_dofs; ++i)
845 const bool i_non_zero_i = support_on_face(i, face);
846 const bool i_non_zero_e = support_on_face(i, neighbor_face);
847 for (
unsigned int j = 0; j < total_dofs; ++j)
849 const bool j_non_zero_i = support_on_face(j, face);
850 const bool j_non_zero_e =
851 support_on_face(j, neighbor_face);
854 cell_entries.emplace_back(dofs_on_this_cell[i],
855 dofs_on_other_cell[j]);
856 cell_entries.emplace_back(dofs_on_other_cell[i],
857 dofs_on_this_cell[j]);
858 cell_entries.emplace_back(dofs_on_this_cell[i],
859 dofs_on_this_cell[j]);
860 cell_entries.emplace_back(dofs_on_other_cell[i],
861 dofs_on_other_cell[j]);
865 if (i_non_zero_i && j_non_zero_e)
866 cell_entries.emplace_back(dofs_on_this_cell[i],
867 dofs_on_other_cell[j]);
868 if (i_non_zero_e && j_non_zero_i)
869 cell_entries.emplace_back(dofs_on_other_cell[i],
870 dofs_on_this_cell[j]);
871 if (i_non_zero_i && j_non_zero_i)
872 cell_entries.emplace_back(dofs_on_this_cell[i],
873 dofs_on_this_cell[j]);
874 if (i_non_zero_e && j_non_zero_e)
875 cell_entries.emplace_back(dofs_on_other_cell[i],
876 dofs_on_other_cell[j]);
881 cell_entries.emplace_back(dofs_on_this_cell[j],
882 dofs_on_other_cell[i]);
883 cell_entries.emplace_back(dofs_on_other_cell[j],
884 dofs_on_this_cell[i]);
885 cell_entries.emplace_back(dofs_on_this_cell[j],
886 dofs_on_this_cell[i]);
887 cell_entries.emplace_back(dofs_on_other_cell[j],
888 dofs_on_other_cell[i]);
892 if (j_non_zero_i && i_non_zero_e)
893 cell_entries.emplace_back(dofs_on_this_cell[j],
894 dofs_on_other_cell[i]);
895 if (j_non_zero_e && i_non_zero_i)
896 cell_entries.emplace_back(dofs_on_other_cell[j],
897 dofs_on_this_cell[i]);
898 if (j_non_zero_i && i_non_zero_i)
899 cell_entries.emplace_back(dofs_on_this_cell[j],
900 dofs_on_this_cell[i]);
901 if (j_non_zero_e && i_non_zero_e)
902 cell_entries.emplace_back(dofs_on_other_cell[j],
903 dofs_on_other_cell[i]);
907 face_touched[neighbor->face(neighbor_face)->index()] =
true;
911 cell_entries.clear();
917 template <
int dim,
int spacedim>
921 const unsigned int level,
942 Assert(flux_mask.n_rows() == n_comp,
944 Assert(flux_mask.n_cols() == n_comp,
948 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
949 std::vector<types::global_dof_index> dofs_on_other_cell(dofs_per_cell);
950 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
959 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
965 if (!cell->is_locally_owned_on_level())
968 cell->get_mg_dof_indices(dofs_on_this_cell);
973 bool use_face =
false;
974 if ((!cell->at_boundary(face)) &&
975 (
static_cast<unsigned int>(cell->neighbor_level(face)) !=
978 else if (cell->has_periodic_neighbor(face) &&
979 (
static_cast<unsigned int>(
980 cell->periodic_neighbor_level(face)) !=
level))
986 cell->neighbor_or_periodic_neighbor(face);
987 neighbor->get_mg_dof_indices(dofs_on_other_cell);
989 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
991 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
995 cell_entries.emplace_back(dofs_on_other_cell[i],
996 dofs_on_this_cell[j]);
997 cell_entries.emplace_back(dofs_on_other_cell[j],
998 dofs_on_this_cell[i]);
1005 cell_entries.clear();
1011 template <
int dim,
int spacedim>
1016 const unsigned int level)
1027 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
1028 std::vector<types::global_dof_index> cols;
1029 cols.reserve(dofs_per_cell);
1032 if (cell->is_locally_owned_on_level())
1034 cell->get_mg_dof_indices(dofs_on_this_cell);
1035 std::sort(dofs_on_this_cell.begin(), dofs_on_this_cell.end());
1036 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1038 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
1040 level, dofs_on_this_cell[i], dofs_on_this_cell[j]))
1041 cols.push_back(dofs_on_this_cell[j]);
1052 template <
int dim,
int spacedim>
1056 std::vector<std::vector<types::global_dof_index>> &result,
1058 std::vector<unsigned int> target_component)
1062 const unsigned int nlevels =
1065 Assert(result.size() == nlevels,
1068 if (target_component.empty())
1070 target_component.resize(n_components);
1071 for (
unsigned int i = 0; i < n_components; ++i)
1072 target_component[i] = i;
1075 Assert(target_component.size() == n_components,
1078 for (
unsigned int l = 0; l < nlevels; ++l)
1080 result[l].resize(n_components);
1081 std::fill(result[l].begin(), result[l].end(), 0U);
1087 if (n_components == 1)
1089 result[l][0] = dof_handler.
n_dofs(l);
1096 std::vector<std::vector<bool>> dofs_in_component(
1097 n_components, std::vector<bool>(dof_handler.
n_dofs(l),
false));
1098 std::vector<ComponentMask> component_select(n_components);
1100 for (
unsigned int i = 0; i < n_components; ++i)
1102 void (*fun_ptr)(
const unsigned int level,
1105 std::vector<bool> &) =
1108 std::vector<bool> tmp(n_components,
false);
1115 component_select[i],
1116 dofs_in_component[i]);
1121 unsigned int component = 0;
1130 for (
unsigned int dd = 0; dd < d; ++dd)
1133 result[l][target_component[component]] +=
1134 std::count(dofs_in_component[component].begin(),
1135 dofs_in_component[component].end(),
1143 std::accumulate(result[l].begin(),
1154 template <
int dim,
int spacedim>
1158 std::vector<std::vector<types::global_dof_index>> &dofs_per_block,
1159 std::vector<unsigned int> target_block)
1162 const unsigned int n_blocks = fe.
n_blocks();
1163 const unsigned int n_levels =
1168 for (
unsigned int l = 0; l < n_levels; ++l)
1169 std::fill(dofs_per_block[l].begin(), dofs_per_block[l].end(), 0U);
1173 if (target_block.empty())
1175 target_block.resize(n_blocks);
1176 for (
unsigned int i = 0; i < n_blocks; ++i)
1177 target_block[i] = i;
1179 Assert(target_block.size() == n_blocks,
1182 const unsigned int max_block =
1183 *std::max_element(target_block.begin(), target_block.end());
1184 const unsigned int n_target_blocks = max_block + 1;
1185 (void)n_target_blocks;
1187 for (
unsigned int l = 0; l < n_levels; ++l)
1196 for (
unsigned int l = 0; l < n_levels; ++l)
1197 dofs_per_block[l][0] = dof_handler.
n_dofs(l);
1203 for (
unsigned int l = 0; l < n_levels; ++l)
1205 std::vector<std::vector<bool>> dofs_in_block(
1206 n_blocks, std::vector<bool>(dof_handler.
n_dofs(l),
false));
1207 std::vector<BlockMask> block_select(n_blocks);
1209 for (
unsigned int i = 0; i < n_blocks; ++i)
1211 void (*fun_ptr)(
const unsigned int level,
1214 std::vector<bool> &) =
1217 std::vector<bool> tmp(n_blocks,
false);
1222 fun_ptr, l, dof_handler, block_select[i], dofs_in_block[i]);
1227 for (
unsigned int block = 0; block < fe.
n_blocks(); ++block)
1228 dofs_per_block[l][target_block[block]] +=
1229 std::count(dofs_in_block[block].begin(),
1230 dofs_in_block[block].end(),
1237 template <
int dim,
int spacedim>
1243 std::vector<std::set<types::global_dof_index>> &boundary_indices,
1250 std::set<types::boundary_id> boundary_ids;
1251 for (
const auto &boundary_function : function_map)
1252 boundary_ids.insert(boundary_function.first);
1254 std::vector<IndexSet> boundary_indexset;
1257 boundary_indices[i].insert(boundary_indexset[i].begin(),
1258 boundary_indexset[i].end());
1262 template <
int dim,
int spacedim>
1267 std::vector<IndexSet> &boundary_indices,
1274 std::set<types::boundary_id> boundary_ids;
1275 for (
const auto &boundary_function : function_map)
1276 boundary_ids.insert(boundary_function.first);
1283 template <
int dim,
int spacedim>
1286 const std::set<types::boundary_id> &boundary_ids,
1287 std::vector<IndexSet> &boundary_indices,
1293 if (boundary_ids.empty())
1297 if (boundary_indices[i].size() == 0)
1301 const bool fe_is_system = (n_components != 1);
1303 std::vector<types::global_dof_index> local_dofs;
1307 std::vector<std::vector<types::global_dof_index>> dofs_by_level(
1316 if (cell->is_artificial_on_level())
1319 const unsigned int level = cell->level();
1322 if (cell->at_boundary(face_no) ==
true)
1325 cell->face(face_no);
1328 if (boundary_ids.find(bi) != boundary_ids.end())
1331 face->get_mg_dof_indices(
level, local_dofs);
1332 dofs_by_level[
level].insert(dofs_by_level[
level].end(),
1343 "It's probably worthwhile to select at least one component."));
1346 if (!cell->is_artificial_on_level())
1349 if (cell->at_boundary(face_no) ==
false)
1353 const unsigned int level = cell->level();
1356 cell->face(face_no);
1358 face->boundary_id();
1359 if (boundary_ids.find(boundary_component) != boundary_ids.end())
1362 for (
unsigned int i = 0;
1363 i < cell->get_fe().n_dofs_per_cell();
1367 cell->get_fe().get_nonzero_components(i);
1371 bool selected =
false;
1372 for (
unsigned int c = 0; c < n_components; ++c)
1373 if (nonzero_component_array[c] ==
true &&
1374 component_mask[c] ==
true)
1380 for (
unsigned int c = 0; c < n_components; ++c)
1382 nonzero_component_array[c] ==
false ||
1383 component_mask[c] ==
true,
1385 "You are using a non-primitive FiniteElement "
1386 "and try to constrain just some of its components!"));
1392 face->get_mg_dof_indices(
level, local_dofs);
1395 for (
unsigned int i = 0; i < local_dofs.size(); ++i)
1397 unsigned int component =
1409 cell->get_fe().get_nonzero_components(i);
1410 for (
unsigned int c = 0; c < n_components; ++c)
1411 if (nonzero_component_array[c] ==
true)
1419 if (component_mask[component] ==
true)
1420 dofs_by_level[
level].push_back(local_dofs[i]);
1424 dofs_by_level[
level].insert(dofs_by_level[
level].end(),
1433 std::sort(dofs_by_level[
level].begin(), dofs_by_level[
level].end());
1434 boundary_indices[
level].add_indices(dofs_by_level[
level].begin(),
1435 dofs_by_level[
level].end());
1441 template <
int dim,
int spacedim>
1444 std::vector<IndexSet> &interface_dofs)
1446 Assert(interface_dofs.size() ==
1449 interface_dofs.size(),
1452 std::vector<std::vector<types::global_dof_index>> tmp_interface_dofs(
1453 interface_dofs.size());
1459 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1461 std::vector<bool> cell_dofs(dofs_per_cell,
false);
1467 if (cell->is_artificial_on_level())
1470 bool has_coarser_neighbor =
false;
1472 std::fill(cell_dofs.begin(), cell_dofs.end(),
false);
1477 cell->face(face_nr);
1478 if (!face->at_boundary() || cell->has_periodic_neighbor(face_nr))
1482 cell->neighbor_or_periodic_neighbor(face_nr);
1486 if (neighbor->is_artificial_on_level())
1490 if (neighbor->level() < cell->level())
1496 has_coarser_neighbor =
true;
1501 if (has_coarser_neighbor ==
false)
1504 const unsigned int level = cell->level();
1505 cell->get_mg_dof_indices(local_dof_indices);
1507 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1510 tmp_interface_dofs[
level].push_back(local_dof_indices[i]);
1514 for (
unsigned int l = 0;
1518 interface_dofs[l].clear();
1519 std::sort(tmp_interface_dofs[l].begin(), tmp_interface_dofs[l].end());
1520 interface_dofs[l].add_indices(tmp_interface_dofs[l].begin(),
1521 tmp_interface_dofs[l].end());
1522 interface_dofs[l].compress();
1528 template <
int dim,
int spacedim>
1539 if (cell->is_locally_owned())
1541 min_level = cell->level();
1545 unsigned int global_min = min_level;
1564 const std::vector<types::global_dof_index> &n_cells_on_levels,
1567 std::vector<types::global_dof_index> n_cells_on_levels_max(
1568 n_cells_on_levels.size());
1569 std::vector<types::global_dof_index> n_cells_on_levels_sum(
1570 n_cells_on_levels.size());
1577 const double ideal_work = std::accumulate(n_cells_on_levels_sum.begin(),
1578 n_cells_on_levels_sum.end(),
1580 static_cast<double>(n_proc);
1582 std::accumulate(n_cells_on_levels_max.begin(),
1583 n_cells_on_levels_max.end(),
1595 std::pair<types::global_dof_index, types::global_dof_index>> &cells,
1598 std::vector<types::global_dof_index> cells_local(cells.size());
1599 std::vector<types::global_dof_index> cells_remote(cells.size());
1601 for (
unsigned int i = 0; i < cells.size(); ++i)
1603 cells_local[i] = cells[i].first;
1604 cells_remote[i] = cells[i].second;
1607 std::vector<types::global_dof_index> cells_local_sum(cells_local.size());
1610 std::vector<types::global_dof_index> cells_remote_sum(
1611 cells_remote.size());
1614 const auto n_cells_local =
1615 std::accumulate(cells_local_sum.begin(), cells_local_sum.end(), 0);
1616 const auto n_cells_remote =
1617 std::accumulate(cells_remote_sum.begin(), cells_remote_sum.end(), 0);
1619 return static_cast<double>(n_cells_local) /
1620 (n_cells_local + n_cells_remote);
1626 template <
int dim,
int spacedim>
1627 std::vector<types::global_dof_index>
1634 tr->is_multilevel_hierarchy_constructed(),
1636 "We can only compute the workload imbalance if the multilevel hierarchy has been constructed!"));
1640 std::vector<types::global_dof_index> n_cells_on_levels(n_global_levels);
1642 for (
unsigned int lvl = 0; lvl < n_global_levels; ++lvl)
1644 if (cell->is_locally_owned_on_level())
1645 ++n_cells_on_levels[lvl];
1647 return n_cells_on_levels;
1652 template <
int dim,
int spacedim>
1653 std::vector<types::global_dof_index>
1658 const unsigned int n_global_levels = trias.size();
1660 std::vector<types::global_dof_index> n_cells_on_levels(n_global_levels);
1662 for (
unsigned int lvl = 0; lvl < n_global_levels; ++lvl)
1663 for (
const auto &cell : trias[lvl]->active_cell_iterators())
1664 if (cell->is_locally_owned())
1665 ++n_cells_on_levels[lvl];
1667 return n_cells_on_levels;
1672 template <
int dim,
int spacedim>
1682 template <
int dim,
int spacedim>
1689 trias.back()->get_communicator());
1694 template <
int dim,
int spacedim>
1695 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1700 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1701 cells(n_global_levels);
1707 for (
unsigned int lvl = 0; lvl < n_global_levels - 1; ++lvl)
1709 if (cell->is_locally_owned_on_level() && cell->has_children())
1710 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_cell;
1713 const auto level_subdomain_id =
1714 cell->child(i)->level_subdomain_id();
1715 if (level_subdomain_id == my_rank)
1716 ++cells[lvl + 1].first;
1718 ++cells[lvl + 1].second;
1728 template <
int dim,
int spacedim>
1729 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1734 const unsigned int n_global_levels = trias.size();
1736 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1737 cells(n_global_levels);
1739 const MPI_Comm communicator = trias.back()->get_communicator();
1743 for (
unsigned int lvl = 0; lvl < n_global_levels - 1; ++lvl)
1745 const auto &tria_coarse = *trias[lvl];
1746 const auto &tria_fine = *trias[lvl + 1];
1748 const unsigned int n_coarse_cells = tria_fine.n_global_coarse_cells();
1749 const unsigned int n_global_levels = tria_fine.n_global_levels();
1751 const ::internal::CellIDTranslator<dim> cell_id_translator(
1752 n_coarse_cells, n_global_levels);
1754 IndexSet is_fine_owned(cell_id_translator.size());
1755 IndexSet is_fine_required(cell_id_translator.size());
1757 for (
const auto &cell : tria_fine.active_cell_iterators())
1758 if (!cell->is_artificial() && cell->is_locally_owned())
1759 is_fine_owned.
add_index(cell_id_translator.translate(cell));
1761 for (
const auto &cell : tria_coarse.active_cell_iterators())
1762 if (!cell->is_artificial() && cell->is_locally_owned())
1764 if (cell->level() + 1u == tria_fine.n_global_levels())
1767 for (
unsigned int i = 0;
1768 i < GeometryInfo<dim>::max_children_per_cell;
1771 cell_id_translator.translate(cell, i));
1774 std::vector<unsigned int> is_fine_required_ranks(
1778 process(is_fine_owned,
1781 is_fine_required_ranks,
1786 std::pair<types::global_cell_index, types::global_cell_index>>,
1787 std::vector<unsigned int>>
1788 consensus_algorithm;
1789 consensus_algorithm.
run(process, communicator);
1791 for (
unsigned i = 0; i < is_fine_required.
n_elements(); ++i)
1792 if (is_fine_required_ranks[i] == my_rank)
1793 ++cells[lvl + 1].first;
1795 ++cells[lvl + 1].second;
1803 template <
int dim,
int spacedim>
1813 template <
int dim,
int spacedim>
1821 trias.back()->get_communicator());
1828#include "mg_tools.inst"
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
void add_entries_local_to_global(const std::vector< size_type > &local_dof_indices, SparsityPatternBase &sparsity_pattern, const bool keep_constrained_entries=true, const Table< 2, bool > &dof_mask=Table< 2, bool >()) const
unsigned int n_selected_components(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 Triangulation< dim, spacedim > & get_triangulation() const
types::global_dof_index n_dofs() const
unsigned int get_first_line_index() const
unsigned int n_dofs_per_cell() const
unsigned int get_first_quad_index(const unsigned int quad_no=0) 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
ReferenceCell reference_cell() const
unsigned int get_first_hex_index() const
std::pair< unsigned int, types::global_dof_index > system_to_block_index(const unsigned int component) const
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
virtual unsigned int face_to_cell_index(const unsigned int face_dof_index, const unsigned int face, const unsigned char combined_orientation=ReferenceCell::default_combined_face_orientation()) const
bool is_primitive() const
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) 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
types::global_dof_index first_block_of_base(const unsigned int b) const
size_type n_elements() const
void add_index(const size_type index)
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
virtual MPI_Comm get_communicator() const
unsigned int n_raw_lines() const
unsigned int n_levels() const
virtual unsigned int n_global_levels() const
unsigned int n_raw_quads() const
virtual std::vector< unsigned int > run(const std::vector< unsigned int > &targets, const std::function< RequestType(const unsigned int)> &create_request, const std::function< AnswerType(const unsigned int, const RequestType &)> &answer_request, const std::function< void(const unsigned int, const AnswerType &)> &process_answer, const MPI_Comm comm) override
unsigned int max_dofs_per_face() const
unsigned int n_components() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
IteratorRange< cell_iterator > cell_iterators() const
IteratorRange< active_cell_iterator > active_cell_iterators() const
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
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)
#define DEAL_II_NOT_IMPLEMENTED()
constexpr const ReferenceCell & get_hypercube()
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
*braid_SplitCommworld & comm
static std_cxx20::ranges::iota_view< unsigned int, unsigned int > face_indices()