57 mooseAssert(
_base_mesh,
"Should have a base mesh to copy the partitioning from");
71 std::set<unsigned int> pids_used;
75 mooseError(
"This partitioner does not support using fewer ranks to partition the mesh than are "
76 "used to partition the source mesh (the mesh we are copying the partitioning from)");
78 "Should be the same rank on both mesh MPI communicators");
83 pl->enable_out_of_mesh_mode();
103 std::map<processor_id_type, std::vector<std::tuple<Point, processor_id_type, unsigned int>>>
106 unsigned int request_i = 0;
107 for (
auto & elem :
mesh.active_element_ptr_range())
112 const auto elem_pt = elem->vertex_average();
113 if (distributed_mesh)
114 for (
const auto pid : make_range(
mesh.comm().size()))
115 requested_elements[pid].push_back({elem_pt, elem->processor_id(), request_i});
124 auto gather_functor =
127 const std::vector<std::tuple<Point, processor_id_type, unsigned int>> & incoming_elements,
128 std::vector<processor_id_type> & outgoing_pids)
133 for (
const auto i : index_range(incoming_elements))
135 const auto & elem = (*pl)(Point(std::get<0>(incoming_elements[i])));
137 outgoing_pids[i] = elem->processor_id();
144 std::map<processor_id_type, std::vector<processor_id_type>> filled_request;
145 for (
const auto i : make_range(
mesh.comm().size()))
146 filled_request[i].resize(requested_elements.count(i) ? requested_elements[i].size() : 0);
149 auto action_functor =
152 const std::vector<std::tuple<Point, processor_id_type, unsigned int>> & elems,
153 const std::vector<processor_id_type> & new_procids)
155 for (
const auto i : index_range(new_procids))
158 const auto elem_pid = std::get<1>(elems[i]);
159 const auto request_i = std::get<2>(elems[i]);
160 filled_request[elem_pid][request_i] = new_procids[i];
167 const processor_id_type * ex =
nullptr;
168 Parallel::pull_parallel_vector_data(
169 mesh.comm(), requested_elements, gather_functor, action_functor, ex);
173 for (
auto & elem :
mesh.active_element_ptr_range())
175 const processor_id_type current_pid = elem->processor_id();
176 const auto lookup_pid = distributed_mesh ? current_pid :
processor_id();
177 const processor_id_type elem_procid = filled_request[lookup_pid][request_i++];
179 elem->processor_id() = elem_procid;
181 pids_used.insert(elem_procid);
186 std::vector<unsigned int> pids_used_vec(pids_used.begin(), pids_used.end());
187 mesh.comm().allgather(pids_used_vec);
188 pids_used.insert(pids_used_vec.begin(), pids_used_vec.end());
192 const auto max_pid =
mesh.comm().size();
193 if (pids_used.size() > max_pid)
194 mooseError(
"Partitioning copy used more regions (" + std::to_string(pids_used.size()) +
195 ") than the number of parallel processes (" + std::to_string(
mesh.comm().size()) +
197 if (pids_used.size() < max_pid)
199 "Some parallel (MPI) processes were not assigned any element during partitioning. These "
200 "processes will not perform any work.");
204 if (*pids_used.rbegin() > max_pid)
206 std::unordered_map<unsigned int, unsigned int> source_to_current_pid_map;
212 for (
const auto pid_set : pids_used)
213 source_to_current_pid_map[pid_set] = i++;
215 for (
auto & elem_ptr :
mesh.active_element_ptr_range())
216 elem_ptr->processor_id() = source_to_current_pid_map[elem_ptr->processor_id()];