60 std::vector<unsigned int> &,
72 std::vector<unsigned int> &,
85 std::vector<unsigned int> &,
96 std::vector<unsigned int> &,
106 template <
int dim,
int spacedim>
109 const unsigned int level,
110 std::vector<unsigned int> &row_lengths,
118 std::fill(row_lengths.begin(), row_lengths.end(), 0);
120 std::vector<bool> face_touched(dim == 2 ?
124 std::vector<types::global_dof_index> cell_indices;
125 std::vector<types::global_dof_index> neighbor_indices;
138 cell->get_mg_dof_indices(cell_indices);
162 const unsigned int face_no = 0;
167 unsigned int increment =
170 row_lengths[cell_indices[i++]] += increment;
187 row_lengths[cell_indices[i++]] += increment;
196 row_lengths[cell_indices[i++]] += increment;
201 row_lengths[cell_indices[i++]] += increment;
216 bool level_boundary = cell->at_boundary(iface);
220 neighbor = cell->neighbor(iface);
221 if (
static_cast<unsigned int>(neighbor->level()) !=
level)
222 level_boundary =
true;
227 for (
unsigned int local_dof = 0;
230 row_lengths[cell_indices[local_dof]] +=
249 const unsigned int dof_increment =
251 for (
unsigned int local_dof = 0;
254 row_lengths[cell_indices[local_dof]] += dof_increment;
259 if (face_touched[face->index()])
261 face_touched[face->index()] =
true;
276 neighbor->get_mg_dof_indices(neighbor_indices);
279 row_lengths[cell_indices[local_dof]] +=
283 row_lengths[neighbor_indices[local_dof]] +=
291 template <
int dim,
int spacedim>
294 const unsigned int level,
295 std::vector<unsigned int> &row_lengths,
304 std::fill(row_lengths.begin(), row_lengths.end(), 0);
306 std::vector<bool> face_touched(dim == 2 ?
310 std::vector<types::global_dof_index> cell_indices;
311 std::vector<types::global_dof_index> neighbor_indices;
317 std::vector<Table<2, DoFTools::Coupling>> couple_cell;
318 std::vector<Table<2, DoFTools::Coupling>> couple_face;
332 const unsigned int fe_index = cell->active_fe_index();
336 const unsigned int face_no = 0;
352 cell->get_mg_dof_indices(cell_indices);
375 unsigned int increment;
388 row_lengths[cell_indices[i]] += increment;
413 ((dim > 1) ? (dim - 1) :
416 row_lengths[cell_indices[i]] += increment;
433 ((dim > 2) ? (dim - 2) :
436 row_lengths[cell_indices[i]] += increment;
455 row_lengths[cell_indices[i]] += increment;
473 bool level_boundary = cell->at_boundary(iface);
477 neighbor = cell->neighbor(iface);
478 if (
static_cast<unsigned int>(neighbor->level()) !=
level)
479 level_boundary =
true;
484 for (
unsigned int local_dof = 0;
487 row_lengths[cell_indices[local_dof]] +=
507 for (
unsigned int local_dof = 0;
510 if (couple_face[fe_index](
514 const unsigned int dof_increment =
517 row_lengths[cell_indices[local_dof]] += dof_increment;
521 if (face_touched[face->index()])
523 face_touched[face->index()] =
true;
546 neighbor->get_mg_dof_indices(neighbor_indices);
550 for (
unsigned int local_dof = 0;
553 if (couple_cell[fe_index](
556 row_lengths[cell_indices[local_dof]] +=
561 for (
unsigned int local_dof = 0;
564 if (couple_cell[fe_index](
567 row_lengths[neighbor_indices[local_dof]] +=
575 template <
int dim,
int spacedim,
typename number>
579 const unsigned int level,
581 const bool keep_constrained_dofs)
592 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
594 if (cell->is_locally_owned_on_level())
596 cell->get_mg_dof_indices(dofs_on_this_cell);
599 keep_constrained_dofs);
605 template <
int dim,
int spacedim,
typename number>
609 const unsigned int level,
611 const bool keep_constrained_dofs)
622 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
623 std::vector<types::global_dof_index> dofs_on_other_cell(dofs_per_cell);
626 if (!cell->is_locally_owned_on_level())
629 cell->get_mg_dof_indices(dofs_on_this_cell);
633 keep_constrained_dofs);
638 bool use_face =
false;
639 if ((!cell->at_boundary(face)) &&
640 (
static_cast<unsigned int>(cell->neighbor_level(face)) ==
643 else if (cell->has_periodic_neighbor(face) &&
644 (
static_cast<unsigned int>(
645 cell->periodic_neighbor_level(face)) ==
level))
651 cell->neighbor_or_periodic_neighbor(face);
652 neighbor->get_mg_dof_indices(dofs_on_other_cell);
659 keep_constrained_dofs);
661 if (neighbor->is_locally_owned_on_level() ==
false)
664 dofs_on_other_cell, sparsity, keep_constrained_dofs);
670 keep_constrained_dofs);
679 template <
int dim,
int spacedim>
683 const unsigned int level)
701 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
702 std::vector<types::global_dof_index> dofs_on_other_cell(dofs_per_cell);
705 if (!cell->is_locally_owned_on_level())
708 cell->get_mg_dof_indices(dofs_on_this_cell);
713 bool use_face =
false;
714 if ((!cell->at_boundary(face)) &&
715 (
static_cast<unsigned int>(cell->neighbor_level(face)) !=
718 else if (cell->has_periodic_neighbor(face) &&
719 (
static_cast<unsigned int>(
720 cell->periodic_neighbor_level(face)) !=
level))
726 cell->neighbor_or_periodic_neighbor(face);
727 neighbor->get_mg_dof_indices(dofs_on_other_cell);
729 std::sort(dofs_on_this_cell.begin(), dofs_on_this_cell.end());
730 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
741 template <
int dim,
int spacedim>
745 const unsigned int level,
759 Assert(int_mask.n_rows() == n_comp,
761 Assert(int_mask.n_cols() == n_comp,
763 Assert(flux_mask.n_rows() == n_comp,
765 Assert(flux_mask.n_cols() == n_comp,
769 std::vector<types::global_dof_index> dofs_on_this_cell(total_dofs);
770 std::vector<types::global_dof_index> dofs_on_other_cell(total_dofs);
771 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
783 for (
unsigned int i = 0; i < total_dofs; ++i)
787 std::vector<bool> face_touched(dim == 2 ?
793 if (!cell->is_locally_owned_on_level())
796 cell->get_mg_dof_indices(dofs_on_this_cell);
798 for (
unsigned int i = 0; i < total_dofs; ++i)
799 for (
unsigned int j = 0; j < total_dofs; ++j)
801 cell_entries.emplace_back(dofs_on_this_cell[i],
802 dofs_on_this_cell[j]);
809 if (face_touched[cell_face->index()])
812 if (cell->at_boundary(face) && !cell->has_periodic_neighbor(face))
814 for (
unsigned int i = 0; i < total_dofs; ++i)
816 const bool i_non_zero_i = support_on_face(i, face);
817 for (
unsigned int j = 0; j < total_dofs; ++j)
819 const bool j_non_zero_i = support_on_face(j, face);
822 cell_entries.emplace_back(dofs_on_this_cell[i],
823 dofs_on_this_cell[j]);
825 i_non_zero_i && j_non_zero_i)
826 cell_entries.emplace_back(dofs_on_this_cell[i],
827 dofs_on_this_cell[j]);
834 cell->neighbor_or_periodic_neighbor(face);
836 if (neighbor->level() < cell->level())
839 unsigned int neighbor_face =
840 cell->has_periodic_neighbor(face) ?
841 cell->periodic_neighbor_of_periodic_neighbor(face) :
842 cell->neighbor_of_neighbor(face);
844 neighbor->get_mg_dof_indices(dofs_on_other_cell);
845 for (
unsigned int i = 0; i < total_dofs; ++i)
847 const bool i_non_zero_i = support_on_face(i, face);
848 const bool i_non_zero_e = support_on_face(i, neighbor_face);
849 for (
unsigned int j = 0; j < total_dofs; ++j)
851 const bool j_non_zero_i = support_on_face(j, face);
852 const bool j_non_zero_e =
853 support_on_face(j, neighbor_face);
856 cell_entries.emplace_back(dofs_on_this_cell[i],
857 dofs_on_other_cell[j]);
858 cell_entries.emplace_back(dofs_on_other_cell[i],
859 dofs_on_this_cell[j]);
860 cell_entries.emplace_back(dofs_on_this_cell[i],
861 dofs_on_this_cell[j]);
862 cell_entries.emplace_back(dofs_on_other_cell[i],
863 dofs_on_other_cell[j]);
867 if (i_non_zero_i && j_non_zero_e)
868 cell_entries.emplace_back(dofs_on_this_cell[i],
869 dofs_on_other_cell[j]);
870 if (i_non_zero_e && j_non_zero_i)
871 cell_entries.emplace_back(dofs_on_other_cell[i],
872 dofs_on_this_cell[j]);
873 if (i_non_zero_i && j_non_zero_i)
874 cell_entries.emplace_back(dofs_on_this_cell[i],
875 dofs_on_this_cell[j]);
876 if (i_non_zero_e && j_non_zero_e)
877 cell_entries.emplace_back(dofs_on_other_cell[i],
878 dofs_on_other_cell[j]);
883 cell_entries.emplace_back(dofs_on_this_cell[j],
884 dofs_on_other_cell[i]);
885 cell_entries.emplace_back(dofs_on_other_cell[j],
886 dofs_on_this_cell[i]);
887 cell_entries.emplace_back(dofs_on_this_cell[j],
888 dofs_on_this_cell[i]);
889 cell_entries.emplace_back(dofs_on_other_cell[j],
890 dofs_on_other_cell[i]);
894 if (j_non_zero_i && i_non_zero_e)
895 cell_entries.emplace_back(dofs_on_this_cell[j],
896 dofs_on_other_cell[i]);
897 if (j_non_zero_e && i_non_zero_i)
898 cell_entries.emplace_back(dofs_on_other_cell[j],
899 dofs_on_this_cell[i]);
900 if (j_non_zero_i && i_non_zero_i)
901 cell_entries.emplace_back(dofs_on_this_cell[j],
902 dofs_on_this_cell[i]);
903 if (j_non_zero_e && i_non_zero_e)
904 cell_entries.emplace_back(dofs_on_other_cell[j],
905 dofs_on_other_cell[i]);
909 face_touched[neighbor->face(neighbor_face)->index()] =
true;
913 cell_entries.clear();
919 template <
int dim,
int spacedim>
923 const unsigned int level,
944 Assert(flux_mask.n_rows() == n_comp,
946 Assert(flux_mask.n_cols() == n_comp,
950 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
951 std::vector<types::global_dof_index> dofs_on_other_cell(dofs_per_cell);
952 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
961 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
967 if (!cell->is_locally_owned_on_level())
970 cell->get_mg_dof_indices(dofs_on_this_cell);
975 bool use_face =
false;
976 if ((!cell->at_boundary(face)) &&
977 (
static_cast<unsigned int>(cell->neighbor_level(face)) !=
980 else if (cell->has_periodic_neighbor(face) &&
981 (
static_cast<unsigned int>(
982 cell->periodic_neighbor_level(face)) !=
level))
988 cell->neighbor_or_periodic_neighbor(face);
989 neighbor->get_mg_dof_indices(dofs_on_other_cell);
991 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
993 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
997 cell_entries.emplace_back(dofs_on_other_cell[i],
998 dofs_on_this_cell[j]);
999 cell_entries.emplace_back(dofs_on_other_cell[j],
1000 dofs_on_this_cell[i]);
1007 cell_entries.clear();
1013 template <
int dim,
int spacedim>
1018 const unsigned int level)
1029 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
1030 std::vector<types::global_dof_index> cols;
1031 cols.reserve(dofs_per_cell);
1034 if (cell->is_locally_owned_on_level())
1036 cell->get_mg_dof_indices(dofs_on_this_cell);
1037 std::sort(dofs_on_this_cell.begin(), dofs_on_this_cell.end());
1038 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1040 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
1042 level, dofs_on_this_cell[i], dofs_on_this_cell[j]))
1043 cols.push_back(dofs_on_this_cell[j]);
1054 template <
int dim,
int spacedim>
1058 std::vector<std::vector<types::global_dof_index>> &result,
1060 std::vector<unsigned int> target_component)
1064 const unsigned int nlevels =
1067 Assert(result.size() == nlevels,
1070 if (target_component.empty())
1072 target_component.resize(n_components);
1073 for (
unsigned int i = 0; i < n_components; ++i)
1074 target_component[i] = i;
1077 Assert(target_component.size() == n_components,
1080 for (
unsigned int l = 0; l < nlevels; ++l)
1082 result[l].resize(n_components);
1083 std::fill(result[l].begin(), result[l].end(), 0U);
1089 if (n_components == 1)
1091 result[l][0] = dof_handler.
n_dofs(l);
1098 std::vector<std::vector<bool>> dofs_in_component(
1099 n_components, std::vector<bool>(dof_handler.
n_dofs(l),
false));
1100 std::vector<ComponentMask> component_select(n_components);
1102 for (
unsigned int i = 0; i < n_components; ++i)
1104 void (*fun_ptr)(
const unsigned int level,
1107 std::vector<bool> &) =
1108 &DoFTools::extract_level_dofs<dim, spacedim>;
1110 std::vector<bool> tmp(n_components,
false);
1117 component_select[i],
1118 dofs_in_component[i]);
1123 unsigned int component = 0;
1132 for (
unsigned int dd = 0; dd < d; ++dd)
1135 result[l][target_component[component]] +=
1136 std::count(dofs_in_component[component].begin(),
1137 dofs_in_component[component].end(),
1145 std::accumulate(result[l].begin(),
1156 template <
int dim,
int spacedim>
1160 std::vector<std::vector<types::global_dof_index>> &dofs_per_block,
1161 std::vector<unsigned int> target_block)
1164 const unsigned int n_blocks = fe.
n_blocks();
1165 const unsigned int n_levels =
1170 for (
unsigned int l = 0; l < n_levels; ++l)
1171 std::fill(dofs_per_block[l].begin(), dofs_per_block[l].end(), 0U);
1175 if (target_block.empty())
1177 target_block.resize(n_blocks);
1178 for (
unsigned int i = 0; i < n_blocks; ++i)
1179 target_block[i] = i;
1181 Assert(target_block.size() == n_blocks,
1184 const unsigned int max_block =
1185 *std::max_element(target_block.begin(), target_block.end());
1186 const unsigned int n_target_blocks = max_block + 1;
1187 (void)n_target_blocks;
1189 for (
unsigned int l = 0; l < n_levels; ++l)
1198 for (
unsigned int l = 0; l < n_levels; ++l)
1199 dofs_per_block[l][0] = dof_handler.
n_dofs(l);
1205 for (
unsigned int l = 0; l < n_levels; ++l)
1207 std::vector<std::vector<bool>> dofs_in_block(
1208 n_blocks, std::vector<bool>(dof_handler.
n_dofs(l),
false));
1209 std::vector<BlockMask> block_select(n_blocks);
1211 for (
unsigned int i = 0; i < n_blocks; ++i)
1213 void (*fun_ptr)(
const unsigned int level,
1216 std::vector<bool> &) =
1217 &DoFTools::extract_level_dofs<dim, spacedim>;
1219 std::vector<bool> tmp(n_blocks,
false);
1224 fun_ptr, l, dof_handler, block_select[i], dofs_in_block[i]);
1229 for (
unsigned int block = 0; block < fe.
n_blocks(); ++block)
1230 dofs_per_block[l][target_block[block]] +=
1231 std::count(dofs_in_block[block].begin(),
1232 dofs_in_block[block].end(),
1239 template <
int dim,
int spacedim>
1245 std::vector<std::set<types::global_dof_index>> &boundary_indices,
1252 std::set<types::boundary_id> boundary_ids;
1253 for (
const auto &boundary_function : function_map)
1254 boundary_ids.insert(boundary_function.first);
1256 std::vector<IndexSet> boundary_indexset;
1259 boundary_indices[i].insert(boundary_indexset[i].begin(),
1260 boundary_indexset[i].end());
1264 template <
int dim,
int spacedim>
1269 std::vector<IndexSet> &boundary_indices,
1276 std::set<types::boundary_id> boundary_ids;
1277 for (
const auto &boundary_function : function_map)
1278 boundary_ids.insert(boundary_function.first);
1285 template <
int dim,
int spacedim>
1288 const std::set<types::boundary_id> &boundary_ids,
1289 std::vector<IndexSet> &boundary_indices,
1295 if (boundary_ids.empty())
1299 if (boundary_indices[i].
size() == 0)
1303 const bool fe_is_system = (n_components != 1);
1305 std::vector<types::global_dof_index> local_dofs;
1309 std::vector<std::vector<types::global_dof_index>> dofs_by_level(
1318 if (cell->is_artificial_on_level())
1321 const unsigned int level = cell->level();
1324 if (cell->at_boundary(face_no) ==
true)
1327 cell->face(face_no);
1330 if (boundary_ids.find(bi) != boundary_ids.end())
1333 face->get_mg_dof_indices(
level, local_dofs);
1334 dofs_by_level[
level].insert(dofs_by_level[
level].end(),
1345 "It's probably worthwhile to select at least one component."));
1348 if (!cell->is_artificial_on_level())
1351 if (cell->at_boundary(face_no) ==
false)
1355 const unsigned int level = cell->level();
1358 cell->face(face_no);
1360 face->boundary_id();
1361 if (boundary_ids.find(boundary_component) != boundary_ids.end())
1364 for (
unsigned int i = 0;
1365 i < cell->get_fe().n_dofs_per_cell();
1369 cell->get_fe().get_nonzero_components(i);
1373 bool selected =
false;
1374 for (
unsigned int c = 0; c < n_components; ++c)
1375 if (nonzero_component_array[c] ==
true &&
1376 component_mask[c] ==
true)
1382 for (
unsigned int c = 0; c < n_components; ++c)
1384 nonzero_component_array[c] ==
false ||
1385 component_mask[c] ==
true,
1387 "You are using a non-primitive FiniteElement "
1388 "and try to constrain just some of its components!"));
1394 face->get_mg_dof_indices(
level, local_dofs);
1397 for (
unsigned int i = 0; i < local_dofs.size(); ++i)
1399 unsigned int component =
1411 cell->get_fe().get_nonzero_components(i);
1412 for (
unsigned int c = 0; c < n_components; ++c)
1413 if (nonzero_component_array[c] ==
true)
1421 if (component_mask[component] ==
true)
1422 dofs_by_level[
level].push_back(local_dofs[i]);
1426 dofs_by_level[
level].insert(dofs_by_level[
level].end(),
1435 std::sort(dofs_by_level[
level].begin(), dofs_by_level[
level].end());
1436 boundary_indices[
level].add_indices(dofs_by_level[
level].begin(),
1437 dofs_by_level[
level].end());
1443 template <
int dim,
int spacedim>
1446 std::vector<IndexSet> &interface_dofs)
1448 Assert(interface_dofs.size() ==
1451 interface_dofs.size(),
1454 std::vector<std::vector<types::global_dof_index>> tmp_interface_dofs(
1455 interface_dofs.size());
1461 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1463 std::vector<bool> cell_dofs(dofs_per_cell,
false);
1469 if (cell->is_artificial_on_level())
1472 bool has_coarser_neighbor =
false;
1474 std::fill(cell_dofs.begin(), cell_dofs.end(),
false);
1479 cell->face(face_nr);
1480 if (!face->at_boundary() || cell->has_periodic_neighbor(face_nr))
1484 cell->neighbor_or_periodic_neighbor(face_nr);
1488 if (neighbor->is_artificial_on_level())
1492 if (neighbor->level() < cell->level())
1498 has_coarser_neighbor =
true;
1503 if (has_coarser_neighbor ==
false)
1506 const unsigned int level = cell->level();
1507 cell->get_mg_dof_indices(local_dof_indices);
1509 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1512 tmp_interface_dofs[
level].push_back(local_dof_indices[i]);
1516 for (
unsigned int l = 0;
1520 interface_dofs[l].clear();
1521 std::sort(tmp_interface_dofs[l].begin(), tmp_interface_dofs[l].end());
1522 interface_dofs[l].add_indices(tmp_interface_dofs[l].begin(),
1523 tmp_interface_dofs[l].end());
1524 interface_dofs[l].compress();
1530 template <
int dim,
int spacedim>
1541 if (cell->is_locally_owned())
1543 min_level = cell->level();
1547 unsigned int global_min = min_level;
1566 const std::vector<types::global_dof_index> &n_cells_on_levels,
1569 std::vector<types::global_dof_index> n_cells_on_levels_max(
1570 n_cells_on_levels.size());
1571 std::vector<types::global_dof_index> n_cells_on_levels_sum(
1572 n_cells_on_levels.size());
1579 const double ideal_work = std::accumulate(n_cells_on_levels_sum.begin(),
1580 n_cells_on_levels_sum.end(),
1582 static_cast<double>(n_proc);
1584 std::accumulate(n_cells_on_levels_max.begin(),
1585 n_cells_on_levels_max.end(),
1597 std::pair<types::global_dof_index, types::global_dof_index>> &cells,
1600 std::vector<types::global_dof_index> cells_local(cells.size());
1601 std::vector<types::global_dof_index> cells_remote(cells.size());
1603 for (
unsigned int i = 0; i < cells.size(); ++i)
1605 cells_local[i] = cells[i].first;
1606 cells_remote[i] = cells[i].second;
1609 std::vector<types::global_dof_index> cells_local_sum(cells_local.size());
1612 std::vector<types::global_dof_index> cells_remote_sum(
1613 cells_remote.size());
1616 const auto n_cells_local =
1617 std::accumulate(cells_local_sum.begin(), cells_local_sum.end(), 0);
1618 const auto n_cells_remote =
1619 std::accumulate(cells_remote_sum.begin(), cells_remote_sum.end(), 0);
1621 return static_cast<double>(n_cells_local) /
1622 (n_cells_local + n_cells_remote);
1628 template <
int dim,
int spacedim>
1629 std::vector<types::global_dof_index>
1636 tr->is_multilevel_hierarchy_constructed(),
1638 "We can only compute the workload imbalance if the multilevel hierarchy has been constructed!"));
1642 std::vector<types::global_dof_index> n_cells_on_levels(n_global_levels);
1644 for (
unsigned int lvl = 0; lvl < n_global_levels; ++lvl)
1646 if (cell->is_locally_owned_on_level())
1647 ++n_cells_on_levels[lvl];
1649 return n_cells_on_levels;
1654 template <
int dim,
int spacedim>
1655 std::vector<types::global_dof_index>
1660 const unsigned int n_global_levels = trias.size();
1662 std::vector<types::global_dof_index> n_cells_on_levels(n_global_levels);
1664 for (
unsigned int lvl = 0; lvl < n_global_levels; ++lvl)
1665 for (
const auto &cell : trias[lvl]->active_cell_iterators())
1666 if (cell->is_locally_owned())
1667 ++n_cells_on_levels[lvl];
1669 return n_cells_on_levels;
1674 template <
int dim,
int spacedim>
1684 template <
int dim,
int spacedim>
1691 trias.back()->get_mpi_communicator());
1696 template <
int dim,
int spacedim>
1697 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1702 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1703 cells(n_global_levels);
1709 for (
unsigned int lvl = 0; lvl < n_global_levels - 1; ++lvl)
1711 if (cell->is_locally_owned_on_level() && cell->has_children())
1712 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_cell;
1715 const auto level_subdomain_id =
1716 cell->child(i)->level_subdomain_id();
1717 if (level_subdomain_id ==
my_rank)
1718 ++cells[lvl + 1].first;
1720 ++cells[lvl + 1].second;
1730 template <
int dim,
int spacedim>
1731 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1736 const unsigned int n_global_levels = trias.size();
1738 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1739 cells(n_global_levels);
1741 const MPI_Comm communicator = trias.back()->get_mpi_communicator();
1745 for (
unsigned int lvl = 0; lvl < n_global_levels - 1; ++lvl)
1747 const auto &tria_coarse = *trias[lvl];
1748 const auto &tria_fine = *trias[lvl + 1];
1750 const unsigned int n_coarse_cells = tria_fine.n_global_coarse_cells();
1751 const unsigned int n_global_levels = tria_fine.n_global_levels();
1753 const ::internal::CellIDTranslator<dim> cell_id_translator(
1754 n_coarse_cells, n_global_levels);
1756 IndexSet is_fine_owned(cell_id_translator.size());
1757 IndexSet is_fine_required(cell_id_translator.size());
1759 for (
const auto &cell : tria_fine.active_cell_iterators())
1760 if (!cell->is_artificial() && cell->is_locally_owned())
1761 is_fine_owned.
add_index(cell_id_translator.translate(cell));
1763 for (
const auto &cell : tria_coarse.active_cell_iterators())
1764 if (!cell->is_artificial() && cell->is_locally_owned())
1766 if (cell->level() + 1u == tria_fine.n_global_levels())
1769 for (
unsigned int i = 0;
1770 i < GeometryInfo<dim>::max_children_per_cell;
1773 cell_id_translator.translate(cell, i));
1776 const std::vector<unsigned int> is_fine_required_ranks =
1781 for (
unsigned i = 0; i < is_fine_required.
n_elements(); ++i)
1782 if (is_fine_required_ranks[i] ==
my_rank)
1783 ++cells[lvl + 1].first;
1785 ++cells[lvl + 1].second;
1793 template <
int dim,
int spacedim>
1803 template <
int dim,
int spacedim>
1811 trias.back()->get_mpi_communicator());
1818#include "multigrid/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
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
virtual unsigned int face_to_cell_index(const unsigned int face_dof_index, const unsigned int face, const types::geometric_orientation combined_orientation=numbers::default_geometric_orientation) 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_mpi_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
unsigned int max_dofs_per_face() const
unsigned int n_components() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NOT_IMPLEMENTED()
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)
const unsigned int my_rank
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)
std::vector< unsigned int > compute_index_owner(const IndexSet &owned_indices, const IndexSet &indices_to_look_up, const MPI_Comm comm)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
constexpr types::global_dof_index invalid_dof_index
constexpr unsigned int invalid_unsigned_int
static std_cxx20::ranges::iota_view< unsigned int, unsigned int > face_indices()