64 std::vector<std::vector<
65 std::pair<types::global_dof_index, types::global_dof_index>>>
67 std::vector<std::vector<
68 std::pair<types::global_dof_index, types::global_dof_index>>>
69 ©_indices_global_mine,
70 std::vector<std::vector<
71 std::pair<types::global_dof_index, types::global_dof_index>>>
72 & copy_indices_level_mine,
88 const unsigned int n_levels =
89 dof_handler.get_triangulation().n_global_levels();
90 copy_indices.resize(n_levels);
91 copy_indices_global_mine.resize(n_levels);
92 copy_indices_level_mine.resize(n_levels);
95 const unsigned int dofs_per_cell = dof_handler.get_fe().n_dofs_per_cell();
97 std::vector<types::global_dof_index> level_dof_indices(dofs_per_cell);
103 dof_handler.locally_owned_mg_dofs(
level);
111 copy_indices_level_mine[
level].clear();
112 copy_indices_global_mine[
level].clear();
114 for (
const auto &level_cell :
115 dof_handler.active_cell_iterators_on_level(
level))
117 if (dof_handler.get_triangulation().locally_owned_subdomain() !=
119 (level_cell->level_subdomain_id() ==
121 level_cell->subdomain_id() ==
131 level_cell->get_mg_dof_indices(level_dof_indices);
133 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
139 level, level_dof_indices[i]))
159 level_dof_indices[i];
164 copy_indices_global_mine[
level].emplace_back(
170 level_dof_indices[i]);
184 copy_indices[
level].clear();
188 if (copy_indices_global_mine[
level].empty())
196 copy_indices[
level].emplace_back(
201 const ::parallel::TriangulationBase<dim, spacedim> *
tria =
202 (
dynamic_cast<const ::parallel::TriangulationBase<dim, spacedim>
203 *
>(&dof_handler.get_triangulation()));
207 "We should only be sending information with a parallel Triangulation!"));
209#ifdef DEAL_II_WITH_MPI
211 tria->get_communicator()) > 0)
213 const std::set<types::subdomain_id> &neighbors =
214 tria->level_ghost_owners();
215 std::map<int, std::vector<DoFPair>> send_data;
220 if (lhs.level < rhs.level)
222 if (lhs.level > rhs.level)
225 if (lhs.level_dof_index < rhs.level_dof_index)
227 if (lhs.level_dof_index > rhs.level_dof_index)
230 if (lhs.global_dof_index < rhs.global_dof_index)
239 return (lhs.level == rhs.level) &&
240 (lhs.level_dof_index == rhs.level_dof_index) &&
241 (lhs.global_dof_index == rhs.global_dof_index);
248 dof_handler.locally_owned_mg_dofs(
level);
250 std::vector<types::global_dof_index> level_dof_indices;
255 level_dof_indices.push_back(
dofpair.level_dof_index);
261 level_dof_indices.end());
269 tria->get_communicator());
277 level_dof_indices[i]);
284 mutex,
tria->get_communicator());
290 std::vector<MPI_Request> requests;
292 for (
const auto dest : neighbors)
294 requests.push_back(MPI_Request());
295 std::vector<DoFPair> &data = send_data[
dest];
299 data.size() *
sizeof(
decltype(*data.data())),
303 tria->get_communicator(),
304 &*requests.rbegin());
313 for (
unsigned int counter = 0; counter < neighbors.size();
319 tria->get_communicator(),
333 tria->get_communicator(),
350 tria->get_communicator(),
356 copy_indices_level_mine[
dof_pair.level].emplace_back(
363 if (requests.size() > 0)
385 std::less<std::pair<types::global_dof_index, types::global_dof_index>>
560 elem_info.n_components = dof_handler.get_fe().element_multiplicity(0);
563 dof_handler.get_fe().n_dofs_per_cell());
566 elem_info.element_is_continuous = fe.n_dofs_per_vertex() > 0;
572 std::vector<unsigned int>
renumbering(fe.n_dofs_per_cell());
576 for (
unsigned int i = 0; i < fe.n_dofs_per_line(); ++i)
579 if (fe.n_dofs_per_vertex() > 0)
580 renumbering[fe.n_dofs_per_cell() - fe.n_dofs_per_vertex()] =
581 fe.n_dofs_per_vertex();
586 Assert(fe.n_dofs_per_vertex() == 0 || fe.n_dofs_per_vertex() == 1,
588 const unsigned int shift = fe.n_dofs_per_cell() - fe.n_dofs_per_vertex();
590 (fe.n_dofs_per_vertex() > 0 ? (2 * fe.n_dofs_per_cell() - 1) :
591 (2 * fe.n_dofs_per_cell()));
602 elem_info.prolongation_matrix_1d.resize(fe.n_dofs_per_cell() *
606 for (
unsigned int i = 0; i < fe.n_dofs_per_cell(); ++i)
607 for (
unsigned int j = 0;
j < fe.n_dofs_per_cell(); ++
j)
622 const std::vector<std::shared_ptr<const Utilities::MPI::Partitioner>>
623 & external_partitioners,
625 std::vector<std::vector<unsigned int>> &level_dof_indices,
626 std::vector<std::vector<std::pair<unsigned int, unsigned int>>>
627 & parent_child_connect,
628 std::vector<unsigned int> &n_owned_level_cells,
629 std::vector<std::vector<std::vector<unsigned short>>> &dirichlet_indices,
630 std::vector<std::vector<Number>> & weights_on_refined,
632 MGLevelObject<std::shared_ptr<const Utilities::MPI::Partitioner>>
635 level_dof_indices.clear();
636 parent_child_connect.clear();
637 n_owned_level_cells.clear();
638 dirichlet_indices.clear();
639 weights_on_refined.clear();
651 std::string
fe_name = dof_handler.get_fe().base_element(0).get_name();
655 (dim == 1 ?
'1' : (dim == 2 ?
'2' :
'3')),
659 const std::unique_ptr<FiniteElement<1>> fe(
660 FETools::get_fe_by_name<1, 1>(
fe_name));
666 const unsigned int n_levels =
tria.n_global_levels();
667 level_dof_indices.resize(n_levels);
668 parent_child_connect.resize(n_levels - 1);
669 n_owned_level_cells.resize(n_levels - 1);
671 for (
unsigned int level = 0;
676 std::vector<types::global_dof_index> local_dof_indices(
677 dof_handler.get_fe().n_dofs_per_cell());
678 dirichlet_indices.resize(n_levels - 1);
681 Assert(external_partitioners.empty() ||
682 external_partitioners.size() == n_levels,
687 unsigned int counter = 0;
701 if (!cell->has_children())
705 (
tria.locally_owned_subdomain() ==
707 cell->level_subdomain_id() ==
tria.locally_owned_subdomain());
713 for (
unsigned int c = 0;
716 if (cell->child(c)->level_subdomain_id() ==
717 tria.locally_owned_subdomain())
740 for (
unsigned int c = 0;
745 tria.locally_owned_subdomain())
747 cell->child(c)->get_mg_dof_indices(local_dof_indices);
754 dof_handler.locally_owned_mg_dofs(
level);
760 fe->n_dofs_per_cell() -
761 fe->n_dofs_per_vertex(),
768 if (cell->child(c)->has_children() &&
769 (
tria.locally_owned_subdomain() ==
771 cell->child(c)->level_subdomain_id() ==
772 tria.locally_owned_subdomain()))
774 const unsigned int child_index =
777 parent_child_connect[
level].size());
778 unsigned int parent_index = counter;
789 parent_child_connect[
level][child_index] =
790 std::make_pair(parent_index, c);
792 static_cast<unsigned short>(-1));
796 if (mg_constrained_dofs !=
nullptr)
797 for (
unsigned int i = 0;
798 i < dof_handler.get_fe().n_dofs_per_cell();
804 dirichlet_indices[
level][child_index].push_back(i);
820 cell->get_mg_dof_indices(local_dof_indices);
827 dof_handler.locally_owned_mg_dofs(0);
839 fe->n_dofs_per_cell() - fe->n_dofs_per_vertex(),
845 dirichlet_indices[0].emplace_back();
846 if (mg_constrained_dofs !=
nullptr)
847 for (
unsigned int i = 0;
848 i < dof_handler.get_fe().n_dofs_per_cell();
853 .lexicographic_numbering[i]]))
854 dirichlet_indices[0].back().push_back(i);
863 n_owned_level_cells[
level - 1] = counter;
864 dirichlet_indices[
level - 1].resize(counter);
865 parent_child_connect[
level - 1].resize(
873 if (
level < n_levels - 1)
874 for (std::vector<std::pair<unsigned int, unsigned int>>::iterator
875 i = parent_child_connect[
level].begin();
876 i != parent_child_connect[
level].end();
892 external_partitioners.
empty() ?
894 external_partitioners[
level],
895 tria.get_communicator(),
897 copy_indices_global_mine[
level]);
902 level_dof_indices[
level]);
906 for (
unsigned int i = 0; i < parent_child_connect[0].size(); ++i)
907 parent_child_connect[0][i] = std::make_pair(i, 0U);
911 external_partitioners.
empty() ?
913 external_partitioners[0],
914 tria.get_communicator(),
916 copy_indices_global_mine[0]);
921 std::vector<types::global_dof_index>(),
922 level_dof_indices[0]);
929 fe->degree + 1 + fe->n_dofs_per_cell() - fe->n_dofs_per_vertex();
933 weights_on_refined.resize(n_levels - 1);
938 for (
unsigned int c = 0; c < n_owned_level_cells[
level - 1]; ++c)
939 for (
unsigned int j = 0;
j <
elem_info.n_child_cell_dofs; ++
j)
954 weights_on_refined[
level - 1].resize(n_owned_level_cells[
level - 1] *
955 Utilities::fixed_power<dim>(3));
956 for (
unsigned int c = 0; c < n_owned_level_cells[
level - 1]; ++c)
963 weights_on_refined[
level -
964 1][c * Utilities::fixed_power<dim>(3) +
968 level_dof_indices[
level]
void setup_transfer(const DoFHandler< dim > &dof_handler, const MGConstrainedDoFs *mg_constrained_dofs, const std::vector< std::shared_ptr< const Utilities::MPI::Partitioner > > &external_partitioners, ElementInfo< Number > &elem_info, std::vector< std::vector< unsigned int > > &level_dof_indices, std::vector< std::vector< std::pair< unsigned int, unsigned int > > > &parent_child_connect, std::vector< unsigned int > &n_owned_level_cells, std::vector< std::vector< std::vector< unsigned short > > > &dirichlet_indices, std::vector< std::vector< Number > > &weights_on_refined, std::vector< Table< 2, unsigned int > > ©_indices_global_mine, MGLevelObject< std::shared_ptr< const Utilities::MPI::Partitioner > > &vector_partitioners)