81 mooseAssert(i <
_var_size,
"The variable of index " << i <<
" does not exist");
99 std::map<processor_id_type, std::vector<Point>> outgoing_points;
101 std::map<processor_id_type, std::map<std::pair<unsigned int, dof_id_type>, dof_id_type>>
104 for (
unsigned int i_to = 0; i_to <
_to_problems.size(); ++i_to)
107 unsigned int sys_num = to_sys->number();
108 unsigned int var_num = to_sys->variable_number(
_to_var_names[i]);
109 MeshBase * to_mesh = &
_to_meshes[i_to]->getMesh();
110 auto & fe_type = to_sys->variable_type(var_num);
111 bool is_constant = fe_type.order == CONSTANT;
112 bool is_nodal = fe_type.family == LAGRANGE;
116 if (fe_type.order > FIRST && !is_nodal)
117 mooseError(
"We don't currently support second order or higher elemental variable.");
121 for (
const auto & node : to_mesh->local_node_ptr_range())
124 if (node->n_dofs(sys_num, var_num) < 1)
130 unsigned int from0 = 0;
131 for (processor_id_type i_proc = 0; i_proc <
n_processors();
132 from0 += froms_per_proc[i_proc], ++i_proc)
134 bool point_found =
false;
135 for (
unsigned int i_from = from0; i_from < from0 + froms_per_proc[i_proc] && !point_found;
138 auto transformed_node = to_transform(*node);
139 if (bboxes[i_from].contains_point(transformed_node))
142 std::pair<unsigned int, dof_id_type> key(i_to, node->id());
145 point_index_map[i_proc][key] = outgoing_points[i_proc].size();
147 outgoing_points[i_proc].push_back(std::move(transformed_node));
156 std::vector<Point> points;
157 std::vector<dof_id_type> point_ids;
158 for (
auto & elem : as_range(to_mesh->local_elements_begin(), to_mesh->local_elements_end()))
161 if (elem->n_dofs(sys_num, var_num) < 1)
170 points.push_back(elem->vertex_average());
171 point_ids.push_back(elem->id());
177 for (
auto & node : elem->node_ref_range())
179 points.push_back(node);
180 point_ids.push_back(node.id());
183 unsigned int offset = 0;
184 for (
auto & point : points)
189 unsigned int from0 = 0;
190 for (processor_id_type i_proc = 0; i_proc <
n_processors();
191 from0 += froms_per_proc[i_proc], ++i_proc)
193 bool point_found =
false;
194 for (
unsigned int i_from = from0;
195 i_from < from0 + froms_per_proc[i_proc] && !point_found;
198 auto transformed_point = to_transform(point);
199 if (bboxes[i_from].contains_point(transformed_point))
201 std::pair<unsigned int, dof_id_type> key(i_to, point_ids[offset]);
202 if (point_index_map[i_proc].find(key) != point_index_map[i_proc].end())
205 point_index_map[i_proc][key] = outgoing_points[i_proc].size();
206 outgoing_points[i_proc].push_back(std::move(transformed_point));
221 std::vector<BoundingBox> local_bboxes(froms_per_proc[
processor_id()]);
224 unsigned int local_start = 0;
228 local_start += froms_per_proc[i_proc];
232 for (
unsigned int i_from = 0; i_from < froms_per_proc[
processor_id()]; ++i_from)
234 local_bboxes[i_from] = bboxes[local_start + i_from];
239 std::vector<libMesh::MeshFunction> local_meshfuns;
241 for (
unsigned int i_from = 0; i_from <
_from_problems.size(); ++i_from)
249 System & from_sys = from_var.
sys().
system();
253 *from_sys.current_local_solution,
254 from_sys.get_dof_map(),
256 local_meshfuns.back().init();
269 auto gather_functor =
270 [
this, &local_meshfuns, &local_bboxes](
272 const std::vector<Point> & incoming_points,
273 std::vector<std::pair<Real, unsigned int>> & vals_ids_for_incoming_points)
275 vals_ids_for_incoming_points.resize(incoming_points.size(), std::make_pair(
OutOfMeshValue, 0));
276 for (MooseIndex(incoming_points.size()) i_pt = 0; i_pt < incoming_points.size(); ++i_pt)
278 Point pt = incoming_points[i_pt];
287 if (local_bboxes[i_from].contains_point(pt))
290 vals_ids_for_incoming_points[i_pt].first = (local_meshfuns[i_from])(
310 std::map<processor_id_type, std::vector<std::pair<Real, unsigned int>>> incoming_vals_ids;
312 auto action_functor =
313 [&incoming_vals_ids](
314 processor_id_type pid,
315 const std::vector<Point> & ,
316 const std::vector<std::pair<Real, unsigned int>> & vals_ids_for_outgoing_points)
319 incoming_vals_ids[pid].reserve(vals_ids_for_outgoing_points.size());
321 std::copy(vals_ids_for_outgoing_points.begin(),
322 vals_ids_for_outgoing_points.end(),
323 std::back_inserter(incoming_vals_ids[pid]));
328 const std::pair<Real, unsigned int> * ex =
nullptr;
329 libMesh::Parallel::pull_parallel_vector_data(
330 comm(), outgoing_points, gather_functor, action_functor, ex);
332 for (
unsigned int i_to = 0; i_to <
_to_problems.size(); ++i_to)
337 unsigned int sys_num = to_sys->number();
338 unsigned int var_num = to_sys->variable_number(
_to_var_names[i]);
340 NumericVector<Real> * solution =
nullptr;
347 solution = to_sys->solution.get();
353 MeshBase * to_mesh = &
_to_meshes[i_to]->getMesh();
354 auto & fe_type = to_sys->variable_type(var_num);
355 bool is_constant = fe_type.order == CONSTANT;
356 bool is_nodal = fe_type.family == LAGRANGE;
360 for (
const auto & node : to_mesh->local_node_ptr_range())
363 if (node->n_dofs(sys_num, var_num) < 1)
368 bool point_found =
false;
369 for (
auto & group : incoming_vals_ids)
372 std::pair<unsigned int, dof_id_type> key(i_to, node->id());
374 mooseAssert(point_index_map.find(group.first) != point_index_map.end(),
375 "Point index map does not have data for processor group.first");
376 if (point_index_map[group.first].find(key) == point_index_map[group.first].end())
379 auto i_pt = point_index_map[group.first][key];
385 if (group.second[i_pt].second >= lowest_app_rank)
393 best_val = group.second[i_pt].first;
398 mooseError(
"Point not found in the reference space! ",
401 dof_id_type dof = node->dof_number(sys_num, var_num, 0);
402 solution->set(dof, best_val);
407 std::vector<Point> points;
408 std::vector<dof_id_type> point_ids;
409 for (
auto & elem : as_range(to_mesh->local_elements_begin(), to_mesh->local_elements_end()))
412 if (elem->n_dofs(sys_num, var_num) < 1)
421 points.push_back(elem->vertex_average());
422 point_ids.push_back(elem->id());
429 for (
auto & node : elem->node_ref_range())
431 points.push_back(node);
432 point_ids.push_back(node.id());
436 auto n_points = points.size();
437 unsigned int n_comp = elem->n_comp(sys_num, var_num);
439 if (n_points != n_comp)
442 " does not equal to number of variable components ",
444 for (
unsigned int offset = 0; offset < n_points; offset++)
448 bool point_found =
false;
449 for (
auto & group : incoming_vals_ids)
452 std::pair<unsigned int, dof_id_type> key(i_to, point_ids[offset]);
453 if (point_index_map[group.first].find(key) == point_index_map[group.first].end())
456 unsigned int i_pt = point_index_map[group.first][key];
462 if (group.second[i_pt].second >= lowest_app_rank)
470 best_val = group.second[i_pt].first;
475 mooseError(
"Point not found in the reference space! ",
479 dof_id_type dof = elem->dof_number(sys_num, var_num, offset);
480 solution->set(dof, best_val);