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,
109 std::vector<unsigned int> & row_lengths,
117 std::fill(row_lengths.begin(), row_lengths.end(), 0);
119 std::vector<bool> face_touched(dim == 2 ?
123 std::vector<types::global_dof_index> cell_indices;
124 std::vector<types::global_dof_index> neighbor_indices;
137 cell->get_mg_dof_indices(cell_indices);
161 const unsigned int face_no = 0;
166 unsigned int increment =
169 row_lengths[cell_indices[i++]] += increment;
186 row_lengths[cell_indices[i++]] += increment;
195 row_lengths[cell_indices[i++]] += increment;
200 row_lengths[cell_indices[i++]] += increment;
215 bool level_boundary = cell->at_boundary(iface);
219 neighbor = cell->neighbor(iface);
220 if (
static_cast<unsigned int>(neighbor->level()) !=
level)
221 level_boundary =
true;
226 for (
unsigned int local_dof = 0;
229 row_lengths[cell_indices[local_dof]] +=
248 const unsigned int dof_increment =
250 for (
unsigned int local_dof = 0;
253 row_lengths[cell_indices[local_dof]] += dof_increment;
258 if (face_touched[face->index()])
260 face_touched[face->index()] =
true;
275 neighbor->get_mg_dof_indices(neighbor_indices);
278 row_lengths[cell_indices[local_dof]] +=
282 row_lengths[neighbor_indices[local_dof]] +=
290 template <
int dim,
int spacedim>
293 const unsigned int level,
294 std::vector<unsigned int> & row_lengths,
303 std::fill(row_lengths.begin(), row_lengths.end(), 0);
305 std::vector<bool> face_touched(dim == 2 ?
309 std::vector<types::global_dof_index> cell_indices;
310 std::vector<types::global_dof_index> neighbor_indices;
316 std::vector<Table<2, DoFTools::Coupling>> couple_cell;
317 std::vector<Table<2, DoFTools::Coupling>> couple_face;
331 const unsigned int fe_index = cell->active_fe_index();
335 const unsigned int face_no = 0;
351 cell->get_mg_dof_indices(cell_indices);
374 unsigned int increment;
387 row_lengths[cell_indices[i]] += increment;
412 ((dim > 1) ? (dim - 1) :
415 row_lengths[cell_indices[i]] += increment;
432 ((dim > 2) ? (dim - 2) :
435 row_lengths[cell_indices[i]] += increment;
454 row_lengths[cell_indices[i]] += increment;
472 bool level_boundary = cell->at_boundary(iface);
476 neighbor = cell->neighbor(iface);
477 if (
static_cast<unsigned int>(neighbor->level()) !=
level)
478 level_boundary =
true;
483 for (
unsigned int local_dof = 0;
486 row_lengths[cell_indices[local_dof]] +=
506 for (
unsigned int local_dof = 0;
509 if (couple_face[fe_index](
513 const unsigned int dof_increment =
516 row_lengths[cell_indices[local_dof]] += dof_increment;
520 if (face_touched[face->index()])
522 face_touched[face->index()] =
true;
545 neighbor->get_mg_dof_indices(neighbor_indices);
549 for (
unsigned int local_dof = 0;
552 if (couple_cell[fe_index](
555 row_lengths[cell_indices[local_dof]] +=
560 for (
unsigned int local_dof = 0;
563 if (couple_cell[fe_index](
566 row_lengths[neighbor_indices[local_dof]] +=
576 typename SparsityPatternType,
580 SparsityPatternType & sparsity,
581 const unsigned int level,
583 const bool keep_constrained_dofs)
588 Assert(sparsity.n_rows() == n_dofs,
590 Assert(sparsity.n_cols() == n_dofs,
594 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
596 if (cell->is_locally_owned_on_level())
598 cell->get_mg_dof_indices(dofs_on_this_cell);
601 keep_constrained_dofs);
609 typename SparsityPatternType,
613 SparsityPatternType & sparsity,
614 const unsigned int level,
616 const bool keep_constrained_dofs)
621 Assert(sparsity.n_rows() == n_dofs,
623 Assert(sparsity.n_cols() == n_dofs,
627 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
628 std::vector<types::global_dof_index> dofs_on_other_cell(dofs_per_cell);
631 if (!cell->is_locally_owned_on_level())
634 cell->get_mg_dof_indices(dofs_on_this_cell);
638 keep_constrained_dofs);
643 bool use_face =
false;
644 if ((!cell->at_boundary(face)) &&
645 (
static_cast<unsigned int>(cell->neighbor_level(face)) ==
648 else if (cell->has_periodic_neighbor(face) &&
649 (
static_cast<unsigned int>(
650 cell->periodic_neighbor_level(face)) ==
level))
656 cell->neighbor_or_periodic_neighbor(face);
657 neighbor->get_mg_dof_indices(dofs_on_other_cell);
664 keep_constrained_dofs);
666 if (neighbor->is_locally_owned_on_level() ==
false)
669 dofs_on_other_cell, sparsity, keep_constrained_dofs);
675 keep_constrained_dofs);
684 template <
int dim,
typename SparsityPatternType,
int spacedim>
687 SparsityPatternType & sparsity,
688 const unsigned int level)
700 Assert(sparsity.n_rows() == coarse_dofs,
702 Assert(sparsity.n_cols() == fine_dofs,
706 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
707 std::vector<types::global_dof_index> dofs_on_other_cell(dofs_per_cell);
710 if (!cell->is_locally_owned_on_level())
713 cell->get_mg_dof_indices(dofs_on_this_cell);
718 bool use_face =
false;
719 if ((!cell->at_boundary(face)) &&
720 (
static_cast<unsigned int>(cell->neighbor_level(face)) !=
723 else if (cell->has_periodic_neighbor(face) &&
724 (
static_cast<unsigned int>(
725 cell->periodic_neighbor_level(face)) !=
level))
731 cell->neighbor_or_periodic_neighbor(face);
732 neighbor->get_mg_dof_indices(dofs_on_other_cell);
734 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
736 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
738 sparsity.add(dofs_on_other_cell[i],
739 dofs_on_this_cell[j]);
740 sparsity.add(dofs_on_other_cell[j],
741 dofs_on_this_cell[i]);
751 template <
int dim,
typename SparsityPatternType,
int spacedim>
754 SparsityPatternType & sparsity,
755 const unsigned int level,
765 Assert(sparsity.n_rows() == n_dofs,
767 Assert(sparsity.n_cols() == n_dofs,
769 Assert(int_mask.n_rows() == n_comp,
771 Assert(int_mask.n_cols() == n_comp,
773 Assert(flux_mask.n_rows() == n_comp,
775 Assert(flux_mask.n_cols() == n_comp,
779 std::vector<types::global_dof_index> dofs_on_this_cell(total_dofs);
780 std::vector<types::global_dof_index> dofs_on_other_cell(total_dofs);
790 for (
unsigned int i = 0; i < total_dofs; ++i)
794 std::vector<bool> face_touched(dim == 2 ?
800 if (!cell->is_locally_owned_on_level())
803 cell->get_mg_dof_indices(dofs_on_this_cell);
805 for (
unsigned int i = 0; i < total_dofs; ++i)
806 for (
unsigned int j = 0; j < total_dofs; ++j)
808 sparsity.add(dofs_on_this_cell[i], dofs_on_this_cell[j]);
815 if (face_touched[cell_face->index()])
818 if (cell->at_boundary(face) && !cell->has_periodic_neighbor(face))
820 for (
unsigned int i = 0; i < total_dofs; ++i)
822 const bool i_non_zero_i = support_on_face(i, face);
823 for (
unsigned int j = 0; j < total_dofs; ++j)
825 const bool j_non_zero_i = support_on_face(j, face);
828 sparsity.add(dofs_on_this_cell[i],
829 dofs_on_this_cell[j]);
831 i_non_zero_i && j_non_zero_i)
832 sparsity.add(dofs_on_this_cell[i],
833 dofs_on_this_cell[j]);
840 cell->neighbor_or_periodic_neighbor(face);
842 if (neighbor->level() < cell->level())
845 unsigned int neighbor_face =
846 cell->has_periodic_neighbor(face) ?
847 cell->periodic_neighbor_of_periodic_neighbor(face) :
848 cell->neighbor_of_neighbor(face);
850 neighbor->get_mg_dof_indices(dofs_on_other_cell);
851 for (
unsigned int i = 0; i < total_dofs; ++i)
853 const bool i_non_zero_i = support_on_face(i, face);
854 const bool i_non_zero_e = support_on_face(i, neighbor_face);
855 for (
unsigned int j = 0; j < total_dofs; ++j)
857 const bool j_non_zero_i = support_on_face(j, face);
858 const bool j_non_zero_e =
859 support_on_face(j, neighbor_face);
862 sparsity.add(dofs_on_this_cell[i],
863 dofs_on_other_cell[j]);
864 sparsity.add(dofs_on_other_cell[i],
865 dofs_on_this_cell[j]);
866 sparsity.add(dofs_on_this_cell[i],
867 dofs_on_this_cell[j]);
868 sparsity.add(dofs_on_other_cell[i],
869 dofs_on_other_cell[j]);
873 if (i_non_zero_i && j_non_zero_e)
874 sparsity.add(dofs_on_this_cell[i],
875 dofs_on_other_cell[j]);
876 if (i_non_zero_e && j_non_zero_i)
877 sparsity.add(dofs_on_other_cell[i],
878 dofs_on_this_cell[j]);
879 if (i_non_zero_i && j_non_zero_i)
880 sparsity.add(dofs_on_this_cell[i],
881 dofs_on_this_cell[j]);
882 if (i_non_zero_e && j_non_zero_e)
883 sparsity.add(dofs_on_other_cell[i],
884 dofs_on_other_cell[j]);
889 sparsity.add(dofs_on_this_cell[j],
890 dofs_on_other_cell[i]);
891 sparsity.add(dofs_on_other_cell[j],
892 dofs_on_this_cell[i]);
893 sparsity.add(dofs_on_this_cell[j],
894 dofs_on_this_cell[i]);
895 sparsity.add(dofs_on_other_cell[j],
896 dofs_on_other_cell[i]);
900 if (j_non_zero_i && i_non_zero_e)
901 sparsity.add(dofs_on_this_cell[j],
902 dofs_on_other_cell[i]);
903 if (j_non_zero_e && i_non_zero_i)
904 sparsity.add(dofs_on_other_cell[j],
905 dofs_on_this_cell[i]);
906 if (j_non_zero_i && i_non_zero_i)
907 sparsity.add(dofs_on_this_cell[j],
908 dofs_on_this_cell[i]);
909 if (j_non_zero_e && i_non_zero_e)
910 sparsity.add(dofs_on_other_cell[j],
911 dofs_on_other_cell[i]);
915 face_touched[neighbor->face(neighbor_face)->index()] =
true;
923 template <
int dim,
typename SparsityPatternType,
int spacedim>
926 SparsityPatternType & sparsity,
927 const unsigned int level,
944 Assert(sparsity.n_rows() == coarse_dofs,
946 Assert(sparsity.n_cols() == fine_dofs,
948 Assert(flux_mask.n_rows() == n_comp,
950 Assert(flux_mask.n_cols() == n_comp,
954 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
955 std::vector<types::global_dof_index> dofs_on_other_cell(dofs_per_cell);
962 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
968 if (!cell->is_locally_owned_on_level())
971 cell->get_mg_dof_indices(dofs_on_this_cell);
976 bool use_face =
false;
977 if ((!cell->at_boundary(face)) &&
978 (
static_cast<unsigned int>(cell->neighbor_level(face)) !=
981 else if (cell->has_periodic_neighbor(face) &&
982 (
static_cast<unsigned int>(
983 cell->periodic_neighbor_level(face)) !=
level))
989 cell->neighbor_or_periodic_neighbor(face);
990 neighbor->get_mg_dof_indices(dofs_on_other_cell);
992 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
994 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
998 sparsity.add(dofs_on_other_cell[i],
999 dofs_on_this_cell[j]);
1000 sparsity.add(dofs_on_other_cell[j],
1001 dofs_on_this_cell[i]);
1012 template <
int dim,
int spacedim,
typename SparsityPatternType>
1016 SparsityPatternType & sparsity,
1017 const unsigned int level)
1022 Assert(sparsity.n_rows() == n_dofs,
1024 Assert(sparsity.n_cols() == n_dofs,
1028 std::vector<types::global_dof_index> dofs_on_this_cell(dofs_per_cell);
1030 if (cell->is_locally_owned_on_level())
1032 cell->get_mg_dof_indices(dofs_on_this_cell);
1033 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1034 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
1036 level, dofs_on_this_cell[i], dofs_on_this_cell[j]))
1037 sparsity.add(dofs_on_this_cell[i], dofs_on_this_cell[j]);
1043 template <
int dim,
int spacedim>
1047 std::vector<std::vector<types::global_dof_index>> &result,
1049 std::vector<unsigned int> target_component)
1053 const unsigned int nlevels =
1056 Assert(result.size() == nlevels,
1059 if (target_component.size() == 0)
1061 target_component.resize(n_components);
1062 for (
unsigned int i = 0; i < n_components; ++i)
1063 target_component[i] = i;
1066 Assert(target_component.size() == n_components,
1069 for (
unsigned int l = 0;
l < nlevels; ++
l)
1071 result[
l].resize(n_components);
1072 std::fill(result[
l].
begin(), result[
l].
end(), 0
U);
1078 if (n_components == 1)
1080 result[
l][0] = dof_handler.
n_dofs(
l);
1087 std::vector<std::vector<bool>> dofs_in_component(
1088 n_components, std::vector<bool>(dof_handler.
n_dofs(
l),
false));
1089 std::vector<ComponentMask> component_select(n_components);
1091 for (
unsigned int i = 0; i < n_components; ++i)
1093 void (*fun_ptr)(
const unsigned int level,
1096 std::vector<bool> &) =
1097 &DoFTools::extract_level_dofs<dim, spacedim>;
1099 std::vector<bool> tmp(n_components,
false);
1106 component_select[i],
1107 dofs_in_component[i]);
1112 unsigned int component = 0;
1121 for (
unsigned int dd = 0; dd <
d; ++dd)
1124 result[
l][target_component[component]] +=
1125 std::count(dofs_in_component[component].
begin(),
1126 dofs_in_component[component].
end(),
1134 std::accumulate(result[
l].begin(),
1145 template <
int dim,
int spacedim>
1149 std::vector<std::vector<types::global_dof_index>> &dofs_per_block,
1150 std::vector<unsigned int> target_block)
1154 const unsigned int n_levels =
1159 for (
unsigned int l = 0;
l < n_levels; ++
l)
1160 std::fill(dofs_per_block[
l].
begin(), dofs_per_block[
l].
end(), 0
U);
1164 if (target_block.size() == 0)
1167 for (
unsigned int i = 0; i <
n_blocks; ++i)
1168 target_block[i] = i;
1173 const unsigned int max_block =
1174 *std::max_element(target_block.begin(), target_block.end());
1175 const unsigned int n_target_blocks = max_block + 1;
1176 (void)n_target_blocks;
1178 for (
unsigned int l = 0;
l < n_levels; ++
l)
1187 for (
unsigned int l = 0;
l < n_levels; ++
l)
1188 dofs_per_block[
l][0] = dof_handler.
n_dofs(
l);
1194 for (
unsigned int l = 0;
l < n_levels; ++
l)
1196 std::vector<std::vector<bool>> dofs_in_block(
1198 std::vector<BlockMask> block_select(
n_blocks);
1200 for (
unsigned int i = 0; i <
n_blocks; ++i)
1202 void (*fun_ptr)(
const unsigned int level,
1205 std::vector<bool> &) =
1206 &DoFTools::extract_level_dofs<dim, spacedim>;
1208 std::vector<bool> tmp(
n_blocks,
false);
1210 block_select[i] = tmp;
1213 fun_ptr,
l, dof_handler, block_select[i], dofs_in_block[i]);
1218 for (
unsigned int block = 0; block < fe.
n_blocks(); ++block)
1219 dofs_per_block[
l][target_block[block]] +=
1220 std::count(dofs_in_block[block].
begin(),
1221 dofs_in_block[block].
end(),
1228 template <
int dim,
int spacedim>
1234 std::vector<std::set<types::global_dof_index>> &boundary_indices,
1241 std::set<types::boundary_id> boundary_ids;
1242 for (
const auto &boundary_function : function_map)
1243 boundary_ids.insert(boundary_function.first);
1245 std::vector<IndexSet> boundary_indexset;
1248 boundary_indices[i].
insert(boundary_indexset[i].
begin(),
1249 boundary_indexset[i].
end());
1253 template <
int dim,
int spacedim>
1258 std::vector<IndexSet> &boundary_indices,
1265 std::set<types::boundary_id> boundary_ids;
1266 for (
const auto &boundary_function : function_map)
1267 boundary_ids.insert(boundary_function.first);
1274 template <
int dim,
int spacedim>
1277 const std::set<types::boundary_id> &boundary_ids,
1278 std::vector<IndexSet> & boundary_indices,
1284 if (boundary_ids.size() == 0)
1288 if (boundary_indices[i].size() == 0)
1292 const bool fe_is_system = (n_components != 1);
1294 std::vector<types::global_dof_index> local_dofs;
1298 std::vector<std::vector<types::global_dof_index>> dofs_by_level(
1307 if (cell->is_artificial_on_level())
1310 const unsigned int level = cell->level();
1313 if (cell->at_boundary(face_no) ==
true)
1316 cell->face(face_no);
1319 if (boundary_ids.find(bi) != boundary_ids.end())
1322 face->get_mg_dof_indices(
level, local_dofs);
1334 "It's probably worthwhile to select at least one component."));
1337 if (!cell->is_artificial_on_level())
1340 if (cell->at_boundary(face_no) ==
false)
1344 const unsigned int level = cell->level();
1347 cell->face(face_no);
1349 face->boundary_id();
1350 if (boundary_ids.find(boundary_component) != boundary_ids.end())
1353 for (
unsigned int i = 0;
1354 i < cell->get_fe().n_dofs_per_cell();
1358 cell->get_fe().get_nonzero_components(i);
1362 bool selected =
false;
1363 for (
unsigned int c = 0; c < n_components; ++c)
1364 if (nonzero_component_array[c] ==
true &&
1365 component_mask[c] ==
true)
1371 for (
unsigned int c = 0; c < n_components; ++c)
1373 nonzero_component_array[c] ==
false ||
1374 component_mask[c] ==
true,
1376 "You are using a non-primitive FiniteElement "
1377 "and try to constrain just some of its components!"));
1383 face->get_mg_dof_indices(
level, local_dofs);
1386 for (
unsigned int i = 0; i < local_dofs.size(); ++i)
1388 unsigned int component =
1400 cell->get_fe().get_nonzero_components(i);
1401 for (
unsigned int c = 0; c < n_components; ++c)
1402 if (nonzero_component_array[c] ==
true)
1410 if (component_mask[component] ==
true)
1411 dofs_by_level[
level].push_back(local_dofs[i]);
1425 boundary_indices[
level].add_indices(
1434 template <
int dim,
int spacedim>
1437 std::vector<IndexSet> & interface_dofs)
1439 Assert(interface_dofs.size() ==
1442 interface_dofs.size(),
1445 std::vector<std::vector<types::global_dof_index>> tmp_interface_dofs(
1446 interface_dofs.size());
1452 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1454 std::vector<bool> cell_dofs(dofs_per_cell,
false);
1460 if (cell->is_artificial_on_level())
1463 bool has_coarser_neighbor =
false;
1465 std::fill(cell_dofs.begin(), cell_dofs.end(),
false);
1470 cell->face(face_nr);
1471 if (!face->at_boundary() || cell->has_periodic_neighbor(face_nr))
1475 cell->neighbor_or_periodic_neighbor(face_nr);
1479 if (neighbor->is_artificial_on_level())
1483 if (neighbor->level() < cell->level())
1489 has_coarser_neighbor =
true;
1494 if (has_coarser_neighbor ==
false)
1497 const unsigned int level = cell->level();
1498 cell->get_mg_dof_indices(local_dof_indices);
1500 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1503 tmp_interface_dofs[
level].push_back(local_dof_indices[i]);
1507 for (
unsigned int l = 0;
1511 interface_dofs[
l].clear();
1512 std::sort(tmp_interface_dofs[
l].
begin(), tmp_interface_dofs[
l].
end());
1513 interface_dofs[
l].add_indices(tmp_interface_dofs[
l].
begin(),
1514 std::unique(tmp_interface_dofs[
l].
begin(),
1515 tmp_interface_dofs[
l].
end()));
1516 interface_dofs[
l].compress();
1522 template <
int dim,
int spacedim>
1533 if (cell->is_locally_owned())
1535 min_level = cell->level();
1539 unsigned int global_min = min_level;
1558 const std::vector<types::global_dof_index> &n_cells_on_levels,
1559 const MPI_Comm
comm)
1561 std::vector<types::global_dof_index> n_cells_on_leves_max(
1562 n_cells_on_levels.size());
1563 std::vector<types::global_dof_index> n_cells_on_leves_sum(
1564 n_cells_on_levels.size());
1571 const double ideal_work = std::accumulate(n_cells_on_leves_sum.begin(),
1572 n_cells_on_leves_sum.end(),
1574 static_cast<double>(n_proc);
1576 std::accumulate(n_cells_on_leves_max.begin(),
1577 n_cells_on_leves_max.end(),
1589 std::pair<types::global_dof_index, types::global_dof_index>> &cells,
1590 const MPI_Comm
comm)
1592 std::vector<types::global_dof_index> cells_local(cells.size());
1593 std::vector<types::global_dof_index> cells_remote(cells.size());
1595 for (
unsigned int i = 0; i < cells.size(); ++i)
1597 cells_local[i] = cells[i].first;
1598 cells_remote[i] = cells[i].second;
1601 std::vector<types::global_dof_index> cells_local_sum(cells_local.size());
1604 std::vector<types::global_dof_index> cells_remote_sum(
1605 cells_remote.size());
1608 const auto n_cells_local =
1609 std::accumulate(cells_local_sum.begin(), cells_local_sum.end(), 0);
1610 const auto n_cells_remote =
1611 std::accumulate(cells_remote_sum.begin(), cells_remote_sum.end(), 0);
1613 return static_cast<double>(n_cells_local) /
1614 (n_cells_local + n_cells_remote);
1620 template <
int dim,
int spacedim>
1621 std::vector<types::global_dof_index>
1628 tr->is_multilevel_hierarchy_constructed(),
1630 "We can only compute the workload imbalance if the multilevel hierarchy has been constructed!"));
1634 std::vector<types::global_dof_index> n_cells_on_levels(n_global_levels);
1636 for (
unsigned int lvl = 0; lvl < n_global_levels; ++lvl)
1638 if (cell->is_locally_owned_on_level())
1639 ++n_cells_on_levels[lvl];
1641 return n_cells_on_levels;
1646 template <
int dim,
int spacedim>
1647 std::vector<types::global_dof_index>
1652 const unsigned int n_global_levels = trias.size();
1654 std::vector<types::global_dof_index> n_cells_on_levels(n_global_levels);
1656 for (
unsigned int lvl = 0; lvl < n_global_levels; ++lvl)
1657 for (
const auto &cell : trias[lvl]->active_cell_iterators())
1658 if (cell->is_locally_owned())
1659 ++n_cells_on_levels[lvl];
1661 return n_cells_on_levels;
1666 template <
int dim,
int spacedim>
1676 template <
int dim,
int spacedim>
1683 trias.back()->get_communicator());
1688 template <
int dim,
int spacedim>
1689 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1694 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1695 cells(n_global_levels);
1701 for (
unsigned int lvl = 0; lvl < n_global_levels - 1; ++lvl)
1703 if (cell->is_locally_owned_on_level() && cell->has_children())
1704 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_cell;
1707 const auto level_subdomain_id =
1708 cell->child(i)->level_subdomain_id();
1709 if (level_subdomain_id == my_rank)
1710 ++cells[lvl + 1].first;
1712 ++cells[lvl + 1].second;
1722 template <
int dim,
int spacedim>
1723 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1728 const unsigned int n_global_levels = trias.size();
1730 std::vector<std::pair<types::global_dof_index, types::global_dof_index>>
1731 cells(n_global_levels);
1733 const MPI_Comm communicator = trias.back()->get_communicator();
1737 for (
unsigned int lvl = 0; lvl < n_global_levels - 1; ++lvl)
1739 const auto &tria_coarse = *trias[lvl];
1740 const auto &tria_fine = *trias[lvl + 1];
1742 const unsigned int n_coarse_cells = tria_fine.n_global_coarse_cells();
1743 const unsigned int n_global_levels = tria_fine.n_global_levels();
1745 const ::internal::CellIDTranslator<dim> cell_id_translator(
1746 n_coarse_cells, n_global_levels);
1748 IndexSet is_fine_owned(cell_id_translator.size());
1749 IndexSet is_fine_required(cell_id_translator.size());
1751 for (
const auto &cell : tria_fine.active_cell_iterators())
1752 if (!cell->is_artificial() && cell->is_locally_owned())
1753 is_fine_owned.
add_index(cell_id_translator.translate(cell));
1755 for (
const auto &cell : tria_coarse.active_cell_iterators())
1756 if (!cell->is_artificial() && cell->is_locally_owned())
1758 if (cell->level() + 1u == tria_fine.n_global_levels())
1761 for (
unsigned int i = 0;
1762 i < GeometryInfo<dim>::max_children_per_cell;
1765 cell_id_translator.translate(cell, i));
1768 std::vector<unsigned int> is_fine_required_ranks(
1772 process(is_fine_owned,
1775 is_fine_required_ranks,
1780 std::pair<types::global_cell_index, types::global_cell_index>>,
1781 std::vector<unsigned int>>
1782 consensus_algorithm;
1783 consensus_algorithm.
run(process, communicator);
1785 for (
unsigned i = 0; i < is_fine_required.
n_elements(); ++i)
1786 if (is_fine_required_ranks[i] == my_rank)
1787 ++cells[lvl + 1].first;
1789 ++cells[lvl + 1].second;
1797 template <
int dim,
int spacedim>
1807 template <
int dim,
int spacedim>
1815 trias.back()->get_communicator());
1822 #include "mg_tools.inst"
void add_entries_local_to_global(const std::vector< size_type > &local_dof_indices, SparsityPatternType &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 Triangulation< dim, spacedim > & get_triangulation() const
types::global_dof_index n_dofs() const
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
const hp::FECollection< dim, spacedim > & get_fe_collection() 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, unsigned int > system_to_component_index(const unsigned int index) const
std::pair< unsigned int, types::global_dof_index > system_to_block_index(const unsigned int component) const
bool is_primitive() const
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const
virtual unsigned int face_to_cell_index(const unsigned int face_dof_index, const unsigned int face, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false) const
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
unsigned int element_multiplicity(const unsigned int index) const
std::pair< unsigned int, unsigned int > face_system_to_component_index(const unsigned int index, const unsigned int face_no=0) const
unsigned int n_base_elements() 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 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< active_cell_iterator > active_cell_iterators() const
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
IteratorRange< cell_iterator > cell_iterators() const
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
#define Assert(cond, exc)
static ::ExceptionBase & ExcNotImplemented()
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
typename ActiveSelector::cell_iterator cell_iterator
Task< RT > new_task(const std::function< RT()> &function)
std::enable_if< IsBlockVector< VectorType >::value, unsigned int >::type n_blocks(const VectorType &vector)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
VectorType::value_type * begin(VectorType &V)
VectorType::value_type * end(VectorType &V)
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
T min(const T &t, const MPI_Comm &mpi_communicator)
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)
static const unsigned int invalid_unsigned_int
const types::global_dof_index invalid_dof_index
unsigned int global_dof_index
const ::Triangulation< dim, spacedim > & tria