83 mooseAssert(i <
_var_size,
"The variable of index " << i <<
" does not exist");
101 std::map<processor_id_type, std::vector<Point>> outgoing_points;
103 std::map<processor_id_type, std::map<std::pair<unsigned int, dof_id_type>,
dof_id_type>>
106 for (
unsigned int i_to = 0; i_to <
_to_problems.size(); ++i_to)
109 unsigned int sys_num = to_sys->
number();
114 bool is_nodal = fe_type.family ==
LAGRANGE;
118 if (fe_type.order >
FIRST && !is_nodal)
119 mooseError(
"We don't currently support second order or higher elemental variable.");
123 for (
const auto & node : to_mesh->local_node_ptr_range())
126 if (node->n_dofs(sys_num, var_num) < 1)
132 unsigned int from0 = 0;
134 from0 += froms_per_proc[i_proc], ++i_proc)
136 bool point_found =
false;
137 for (
unsigned int i_from = from0; i_from < from0 + froms_per_proc[i_proc] && !point_found;
140 auto transformed_node = to_transform(*node);
141 if (bboxes[i_from].contains_point(transformed_node))
144 std::pair<unsigned int, dof_id_type> key(i_to, node->id());
147 point_index_map[i_proc][key] = outgoing_points[i_proc].size();
149 outgoing_points[i_proc].push_back(std::move(transformed_node));
158 std::vector<Point> points;
159 std::vector<dof_id_type> point_ids;
160 for (
auto & elem :
as_range(to_mesh->local_elements_begin(), to_mesh->local_elements_end()))
163 if (elem->n_dofs(sys_num, var_num) < 1)
172 points.push_back(elem->vertex_average());
173 point_ids.push_back(elem->id());
179 for (
auto & node : elem->node_ref_range())
181 points.push_back(node);
182 point_ids.push_back(node.id());
185 unsigned int offset = 0;
186 for (
auto & point : points)
191 unsigned int from0 = 0;
193 from0 += froms_per_proc[i_proc], ++i_proc)
195 bool point_found =
false;
196 for (
unsigned int i_from = from0;
197 i_from < from0 + froms_per_proc[i_proc] && !point_found;
200 auto transformed_point = to_transform(point);
201 if (bboxes[i_from].contains_point(transformed_point))
203 std::pair<unsigned int, dof_id_type> key(i_to, point_ids[offset]);
204 if (point_index_map[i_proc].find(key) != point_index_map[i_proc].end())
207 point_index_map[i_proc][key] = outgoing_points[i_proc].size();
208 outgoing_points[i_proc].push_back(std::move(transformed_point));
223 std::vector<BoundingBox> local_bboxes(froms_per_proc[
processor_id()]);
226 unsigned int local_start = 0;
230 local_start += froms_per_proc[i_proc];
234 for (
unsigned int i_from = 0; i_from < froms_per_proc[
processor_id()]; ++i_from)
236 local_bboxes[i_from] = bboxes[local_start + i_from];
241 std::vector<MeshFunction> local_meshfuns;
243 for (
unsigned int i_from = 0; i_from <
_from_problems.size(); ++i_from)
258 local_meshfuns.back().init();
271 auto gather_functor =
272 [
this, &local_meshfuns, &local_bboxes](
274 const std::vector<Point> & incoming_points,
275 std::vector<std::pair<Real, unsigned int>> & vals_ids_for_incoming_points)
277 vals_ids_for_incoming_points.resize(incoming_points.size(), std::make_pair(
OutOfMeshValue, 0));
278 for (MooseIndex(incoming_points.size()) i_pt = 0; i_pt < incoming_points.size(); ++i_pt)
280 Point pt = incoming_points[i_pt];
289 if (local_bboxes[i_from].contains_point(pt))
292 vals_ids_for_incoming_points[i_pt].first = (local_meshfuns[i_from])(
312 std::map<processor_id_type, std::vector<std::pair<Real, unsigned int>>> incoming_vals_ids;
314 auto action_functor =
315 [&incoming_vals_ids](
317 const std::vector<Point> & ,
318 const std::vector<std::pair<Real, unsigned int>> & vals_ids_for_outgoing_points)
321 incoming_vals_ids[pid].reserve(vals_ids_for_outgoing_points.size());
323 std::copy(vals_ids_for_outgoing_points.begin(),
324 vals_ids_for_outgoing_points.end(),
325 std::back_inserter(incoming_vals_ids[pid]));
330 const std::pair<Real, unsigned int> * ex =
nullptr;
331 libMesh::Parallel::pull_parallel_vector_data(
332 comm(), outgoing_points, gather_functor, action_functor, ex);
334 for (
unsigned int i_to = 0; i_to <
_to_problems.size(); ++i_to)
339 unsigned int sys_num = to_sys->
number();
358 bool is_nodal = fe_type.family ==
LAGRANGE;
362 for (
const auto & node : to_mesh->local_node_ptr_range())
365 if (node->n_dofs(sys_num, var_num) < 1)
370 bool point_found =
false;
371 for (
auto & group : incoming_vals_ids)
374 std::pair<unsigned int, dof_id_type> key(i_to, node->id());
376 mooseAssert(point_index_map.find(group.first) != point_index_map.end(),
377 "Point index map does not have data for processor group.first");
378 if (point_index_map[group.first].find(key) == point_index_map[group.first].end())
381 auto i_pt = point_index_map[group.first][key];
387 if (group.second[i_pt].second >= lowest_app_rank)
395 best_val = group.second[i_pt].first;
400 mooseError(
"Point not found in the reference space! ",
403 dof_id_type dof = node->dof_number(sys_num, var_num, 0);
404 solution->
set(dof, best_val);
409 std::vector<Point> points;
410 std::vector<dof_id_type> point_ids;
411 for (
auto & elem :
as_range(to_mesh->local_elements_begin(), to_mesh->local_elements_end()))
414 if (elem->n_dofs(sys_num, var_num) < 1)
423 points.push_back(elem->vertex_average());
424 point_ids.push_back(elem->id());
431 for (
auto & node : elem->node_ref_range())
433 points.push_back(node);
434 point_ids.push_back(node.id());
438 auto n_points = points.size();
439 unsigned int n_comp = elem->n_comp(sys_num, var_num);
441 if (n_points != n_comp)
444 " does not equal to number of variable components ",
446 for (
unsigned int offset = 0; offset < n_points; offset++)
450 bool point_found =
false;
451 for (
auto & group : incoming_vals_ids)
454 std::pair<unsigned int, dof_id_type> key(i_to, point_ids[offset]);
455 if (point_index_map[group.first].find(key) == point_index_map[group.first].end())
458 unsigned int i_pt = point_index_map[group.first][key];
464 if (group.second[i_pt].second >= lowest_app_rank)
472 best_val = group.second[i_pt].first;
477 mooseError(
"Point not found in the reference space! ",
481 dof_id_type dof = elem->dof_number(sys_num, var_num, offset);
482 solution->
set(dof, best_val);