25#include "libmesh/point_locator_base.h"
26#include "libmesh/enum_point_locator_type.h"
47 "Factor to inflate or deflate the source app bounding boxes");
49 "fixed_bounding_box_size",
50 "fixed_bounding_box_size >= 0",
51 "Override source app bounding box size(s) for searches. App bounding boxes will still be "
52 "centered on the same coordinates. Only non-zero components passed will override.");
54 "extrapolation_constant",
56 "Constant to use when no source app can provide a valid value for a target location.");
57 MooseEnum extrap_options(
"none nearest-valid-target",
"none");
60 "Post treatment to apply to the field after the transfer");
63 params.
addParam<std::vector<SubdomainName>>(
65 "Subdomain restriction to transfer from (defaults to all the origin app domain)");
66 params.
addParam<std::vector<SubdomainName>>(
67 "to_blocks",
"Subdomain restriction to transfer to, (defaults to all the target app domain)");
70 params.
addParam<std::vector<BoundaryName>>(
72 "The boundary we are transferring from (if not specified, whole domain is used).");
73 params.
addParam<std::vector<BoundaryName>>(
75 "The boundary we are transferring to (if not specified, whole domain is used).");
76 MooseEnum nodes_or_sides(
"nodes sides",
"sides");
79 "Whether elemental variable boundary restriction is considered by "
80 "element side or element nodes");
83 params.
addParam<MeshDivisionName>(
"from_mesh_division",
84 "Mesh division object on the origin application");
85 params.
addParam<MeshDivisionName>(
"to_mesh_division",
86 "Mesh division object on the target application");
87 MooseEnum mesh_division_uses(
"spatial_restriction matching_division matching_subapp_index none",
91 "How to use the source mesh division in the transfer. See object "
92 "documentation for description of each option");
95 "How to use the target mesh division in the transfer. See object "
96 "documentation for description of each option");
99 params.
addParam<std::vector<unsigned int>>(
"source_variable_components",
100 std::vector<unsigned int>(),
101 "The source array or vector variable component(s).");
102 params.
addParam<std::vector<unsigned int>>(
"target_variable_components",
103 std::vector<unsigned int>(),
104 "The target array or vector variable component(s).");
110 "Whether or not to send a point to all the domains. If true, all the processors will be "
111 "checked for a given point."
112 "The code will be slow if this flag is on but it will give a better solution.");
116 "Whether or not to error in the case that a target point is not found in the source domain.");
117 params.
addParam<
bool>(
"use_bounding_boxes",
119 "When set to false, bounding boxes will not be used to restrict the source "
120 "of the transfer. Either source applications must be set using the "
121 "from_mesh_division parameter, or a greedy search must be used.");
125 "When True, transfers from a child application will work by finding the nearest (using "
126 "the `position` + mesh centroid) sub-app and query that app for the value to transfer.");
128 "use_nearest_position",
129 "Name of the the Positions object (in main app) such that transfers to/from a child "
130 "application will work by finding the nearest position to a target and query only the "
131 "app / points closer to this position than to any other position for the value to transfer.");
133 "from_app_must_contain_point",
135 "Wether on not the origin mesh must contain the point to evaluate data at. If false, this "
136 "allows for interpolation between origin app meshes. Origin app bounding boxes are still "
137 "considered so you may want to increase them with 'fixed_bounding_box_size'");
138 params.
addParam<
bool>(
"search_value_conflicts",
140 "Whether to look for potential conflicts between two valid and different "
141 "source values for any target point");
143 "value_conflicts_output",
145 "Maximum number of conflicts to output if value-conflicts, from equidistant sources to a "
146 "given transfer target location, search is turned on");
149 "to_blocks from_blocks to_boundaries from_boundaries elemental_boundary_restriction "
150 "from_mesh_division from_mesh_division_usage to_mesh_division to_mesh_division_usage",
151 "Transfer spatial restriction");
153 "greedy_search use_bounding_boxes use_nearest_app use_nearest_position "
154 "search_value_conflicts",
157 "Extrapolation behavior");
164 "ElementSideNeighborLayers",
169 obj_params.
get<
MooseEnum>(
"post_transfer_extrapolation") ==
"nearest-valid-target")
170 rm_params.
set<
unsigned short>(
"layers") = 2;
171 rm_params.
set<
bool>(
"use_displaced_mesh") = obj_params.
get<
bool>(
"displaced_target_mesh");
179 _from_var_components(getParam<
std::vector<unsigned
int>>(
"source_variable_components")),
180 _to_var_components(getParam<
std::vector<unsigned
int>>(
"target_variable_components")),
181 _use_bounding_boxes(getParam<bool>(
"use_bounding_boxes")),
182 _use_nearest_app(getParam<bool>(
"use_nearest_app")),
183 _nearest_positions_obj(
184 isParamValid(
"use_nearest_position")
185 ? &_fe_problem.getPositionsObject(getParam<PositionsName>(
"use_nearest_position"))
187 _source_app_must_contain_point(getParam<bool>(
"from_app_must_contain_point")),
188 _from_mesh_division_behavior(getParam<
MooseEnum>(
"from_mesh_division_usage")),
189 _to_mesh_division_behavior(getParam<
MooseEnum>(
"to_mesh_division_usage")),
190 _elemental_boundary_restriction_on_sides(
191 getParam<
MooseEnum>(
"elemental_boundary_restriction") ==
"sides"),
192 _greedy_search(getParam<bool>(
"greedy_search")),
193 _search_value_conflicts(getParam<bool>(
"search_value_conflicts")),
194 _already_output_search_value_conflicts(false),
195 _search_value_conflicts_max_log(getParam<unsigned
int>(
"value_conflicts_output")),
196 _post_transfer_extrapolation(getParam<
MooseEnum>(
"post_transfer_extrapolation")),
197 _error_on_miss(getParam<bool>(
"error_on_miss")),
198 _default_extrapolation_value(getParam<Real>(
"extrapolation_constant")),
199 _bbox_factor(getParam<Real>(
"bbox_factor")),
200 _fixed_bbox_size(isParamValid(
"fixed_bounding_box_size")
201 ? getParam<
std::vector<Real>>(
"fixed_bounding_box_size")
202 :
std::vector<Real>(3, 0))
206 paramError(
"variable",
"The number of variables to transfer to and from should be equal");
211 "This parameter must be equal to the number of source variables");
214 "This parameter must be equal to the number of target variables");
220 paramError(
"use_nearest_app",
"Cannot use nearest-app and nearest-position together");
223 "Should have a 'from_multiapp' when using the nearest-app informed search");
235 "Extrapolation (nearest-source options, outside-app source) parameters have "
236 "been passed, but no subapp bounding box expansion parameters have been passed.");
241 "Cannot pass additional bounding box parameters (sizes, expansion, etc) if we are "
242 "not using bounding boxes");
257 const auto & block_names = getParam<std::vector<SubdomainName>>(
"from_blocks");
259 for (
const auto & b : block_names)
261 paramError(
"from_blocks",
"The block '", b,
"' was not found in the mesh");
263 if (!block_names.empty())
265 const auto ids = from_moose_mesh.getSubdomainIDs(block_names);
272 const auto & boundary_names = getParam<std::vector<BoundaryName>>(
"from_boundaries");
273 for (
const auto & bn : boundary_names)
275 paramError(
"from_boundaries",
"The boundary '", bn,
"' was not found in the mesh");
277 if (!boundary_names.empty())
279 const auto boundary_ids = from_moose_mesh.getBoundaryIDs(boundary_names);
286 const auto & mesh_div_name = getParam<MeshDivisionName>(
"from_mesh_division");
292 mooseInfo(
"'from_mesh_division_usage' is set to use a spatial restriction but the "
293 "'from_mesh_division' for source app of global index " +
295 " covers the entire mesh. Do not expect any restriction from a mesh "
296 "division that covers the entire mesh");
301 "Source mesh division cannot match target mesh division if no target mesh "
302 "division is specified");
307 "Cannot match source mesh division index to target subapp index if there is "
308 "only one target: the parent app (not a subapp)");
311 mooseWarning(
"Attempting to match target subapp index with the number of source mesh "
312 "divisions, which is " +
314 " while there are " + std::to_string(
getToMultiApp()->numGlobalApps()) +
320 "We do not support using target subapp index for source division behavior and "
321 "matching the division index for the target mesh division behavior.");
324 paramError(
"from_mesh_division_usage",
"User must specify a 'from_mesh_division_usage'");
328 "'from_mesh_division' must be specified if the usage method is specified");
337 const auto & block_names = getParam<std::vector<SubdomainName>>(
"to_blocks");
338 for (
const auto & b : block_names)
340 paramError(
"to_blocks",
"The block '", b,
"' was not found in the mesh");
342 if (!block_names.empty())
344 const auto ids = to_moose_mesh.getSubdomainIDs(block_names);
351 const auto & boundary_names = getParam<std::vector<BoundaryName>>(
"to_boundaries");
352 for (
const auto & bn : boundary_names)
354 paramError(
"to_boundaries",
"The boundary '", bn,
"' was not found in the mesh");
356 if (!boundary_names.empty())
358 const auto boundary_ids = to_moose_mesh.getBoundaryIDs(boundary_names);
365 const auto & mesh_div_name = getParam<MeshDivisionName>(
"to_mesh_division");
371 mooseInfo(
"'to_mesh_division_usage' is set to use a spatial restriction but the "
372 "'to_mesh_division' for target application of global index " +
374 " covers the entire mesh. Do not expect any restriction from a mesh "
375 "division that covers the entire mesh");
381 "Target mesh division cannot match source mesh division if no source mesh "
382 "division is specified");
385 mooseWarning(
"Source and target mesh divisions do not have the same number of bins. If "
386 "this is what you expect, please reach out to a MOOSE or app developer to "
387 "ensure appropriate use");
393 "to_mesh_division_usage",
394 "Cannot match target mesh division index to source subapp index if there is only one "
395 "source: the parent app (not a subapp)");
397 mooseWarning(
"Attempting to match source subapp index with the number of target mesh "
398 "divisions, which is " +
400 " while there are " + std::to_string(
getFromMultiApp()->numGlobalApps()) +
404 "from_mesh_division_usage",
405 "We do not support using source subapp index for the target division behavior and "
406 "matching the division index for the source mesh division behavior.");
409 paramError(
"to_mesh_division_usage",
"User must specify a 'to_mesh_division_usage'");
413 "'to_mesh_division' must be specified if usage method '" +
428 paramError(
"source_variable_components",
"Component must be passed for an array variable");
431 "Component passed is larger than size of variable");
436 for (
const auto var_index : make_range(
_to_var_names.size()))
444 paramError(
"target_variable_components",
"Component must be passed for an array variable");
447 "Component passed is larger than size of variable");
472 PointLocatorBase::build(TREE_LOCAL_ELEMENTS, from_moose_mesh.getMesh());
481 "MultiAppGeneralFieldTransfer::execute()_" +
name(), 5,
"Transfer execution " +
name());
488 for (
const auto i : make_range(
_var_size))
531 mooseAssert(i <
_var_size,
"The variable of index " << i <<
" does not exist");
547 auto gather_functor =
548 [
this, &i](processor_id_type ,
549 const std::vector<std::pair<Point, unsigned int>> & incoming_locations,
550 std::vector<std::pair<Real, Real>> & outgoing_vals)
552 outgoing_vals.resize(
553 incoming_locations.size(),
564 auto action_functor = [
this, &i, &dofobject_to_valsvec, &interp_caches, &distance_caches](
565 processor_id_type pid,
566 const std::vector<std::pair<Point, unsigned int>> & my_outgoing_points,
567 const std::vector<std::pair<Real, Real>> & incoming_vals)
577 dofobject_to_valsvec,
584 const std::pair<Real, Real> * ex =
nullptr;
585 libMesh::Parallel::pull_parallel_vector_data(
586 comm(), outgoing_points, gather_functor, action_functor, ex);
601 std::set<processor_id_type> & processors)
624 for (processor_id_type i_proc = 0; i_proc <
n_processors(); ++i_proc)
628 for (
unsigned int i_from = from0; i_from < from0 +
_froms_per_proc[i_proc]; ++i_from)
632 processors.insert(i_proc);
635 mooseAssert(i_from <
getFromMultiApp()->numGlobalApps(),
"We should not reach this");
640 "Should only be one source processor when using more processors than source apps");
650 Real nearest_max_distance = std::numeric_limits<Real>::max();
654 if (
distance < nearest_max_distance)
658 unsigned int from0 = 0;
659 for (processor_id_type i_proc = 0; i_proc <
n_processors();
662 for (
unsigned int i_from = from0; i_from < from0 +
_froms_per_proc[i_proc]; ++i_from)
669 processors.insert(i_proc);
680 processors.insert(i_proc);
690 for (
const auto i_to : index_range(
_to_meshes))
695 if (target_div == saved_target_div)
698 saved_target_div = target_div;
705 processors.insert(i_proc);
711 mooseError(
"No algorithm were selected to find which processes may send value data "
712 "for a each target point. Please either specify using bounding boxes, "
713 "greedy search, or to_mesh_division-based parameters");
718 "Cannot find a source application to provide a value at point: ",
721 "It must be that mismatched meshes, between the source and target application, are being "
722 "used.\nIf you are using the bounding boxes or nearest-app heuristics, or mesh-divisions, "
723 "please consider using the greedy_search to confirm. Then consider choosing a different "
724 "transfer type.\nThis check can be turned off by setting 'error_on_miss' to false. The "
725 "'extrapolation_constant' parameter will be used to set the local value at missed points.");
730 const dof_id_type dof_object_id,
731 const unsigned int problem_id,
734 std::set<processor_id_type> processors;
742 for (
const auto pid : processors)
745 unsigned int required_source_division = 0;
759 outgoing_points[pid].push_back(std::pair<Point, unsigned int>(point, required_source_division));
789 System * to_sys =
find_sys(es, var_name);
790 auto sys_num = to_sys->number();
797 const auto & to_mesh = to_moose_mesh.getMesh();
800 if (fe_type.order > CONSTANT && !is_nodal)
805 const std::vector<unsigned int> varvec(1, var_num);
811 request_gather(*to_sys, f, &g, nullsetter, varvec);
815 mooseError(
"Higher order discontinuous elemental variables are not supported for "
817 "restricted transfers");
822 mooseError(
"Higher order variable support not implemented for target mesh division "
823 "unless the mesh is fully covered / indexed in the mesh division. This must be "
824 "set programmatically in the MeshDivision object used.");
829 ? to_mesh.active_local_elements_begin()
830 : to_mesh.active_local_subdomain_set_elements_begin(
_to_blocks);
833 ? to_mesh.active_local_elements_end()
834 : to_mesh.active_local_subdomain_set_elements_end(
_to_blocks);
836 ConstElemRange to_elem_range(to_begin, to_end);
838 request_gather.
project(to_elem_range);
840 dof_id_type point_id = 0;
845 (*
_to_transforms[global_i_to])(p), point_id++, i_to, outgoing_points);
849 mooseError(
"We don't currently support variables with gradient degrees of freedom");
853 for (
const auto & node : to_mesh.local_node_ptr_range())
856 if (node->n_dofs(sys_num, var_num) < 1)
877 (*
_to_transforms[global_i_to])(*node), node->id(), i_to, outgoing_points);
882 for (
const auto & elem :
883 as_range(to_mesh.local_elements_begin(), to_mesh.local_elements_end()))
886 if (elem->n_dofs(sys_num, var_num) < 1)
918 unsigned int local_start = 0;
924 local_bboxes[i_from] =
_from_bboxes[local_start + i_from];
929 processor_id_type pid,
930 const unsigned int var_index,
931 std::vector<PointInfo> & pointInfoVec,
932 const std::vector<std::pair<Point, unsigned int>> & point_requests,
933 const std::vector<std::pair<Real, Real>> & incoming_vals,
938 mooseAssert(pointInfoVec.size() == incoming_vals.size(),
939 "Number of dof objects does not equal to the number of incoming values");
941 dof_id_type val_offset = 0;
942 for (
const auto & pointinfo : pointInfoVec)
945 const auto problem_id = pointinfo.problem_id;
946 const auto dof_object_id = pointinfo.dof_object_id;
955 if (fe_type.order > CONSTANT && !is_nodal)
958 InterpCache & value_cache = interp_caches[problem_id];
959 InterpCache & distance_cache = distance_caches[problem_id];
961 point_requests[val_offset].first);
962 const Number val = incoming_vals[val_offset].first;
965 if (!distance_cache.
hasKey(p))
966 distance_cache[p] = std::numeric_limits<Real>::max();
972 value_cache.
hasKey(p) != 0 && !MooseUtils::absoluteFuzzyEqual(value_cache[p], val) &&
973 MooseUtils::absoluteFuzzyEqual(distance_cache[p], incoming_vals[val_offset].second))
974 registerConflict(problem_id, dof_object_id, p, incoming_vals[val_offset].second,
false);
979 MooseUtils::absoluteFuzzyGreaterThan(distance_cache[p], incoming_vals[val_offset].second))
984 value_cache[p] = val;
985 distance_cache[p] = incoming_vals[val_offset].second;
997 const DofObject * dof_object_ptr =
nullptr;
998 const auto sys_num = to_sys.number();
1001 dof_object_ptr = to_mesh.node_ptr(dof_object_id);
1004 dof_object_ptr = to_mesh.elem_ptr(dof_object_id);
1009 mooseAssert(dof_object_ptr->n_dofs(sys_num, var_num) == 1,
1010 "Unexpectedly found " << dof_object_ptr->n_dofs(sys_num, var_num)
1011 <<
"dofs instead of 1");
1014 auto & dofobject_to_val = dofobject_to_valsvec[problem_id];
1017 auto values_ptr = dofobject_to_val.find(dof_object_id);
1019 if (values_ptr == dofobject_to_val.end())
1022 auto & val = dofobject_to_val[dof_object_id];
1024 val.interp = incoming_vals[val_offset].first;
1028 val.distance = incoming_vals[val_offset].second;
1032 auto & val = values_ptr->second;
1036 incoming_vals[val_offset].first,
1038 incoming_vals[val_offset].second))
1044 "Registration of received equi-distant value conflict");
1045 registerConflict(problem_id, dof_object_id, p, incoming_vals[val_offset].second,
false);
1056 (MooseUtils::absoluteFuzzyGreaterThan(val.distance, incoming_vals[val_offset].second) ||
1058 MooseUtils::absoluteFuzzyEqual(val.distance, incoming_vals[val_offset].second))))
1060 val.interp = incoming_vals[val_offset].first;
1062 val.distance = incoming_vals[val_offset].second;
1074 unsigned int problem, dof_id_type dof_id, Point p, Real dist,
bool local)
1085 const unsigned int var_index,
1097 const auto potential_conflict = *conflict_it;
1098 bool overlap_found =
false;
1101 const unsigned int problem_id = std::get<0>(potential_conflict);
1102 const dof_id_type dof_object_id = std::get<1>(potential_conflict);
1103 const Point p = std::get<2>(potential_conflict);
1104 const Real
distance = std::get<3>(potential_conflict);
1108 System * to_sys =
find_sys(es, var_name);
1109 auto var_num = to_sys->variable_number(var_name);
1110 auto & fe_type = to_sys->variable_type(var_num);
1114 if (fe_type.order > CONSTANT && !is_nodal)
1116 auto cached_distance = distance_caches[problem_id].find(p);
1117 if (cached_distance == distance_caches[problem_id].end())
1118 mooseError(
"Conflict point was not found in the map of all origin-target distances");
1120 if (MooseUtils::absoluteFuzzyEqual(cached_distance->second,
distance))
1121 overlap_found =
true;
1124 else if (MooseUtils::absoluteFuzzyEqual(
1125 dofobject_to_valsvec[problem_id].find(dof_object_id)->second.distance,
distance))
1126 overlap_found =
true;
1138 const unsigned int var_index,
1153 std::vector<std::tuple<Point, Real>> potential_conflicts;
1161 const auto potential_conflict = *conflict_it;
1162 const unsigned int i_from = std::get<0>(potential_conflict);
1163 Point p = std::get<2>(potential_conflict);
1164 const Real
distance = std::get<3>(potential_conflict);
1174 potential_conflicts.push_back(std::make_tuple(p,
distance));
1178 std::sort(potential_conflicts.begin(), potential_conflicts.end());
1179 potential_conflicts.erase(unique(potential_conflicts.begin(),
1180 potential_conflicts.end(),
1183 return std::get<0>(l).absolute_fuzzy_equals(std::get<0>(r)) &&
1184 std::abs(std::get<1>(l) - std::get<1>(r)) < TOLERANCE;
1186 potential_conflicts.end());
1188 std::vector<std::tuple<Point, Real>> real_conflicts;
1189 real_conflicts.reserve(potential_conflicts.size());
1192 for (
auto conflict_it = potential_conflicts.begin(); conflict_it != potential_conflicts.end();
1196 auto potential_conflict = *conflict_it;
1197 const Point p = std::get<0>(potential_conflict);
1198 const Real
distance = std::get<1>(potential_conflict);
1202 bool target_found =
false;
1203 bool conflict_real =
false;
1208 System * to_sys =
find_sys(es, var_name);
1209 auto var_num = to_sys->variable_number(var_name);
1210 auto & fe_type = to_sys->variable_type(var_num);
1218 if (fe_type.order > CONSTANT && !is_nodal)
1221 auto cached_distance = distance_caches[i_to].find(local_p);
1222 if (cached_distance != distance_caches[i_to].end())
1224 target_found =
true;
1227 if (MooseUtils::absoluteFuzzyEqual(cached_distance->second,
distance))
1228 conflict_real =
true;
1235 dof_id_type dof_object_id = std::numeric_limits<dof_id_type>::max();
1236 auto pl =
_to_problems[i_to]->mesh().getPointLocator();
1237 pl->enable_out_of_mesh_mode();
1240 auto node = pl->locate_node(local_p);
1243 dof_object_id = node->id();
1247 auto elem = (*pl)(local_p);
1249 dof_object_id = elem->id();
1251 pl->disable_out_of_mesh_mode();
1254 if (dof_object_id == std::numeric_limits<dof_id_type>::max())
1258 if (dofobject_to_valsvec[i_to].find(dof_object_id) == dofobject_to_valsvec[i_to].end())
1261 target_found =
true;
1264 if (MooseUtils::absoluteFuzzyEqual(
1265 dofobject_to_valsvec[i_to].find(dof_object_id)->second.distance,
distance))
1266 conflict_real =
true;
1270 if (target_found && conflict_real)
1271 real_conflicts.push_back(potential_conflict);
1284 const auto potential_conflict = *conflict_it;
1285 const unsigned int i_from = std::get<0>(potential_conflict);
1286 Point p = std::get<2>(potential_conflict);
1287 const Real
distance = std::get<3>(potential_conflict);
1295 if (std::find_if(real_conflicts.begin(),
1296 real_conflicts.end(),
1299 return std::get<0>(item).absolute_fuzzy_equals(p) &&
1300 std::abs(std::get<1>(item) - distance) < TOLERANCE;
1301 }) == real_conflicts.end())
1310 const unsigned int var_index,
1323 unsigned int num_outputs = 0;
1324 std::string local_conflicts_string =
"";
1325 std::string potential_reasons =
1326 "Are some points in target mesh equidistant from the sources "
1327 "(nodes/centroids/apps/positions, depending on transfer) in origin mesh(es)?\n";
1329 potential_reasons +=
"Are multiple subapps overlapping?\n";
1332 const unsigned int problem_id = std::get<0>(conflict);
1333 Point p = std::get<2>(conflict);
1336 std::string origin_domain_message;
1345 origin_domain_message =
"In source child app " + std::to_string(app_id) +
" mesh,";
1355 origin_domain_message =
"In target app mesh,";
1358 origin_domain_message =
"In reference (post-coordinate collapse) mesh,";
1361 origin_domain_message =
"In source parent app mesh,";
1364 local_conflicts_string += origin_domain_message +
" point: (" + std::to_string(p(0)) +
1365 ", " + std::to_string(p(1)) +
", " + std::to_string(p(2)) +
1366 "), equi-distance: " + std::to_string(std::get<3>(conflict)) +
1369 local_conflicts_string +=
1370 "Maximum output of the search for value conflicts has been reached. Further conflicts "
1371 "will not be output.\nIncrease 'search_value_conflicts_max_log' to output more.";
1377 ", multiple valid values from equidistant points were "
1378 "found in the origin mesh for source " +
1380 " target points.\n" + potential_reasons +
"Conflicts detected at :\n" +
1381 local_conflicts_string);
1387 unsigned int num_outputs = 0;
1388 std::string received_conflicts_string =
"";
1389 std::string potential_reasons =
1390 "Are some points in target mesh equidistant from the sources "
1391 "(nodes/centroids/apps/positions, depending on transfer) in origin mesh(es)?\n";
1393 potential_reasons +=
"Are multiple subapps overlapping?\n";
1397 const unsigned int problem_id = std::get<0>(conflict);
1398 const Point p = std::get<2>(conflict);
1401 std::string target_domain_message;
1405 target_domain_message =
"In target child app " + std::to_string(app_id) +
" mesh,";
1408 target_domain_message =
"In target parent app mesh,";
1411 received_conflicts_string += target_domain_message +
" point: (" + std::to_string(p(0)) +
1412 ", " + std::to_string(p(1)) +
", " + std::to_string(p(2)) +
1413 "), equi-distance: " + std::to_string(std::get<3>(conflict)) +
1416 received_conflicts_string +=
1417 "Maximum output of the search for value conflicts has been reached. Further conflicts "
1418 "will not be output.\nIncrease 'search_value_conflicts_max_log' to output more.";
1421 ", multiple valid values from equidistant points were "
1422 "received for target variable '" +
1424 " target points.\n" + potential_reasons +
"Conflicts detected at :\n" +
1425 received_conflicts_string);
1431 mooseInfo(
"Automated diagnosis did not detect floating point indetermination in transfer");
1434 "Automated diagnosis did not detect any floating point indetermination in "
1435 "the transfer. You may consider turning it off using `search_value_conflicts=false` "
1436 "to improve performance/scalability.");
1447 const unsigned int var_index,
1454 for (
const auto problem_id : index_range(
_to_problems))
1456 auto & dofobject_to_val = dofobject_to_valsvec[problem_id];
1463 System * to_sys =
find_sys(es, var_name);
1467 auto var_num = to_sys->variable_number(var_name);
1468 auto sys_num = to_sys->number();
1473 if (fe_type.order > CONSTANT && !is_nodal)
1478 es, *to_sys->current_local_solution, to_sys->get_dof_map(), var_num);
1484 const std::vector<unsigned int> varvec(1, var_num);
1490 set_solution(*to_sys, f,
nullptr, setter, varvec);
1494 ? to_mesh.active_local_elements_begin()
1495 : to_mesh.active_local_subdomain_set_elements_begin(
_to_blocks);
1498 ? to_mesh.active_local_elements_end()
1499 : to_mesh.active_local_subdomain_set_elements_end(
_to_blocks);
1501 ConstElemRange active_local_elem_range(to_begin, to_end);
1503 set_solution.
project(active_local_elem_range);
1507 for (
const auto & val_pair : dofobject_to_val)
1509 const auto dof_object_id = val_pair.first;
1511 const DofObject * dof_object =
nullptr;
1513 dof_object = to_mesh.node_ptr(dof_object_id);
1515 dof_object = to_mesh.elem_ptr(dof_object_id);
1517 const auto dof = dof_object->dof_number(sys_num, var_num, 0);
1518 const auto val = val_pair.second.interp;
1523 const auto target_location =
1527 const auto info_msg =
"\nThis check can be turned off by setting 'error_on_miss' to "
1528 "false. The 'extrapolation_constant' parameter will be used to set "
1529 "the local value at missed points.";
1534 " could be located. Node details:\n",
1535 _to_meshes[problem_id]->nodePtr(dof_object_id)->get_info(),
1542 " could be located. Element details:\n",
1543 _to_meshes[problem_id]->elemPtr(dof_object_id)->get_info(),
1564 to_sys->solution->set(dof, missing_value);
1568 to_sys->solution->set(dof, val);
1572 to_sys->solution->close();
1580 const std::vector<BoundingBox> & local_bboxes,
1582 const unsigned int only_from_mesh_div,
1583 Real & distance)
const
1591 const auto transformed_pt =
1610 Point nearest_position_source;
1621 mooseError(
"Rotation and scaling currently unsupported with nearest positions transfer.");
1624 const Real distance_to_position_nearest_source = (pt - nearest_position_source).norm();
1625 const Real distance_to_nearest_position = (pt - nearest_position).norm();
1631 if (!MooseUtils::absoluteFuzzyEqual(distance_to_position_nearest_source,
1632 distance_to_nearest_position))
1636 distance = distance_to_position_nearest_source;
1642 !
inMesh(pl, transformed_pt))
1650 const unsigned int var_index,
1659 for (
const auto problem_id : index_range(
_to_problems))
1661 auto & dofobject_to_val = dofobject_to_valsvec[problem_id];
1668 System * to_sys =
find_sys(es, var_name);
1672 auto var_num = to_sys->variable_number(var_name);
1673 auto sys_num = to_sys->number();
1685 if (fe_type.order > CONSTANT && !is_nodal)
1687 "Nearest-valid-target is not implemented for higher order elemental variables");
1688 const auto & node_to_elem_map =
1691 for (
const auto & val_pair : dofobject_to_val)
1693 const auto dof_object_id = val_pair.first;
1696 const DofObject * dof_object =
nullptr;
1698 dof_object = to_mesh.node_ptr(dof_object_id);
1700 dof_object = to_mesh.elem_ptr(dof_object_id);
1701 const auto dof = dof_object->dof_number(sys_num, var_num, 0);
1702 const auto val = val_pair.second.interp;
1705 Real nearest_value = 0.;
1706 dof_id_type min_dist_id = std::numeric_limits<dof_id_type>::max();
1711 const auto node = to_mesh.node_ptr(dof_object_id);
1714 Real min_distance_sq = std::numeric_limits<Real>::max();
1715 for (
const auto & elem_id : libmesh_map_find(node_to_elem_map, node->id()))
1717 const auto elem = to_mesh.elem_ptr(elem_id);
1718 for (
const auto & elem_node : elem->node_ref_range())
1720 Real distance_sq = (Point(elem_node) - Point(*node)).norm_sq();
1727 if (distance_sq < min_distance_sq && elem_node.id() != node->id())
1729 if (
auto it = dofobject_to_val.find(elem_node.id());
1730 it != dofobject_to_val.end() &&
1733 min_distance_sq = distance_sq;
1734 min_dist_id = elem_node.id();
1735 nearest_value = it->second.interp;
1737 else if (elem_node.n_dofs(sys_num, var_num) > 0)
1739 const auto other_dof = elem_node.dof_number(sys_num, var_num, 0);
1746 if (
const auto sol_val = (*to_sys->current_local_solution)(other_dof);
1749 min_distance_sq = distance_sq;
1750 min_dist_id = elem_node.id();
1751 nearest_value = sol_val;
1765 const auto elem = to_mesh.elem_ptr(dof_object_id);
1766 Real min_distance_sq = std::numeric_limits<Real>::max();
1767 for (
const auto neigh : elem->neighbor_ptr_range())
1771 Real distance_sq = (neigh->vertex_average() - elem->vertex_average()).norm_sq();
1772 if (distance_sq < min_distance_sq)
1774 if (
auto it = dofobject_to_val.find(neigh->id());
1775 it != dofobject_to_val.end() &&
1778 min_distance_sq = distance_sq;
1779 min_dist_id = neigh->id();
1780 nearest_value = it->second.interp;
1783 else if (neigh->n_dofs(sys_num, var_num) > 0)
1785 const auto other_dof = neigh->dof_number(sys_num, var_num, 0);
1790 if (
const auto sol_val = (*to_sys->current_local_solution)(other_dof);
1793 nearest_value = sol_val;
1794 min_distance_sq = distance_sq;
1795 min_dist_id = neigh->id();
1806 nearest_value = (min_dist_id != std::numeric_limits<dof_id_type>::max())
1810 if (min_dist_id != std::numeric_limits<dof_id_type>::max())
1811 to_sys->solution->set(dof, nearest_value);
1817 flagSolutionWarning(
1818 "Search for the valid target nearest from a target point for which no "
1819 "values were found (and thus extrapolation is required) failed. This warning will "
1820 "not be repeated on the console for further failures.");
1824 to_sys->solution->close();
1836 const Elem * elem = (*pl)(point);
1837 return (elem !=
nullptr);
1842 const Elem * elem)
const
1844 return blocks.find(elem->subdomain_id()) !=
blocks.end();
1850 const Elem * elem)
const
1858 const Node * node)
const
1860 const auto & node_blocks =
mesh.getNodeBlockIds(*node);
1861 std::set<SubdomainID> u;
1862 std::set_intersection(
blocks.begin(),
1864 node_blocks.begin(),
1866 std::inserter(u, u.begin()));
1872 const PointLocatorBase *
const pl,
1873 const Point & point)
const
1875 const Elem * elem = (*pl)(point, &
blocks);
1876 return (elem !=
nullptr);
1882 const Node * node)
const
1884 const BoundaryInfo & bnd_info =
mesh.getMesh().get_boundary_info();
1885 std::vector<BoundaryID> vec_to_fill;
1886 bnd_info.boundary_ids(node, vec_to_fill);
1887 std::set<BoundaryID> vec_to_fill_set(vec_to_fill.begin(), vec_to_fill.end());
1888 std::set<BoundaryID> u;
1889 std::set_intersection(boundaries.begin(),
1891 vec_to_fill_set.begin(),
1892 vec_to_fill_set.end(),
1893 std::inserter(u, u.begin()));
1900 const Elem * elem)
const
1903 const BoundaryInfo & bnd_info =
mesh.getMesh().get_boundary_info();
1904 std::vector<BoundaryID> vec_to_fill;
1905 std::vector<BoundaryID> vec_to_fill_temp;
1907 for (
const auto side : make_range(elem->n_sides()))
1909 bnd_info.boundary_ids(elem, side, vec_to_fill_temp);
1910 vec_to_fill.insert(vec_to_fill.end(), vec_to_fill_temp.begin(), vec_to_fill_temp.end());
1913 for (
const auto node_index : make_range(elem->n_nodes()))
1915 bnd_info.boundary_ids(elem->node_ptr(node_index), vec_to_fill_temp);
1916 vec_to_fill.insert(vec_to_fill.end(), vec_to_fill_temp.begin(), vec_to_fill_temp.end());
1918 std::set<BoundaryID> vec_to_fill_set(vec_to_fill.begin(), vec_to_fill.end());
1921 std::set<BoundaryID> u;
1922 std::set_intersection(boundaries.begin(),
1924 vec_to_fill_set.begin(),
1925 vec_to_fill_set.end(),
1926 std::inserter(u, u.begin()));
1932 const std::set<SubdomainID> & block_restriction,
1934 const PointLocatorBase *
const pl,
1935 const Point & point)
const
1939 if (block_restriction.empty())
1940 elem = (*pl)(point);
1942 elem = (*pl)(point, &block_restriction);
1951 const Point & pt,
const unsigned int i_local,
const unsigned int only_from_this_mesh_div)
const
1965 source_mesh_div != only_from_this_mesh_div)
1970 source_mesh_div != only_from_this_mesh_div)
1984 paramError(
"skip_coordinate_collapsing",
"Coordinate collapsing not implemented");
1995 Real distance_to_position_at_index = (pt - nearest_position_at_index).norm();
1996 const Real distance_to_nearest_position = (pt - nearest_position).norm();
1998 if (!MooseUtils::absoluteFuzzyEqual(distance_to_position_at_index,
1999 distance_to_nearest_position))
2002 else if (nearest_position == nearest_position_at_index)
2009 nearest_position_at_index,
2010 " detected near point ",
2020 std::array<Point, 2> source_points = {{bbox.first, bbox.second}};
2022 std::array<Point, 8> all_points;
2023 for (
unsigned int x = 0; x < 2; x++)
2024 for (
unsigned int y = 0; y < 2; y++)
2025 for (
unsigned int z = 0; z < 2; z++)
2026 all_points[x + 2 * y + 4 * z] =
2027 Point(source_points[x](0), source_points[y](1), source_points[z](2));
2029 Real max_distance = 0.;
2031 for (
unsigned int i = 0; i < 8; i++)
2033 Real
distance = (p - all_points[i]).norm();
2038 return max_distance;
2044 std::array<Point, 2> source_points = {{bbox.first, bbox.second}};
2046 std::array<Point, 8> all_points;
2047 for (
unsigned int x = 0; x < 2; x++)
2048 for (
unsigned int y = 0; y < 2; y++)
2049 for (
unsigned int z = 0; z < 2; z++)
2050 all_points[x + 2 * y + 4 * z] =
2051 Point(source_points[x](0), source_points[y](1), source_points[z](2));
2053 Real min_distance = std::numeric_limits<Real>::max();
2055 for (
unsigned int i = 0; i < 8; i++)
2057 Real
distance = (p - all_points[i]).norm();
2062 return min_distance;
2065std::vector<BoundingBox>
2068 std::vector<std::pair<Point, Point>> bb_points(
_from_meshes.size());
2069 const Real min_r = std::numeric_limits<Real>::lowest();
2070 const Real max_r = std::numeric_limits<Real>::max();
2074 Point min(max_r, max_r, max_r);
2075 Point max(min_r, min_r, min_r);
2076 bool at_least_one =
false;
2079 for (
const auto & elem : as_range(from_mesh.getMesh().local_elements_begin(),
2080 from_mesh.getMesh().local_elements_end()))
2085 for (
const auto & node : elem->node_ref_range())
2090 at_least_one =
true;
2093 min(i) = std::min(min(i), node(i));
2094 max(i) = std::max(max(i), node(i));
2103 if ((from_mesh.getUniqueCoordSystem() ==
Moose::COORD_RZ) && (LIBMESH_DIM == 3))
2110 BoundingBox bbox(min, max);
2123 bb_points[j] =
static_cast<std::pair<Point, Point>
>(bbox);
2130 std::vector<BoundingBox> bboxes(bb_points.size());
2131 for (
const auto i : make_range(bb_points.size()))
2132 bboxes[i] =
static_cast<BoundingBox
>(bb_points[i]);
2139 for (
const auto j : make_range(bboxes.size()))
2141 const auto current_width = (bboxes[j].second - bboxes[j].first)(i);
2149std::vector<unsigned int>
2152 std::vector<unsigned int> global_app_start_per_proc(1, -1);
2156 return global_app_start_per_proc;
2162 mooseAssert(var_index <
_from_var_names.size(),
"No source variable at this index");
2169 mooseAssert(var_index <
_from_var_names.size(),
"No source variable at this index");
2179 mooseAssert(var_index <
_to_var_names.size(),
"No target variable at this index");
2189 Point max_dimension = {std::numeric_limits<Real>::min(),
2190 std::numeric_limits<Real>::min(),
2191 std::numeric_limits<Real>::min()};
2195 const auto bbox = to_mesh->getInflatedProcessorBoundingBox();
2197 max_dimension(
dim) = std::max(
2198 max_dimension(
dim), std::max(std::abs(bbox.first(
dim)), std::abs(bbox.second(
dim))));
2201 return max_dimension;
2207 Real current_distance,
2208 Real new_distance)
const
2215 !MooseUtils::absoluteFuzzyEqual(current_value, new_value))
2217 if (MooseUtils::absoluteFuzzyEqual(current_distance, new_distance))
void mooseInfo(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
const ExecFlagType EXEC_INITIAL
void ErrorVector unsigned int
const Positions & getPositionsObject(const std::string &name) const
Get the Positions object by its name.
const ExecFlagType & getCurrentExecuteOnFlag() const
Return/set the current execution flag.
virtual void addReporter(const std::string &type, const std::string &name, InputParameters ¶meters)
Add a Reporter object to the simulation.
InputParameters getValidParams(const std::string &name) const
Get valid parameters for the object.
Value request response base class.
Value request recording base class.
std::vector< Point > & points_requested()
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
const InputParameters & parameters() const
Get the parameters of the object.
const std::string & name() const
Get the name of the class.
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
MooseApp & _app
The MOOSE application this is associated with.
const libMesh::FEType & feType() const
Get the type of finite element object.
virtual bool isNodal() const
Is this variable nodal.
unsigned int count() const
Get the number of components Note: For standard and vector variables, the number is one.
This class provides an interface for common operations on field variables of both FE and FV types wit...
Transfers variables on possibly different meshes while conserving a user defined property (Postproces...
const std::vector< VariableName > _from_var_names
Name of variables transferring from.
const std::vector< AuxVariableName > _to_var_names
Name of variables transferring to.
static InputParameters validParams()
virtual void postExecute()
Add some extra work if necessary after execute().
virtual void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
libMesh::EquationSystems & getEquationSystem(FEProblemBase &problem, bool use_displaced) const
Returns the Problem's equation system, displaced or not Be careful! If you transfer TO a displaced sy...
Transfers a functor (can be variable, function, functor material property, spatial UO,...
std::vector< Real > _fixed_bbox_size
Set the bounding box sizes manually.
std::set< BoundaryID > _to_boundaries
Target boundary(ies) restriction.
const bool _use_nearest_app
Whether to keep track of the distance from the requested point to the app position.
void prepareToTransfer()
Initialize supporting attributes like bounding boxes, processor app indexes etc.
const MooseEnum _post_transfer_extrapolation
How to post treat after the transfer.
const Positions * _nearest_positions_obj
bool acceptPointMeshDivision(const Point &pt, const unsigned int i_local, const unsigned int only_from_this_mesh_div) const
Whether a point lies inside the mesh division delineated by the MeshDivision object.
bool detectConflict(Real value_1, Real value_2, Real distance_1, Real distance_2) const
Detects whether two source values are valid and equidistant for a desired target location.
void outputValueConflicts(const unsigned int var_index, const DofobjectToInterpValVec &dofobject_to_valsvec, const InterpCaches &distance_caches)
Report on conflicts between overlapping child apps, equidistant origin points etc.
void transferVariable(unsigned int i)
Performs the transfer for the variable of index i.
const Real _default_extrapolation_value
Value to use when no received data is valid for a target location.
virtual void getAppInfo() override
This method will fill information into the convenience member variables (_to_problems,...
std::vector< std::unordered_map< dof_id_type, InterpInfo > > DofobjectToInterpValVec
A vector, indexed by to-problem id, of maps from dof object to interpolation values.
const MooseEnum & _from_mesh_division_behavior
How to use the origin mesh divisions to restrict the transfer.
const MooseEnum & _to_mesh_division_behavior
How to use the target mesh divisions to restrict the transfer.
virtual std::string getDataSourceName(unsigned int var_index) const
Return a human-readable description of the data source (variable, functor, user object,...
void cacheOutgoingPointInfo(const Point point, const dof_id_type dof_object_id, const unsigned int problem_id, ProcessorToPointVec &outgoing_points)
bool _source_app_must_contain_point
Whether the source app mesh must actually contain the points for them to be considered or whether the...
std::vector< unsigned int > getGlobalStartAppPerProc() const
Get global index for the first app each processes owns Requires a global communication,...
static InputParameters validParams()
std::vector< std::unique_ptr< libMesh::PointLocatorBase > > _from_point_locators
Point locators, useful to examine point location with regards to domain restriction.
std::vector< MooseVariableFieldBase * > _to_variables
The target variables.
std::vector< unsigned int > _global_app_start_per_proc
First app each processor owns, indexed by processor If no app on the processor, will have a -1 for th...
MultiAppGeneralFieldTransfer(const InputParameters ¶meters)
const std::vector< unsigned int > _from_var_components
Origin array/vector variable components.
void setSolutionVectorValues(const unsigned int var_index, const DofobjectToInterpValVec &dofobject_to_valsvec, const InterpCaches &interp_caches)
bool _error_on_miss
Error out when some points can not be located.
bool inBlocks(const std::set< SubdomainID > &blocks, const Elem *elem) const
void cacheIncomingInterpVals(processor_id_type pid, const unsigned int var_index, std::vector< PointInfo > &pointInfoVec, const std::vector< std::pair< Point, unsigned int > > &point_requests, const std::vector< std::pair< Real, Real > > &incoming_vals, DofobjectToInterpValVec &dofobject_to_valsvec, InterpCaches &interp_caches, InterpCaches &distance_caches)
Real _bbox_factor
How much we should relax bounding boxes.
VariableName getToVarName(unsigned int var_index)
Get the target variable name, with the suffix for array/vector variables.
std::vector< BoundingBox > _from_bboxes
Bounding boxes for all source applications.
void registerConflict(unsigned int problem, dof_id_type dof_id, Point p, Real dist, bool local)
Register a potential value conflict, e.g.
virtual void execute() override
Execute the transfer.
bool onBoundaries(const std::set< BoundaryID > &boundaries, const MooseMesh &mesh, const Node *node) const
Real bboxMinDistance(const Point &p, const BoundingBox &bbox) const
Compute minimum distance.
virtual void evaluateInterpValues(const unsigned int var_index, const std::vector< std::pair< Point, unsigned int > > &incoming_points, std::vector< std::pair< Real, Real > > &outgoing_vals)=0
const bool _elemental_boundary_restriction_on_sides
Whether elemental variable boundary restriction is considered by element side or element nodes.
const std::vector< unsigned int > _to_var_components
Target array/vector variable components.
bool acceptPointInOriginMesh(unsigned int i_from, const std::vector< BoundingBox > &local_bboxes, const Point &pt, const unsigned int mesh_div, Real &distance) const
bool closestToPosition(unsigned int pos_index, const Point &pt) const
Whether a point is closest to a position at the index specified than any other position.
virtual void prepareEvaluationOfInterpValues(const unsigned int var_index)=0
std::set< SubdomainID > _from_blocks
Origin block(s) restriction.
virtual void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
void extractOutgoingPoints(const unsigned int var_index, ProcessorToPointVec &outgoing_points)
void examineLocalValueConflicts(const unsigned int var_index, const DofobjectToInterpValVec &dofobject_to_valsvec, const InterpCaches &distance_caches)
Remove potential value conflicts that did not materialize because another source was closer Several e...
void locatePointReceivers(const Point point, std::set< processor_id_type > &processors)
ProcessorToPointInfoVec _processor_to_pointInfoVec
A map from processor to pointInfo vector.
unsigned int _var_size
The number of variables to transfer.
std::vector< std::tuple< unsigned int, dof_id_type, Point, Real > > _local_conflicts
Keeps track of all local equidistant points to requested points, creating an indetermination in which...
const bool _use_bounding_boxes
Whether to use bounding boxes to determine the applications that may receive point requests then send...
Real bboxMaxDistance(const Point &p, const BoundingBox &bbox) const
Compute max distance.
MooseVariableFieldBase * getToVariable(unsigned int var_index) const
Return a pointer to a target variable.
std::vector< const MeshDivision * > _from_mesh_divisions
Division of the origin mesh.
std::set< SubdomainID > _to_blocks
Target block(s) restriction.
std::vector< const MeshDivision * > _to_mesh_divisions
Division of the target mesh.
void examineReceivedValueConflicts(const unsigned int var_index, const DofobjectToInterpValVec &dofobject_to_valsvec, const InterpCaches &distance_caches)
Remove potential value conflicts that did not materialize because another source was closer Several e...
void correctSolutionVectorValues(const unsigned int var_index, const DofobjectToInterpValVec &dofobject_to_valsvec, const InterpCaches &interp_caches)
bool inMesh(const libMesh::PointLocatorBase *const pl, const Point &pt) const
Point getMaxToProblemsBBoxDimensions() const
Obtains the max dimensions to scale all points in the mesh.
const unsigned int _search_value_conflicts_max_log
How many conflicts are output to console.
bool _already_output_search_value_conflicts
Whether we already output the search value conflicts.
bool _greedy_search
Whether or not a greedy strategy will be used If true, all the partitions will be checked for a given...
std::vector< InterpCache > InterpCaches
A vector of such caches, indexed by to_problem.
VariableName getFromVarName(unsigned int var_index) const
Get the source variable name, with the suffix for array/vector variables.
std::vector< std::tuple< unsigned int, dof_id_type, Point, Real > > _received_conflicts
Keeps track of all received conflicts.
std::unordered_map< processor_id_type, std::vector< std::pair< Point, unsigned int > > > ProcessorToPointVec
A map from pid to a set of points.
std::vector< BoundingBox > getRestrictedFromBoundingBoxes() const
Get from bounding boxes for given domains and boundaries.
std::vector< unsigned int > _froms_per_proc
Number of source/from applications per processor. This vector is indexed by processor id.
virtual void postExecute() override
Add some extra work if necessary after execute().
std::set< BoundaryID > _from_boundaries
Origin boundary(ies) restriction.
void extractLocalFromBoundingBoxes(std::vector< BoundingBox > &local_bboxes)
bool _search_value_conflicts
Whether to look for conflicts between origin points, multiple valid values for a target point.
std::vector< unsigned int > _to_local2global_map
Given local app index, returns global app index.
unsigned int getGlobalSourceAppIndex(unsigned int i_from) const
Return the global app index from the local index in the "from-multiapp" transfer direction.
bool hasToMultiApp() const
Whether the transfer owns a non-null to_multi_app.
bool _displaced_source_mesh
True if displaced mesh is used for the source mesh, otherwise false.
std::vector< unsigned int > _from_local2global_map
Given local app index, returns global app index.
std::vector< MooseMesh * > _from_meshes
static void transformBoundingBox(libMesh::BoundingBox &box, const MultiAppCoordTransform &transform)
Transform a bounding box according to the transformations in the provided coordinate transformation o...
std::vector< FEProblemBase * > _from_problems
std::vector< unsigned int > getFromsPerProc()
Return the number of "from" domains that each processor owns.
virtual void getAppInfo()
This method will fill information into the convenience member variables (_to_problems,...
Point getPointInTargetAppFrame(const Point &p, unsigned int local_i_to, const std::string &phase) const
Get the target app point from a point in the reference frame.
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
unsigned int getGlobalTargetAppIndex(unsigned int i_to) const
Return the global app index from the local index in the "to-multiapp" transfer direction.
bool _displaced_target_mesh
True if displaced mesh is used for the target mesh, otherwise false.
std::vector< FEProblemBase * > _to_problems
const std::shared_ptr< MultiApp > getToMultiApp() const
Get the MultiApp to transfer data to.
void extendBoundingBoxes(const Real factor, std::vector< libMesh::BoundingBox > &bboxes) const
Extends bounding boxes to avoid missing points.
std::vector< MooseMesh * > _to_meshes
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
Point getPointInSourceAppFrame(const Point &p, unsigned int local_i_from, const std::string &phase) const
Get the source app point from a point in the reference frame.
std::vector< std::unique_ptr< MultiAppCoordTransform > > _to_transforms
const bool _skip_coordinate_collapsing
Whether to skip coordinate collapsing (transformations of coordinates between applications using diff...
bool hasFromMultiApp() const
Whether the transfer owns a non-null from_multi_app.
const Point & getPosition(unsigned int index, bool initial) const
Getter for a single position at a known index.
unsigned int getNearestPositionIndex(const Point &target, bool initial) const
Find the nearest Position index for a given point.
const Point & getNearestPosition(const Point &target, bool initial) const
Find the nearest Position for a given point.
processor_id_type size() const
processor_id_type rank() const
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
FEProblemBase & _fe_problem
static libMesh::System * find_sys(libMesh::EquationSystems &es, const std::string &var_name)
Small helper function for finding the system containing the variable.
void project(const ConstElemRange &range)
virtual void init() override
const Parallel::Communicator & _communicator
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
bool isOutOfMeshValue(Number val)
unsigned int INVALID_DIVISION_INDEX
Invalid subdomain id to return when outside the mesh division.
bool hasSubdomainName(const MeshBase &input_mesh, const SubdomainName &name)
Whether a particular subdomain name exists in the mesh.
bool hasBoundaryNameOrID(const MeshBase &mesh, const BoundaryName &name_or_id)
Whether a particular boundary name or ID exists in the mesh.
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
std::string stringify(const T &t)
conversion to string
const RemoteElem * remote_elem
dof_id_type dof_object_id
An unordered map indexed by Point, eg 3 floating point numbers Because floating point rounding errors...
unsigned int hasKey(Point p)
Real distance(const Point &p)