24 #include "libmesh/meshfree_interpolation.h"
25 #include "libmesh/system.h"
26 #include "libmesh/mesh_function.h"
27 #include "libmesh/mesh_tools.h"
42 "The UserObject you want to transfer values from. Note: This might be a "
43 "UserObject from your MultiApp's input file!");
44 params.
addParam<
bool>(
"all_master_nodes_contained_in_sub_app",
46 "Set to true if every master node is mapped to a distinct point on one of "
47 "the subApps during a transfer from sub App to Master App. If master node "
48 "cannot be found within bounding boxes of any of the subApps, an error is "
51 "skip_bounding_box_check",
53 "Skip the check if the to_elem is within the bounding box of the from_app.");
56 "Samples a variable's value in the Master domain at the point where the MultiApp is and "
57 "copies that value into a post-processor in the MultiApp");
64 _user_object_name(getParam<UserObjectName>(
"user_object")),
65 _all_master_nodes_contained_in_sub_app(getParam<bool>(
"all_master_nodes_contained_in_sub_app")),
66 _skip_bbox_check(getParam<bool>(
"skip_bounding_box_check"))
72 paramError(
"variable",
" Support single to-variable only ");
76 " You should not provide any source variables since the transfer takes values from "
83 _console <<
"Beginning MultiAppUserObjectTransfer " <<
name() << std::endl;
89 for (
unsigned int i = 0; i <
_multi_app->numGlobalApps(); i++)
98 unsigned int sys_num = to_sys->number();
99 unsigned int var_num = to_sys->variable_number(
_to_var_name);
103 MeshBase * mesh = NULL;
107 mesh = &
_multi_app->appProblemBase(i).getDisplacedProblem()->mesh().getMesh();
110 mesh = &
_multi_app->appProblemBase(i).mesh().getMesh();
112 auto & fe_type = to_sys->variable_type(var_num);
113 bool is_constant = fe_type.order == CONSTANT;
114 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 ");
124 for (
auto & node : mesh->local_node_ptr_range())
126 if (node->n_dofs(sys_num, var_num) > 0)
129 dof_id_type dof = node->dof_number(sys_num, var_num, 0);
135 solution.set(dof, from_value);
141 std::vector<Point> points;
142 for (
auto & elem : as_range(mesh->local_elements_begin(), mesh->local_elements_end()))
145 if (elem->n_dofs(sys_num, var_num) < 1)
152 points.push_back(elem->centroid());
156 for (
auto & node : elem->node_ref_range())
157 points.push_back(node);
159 auto n_points = points.size();
160 unsigned int n_comp = elem->n_comp(sys_num, var_num);
162 if (n_points != n_comp)
165 " does not equal to number of variable components ",
168 unsigned int offset = 0;
169 for (
auto & point : points)
172 dof_id_type dof = elem->dof_number(sys_num, var_num, offset++);
178 solution.set(dof, from_value);
197 System & to_sys = to_system_base.
system();
199 unsigned int to_sys_num = to_sys.number();
202 mooseAssert(to_sys.get_mesh().is_serial(),
203 "MultiAppUserObjectTransfer only works with ReplicatedMesh!");
205 unsigned int to_var_num = to_sys.variable_number(to_var.
name());
207 _console <<
"Transferring to: " << to_var.
name() << std::endl;
212 NumericVector<Number> * to_solution = to_sys.solution.get();
214 MeshBase * to_mesh = NULL;
221 auto & fe_type = to_sys.variable_type(to_var_num);
222 bool is_constant = fe_type.order == CONSTANT;
223 bool is_nodal = fe_type.family == LAGRANGE;
225 if (fe_type.order > FIRST && !is_nodal)
226 mooseError(
"We don't currently support second order or higher elemental variable ");
234 for (
auto & node : to_mesh->node_ptr_range())
236 if (node->n_dofs(to_sys_num, to_var_num) > 0)
238 unsigned int node_found_in_sub_app = 0;
239 for (
unsigned int i = 0; i <
_multi_app->numGlobalApps(); i++)
246 if (app_box.contains_point(*node))
247 ++node_found_in_sub_app;
250 if (node_found_in_sub_app == 0)
253 mooseError(
"MultiAppUserObjectTransfer: Master node ",
255 " not found within the bounding box of any of the sub applications.");
257 else if (node_found_in_sub_app > 1)
260 mooseError(
"MultiAppUserObjectTransfer: Master node ",
262 " found within the bounding box of two or more sub applications.");
269 std::vector<Point> points;
270 for (
auto & elem : as_range(to_mesh->elements_begin(), to_mesh->elements_end()))
273 if (elem->n_dofs(to_sys_num, to_var_num) < 1)
280 points.push_back(elem->centroid());
284 for (
auto & node : elem->node_ref_range())
285 points.push_back(node);
287 auto n_points = points.size();
288 unsigned int n_comp = elem->n_comp(to_sys_num, to_var_num);
290 if (n_points != n_comp)
293 " does not equal to number of variable components ",
296 for (
auto & point : points)
298 unsigned int elem_found_in_sub_app = 0;
300 for (
unsigned int i = 0; i <
_multi_app->numGlobalApps(); i++)
307 if (app_box.contains_point(point))
308 ++elem_found_in_sub_app;
311 if (elem_found_in_sub_app == 0)
312 mooseError(
"MultiAppUserObjectTransfer: Master element with ",
313 n_points > 1 ?
"node" :
"centroid",
316 " not found within the bounding box of any of the sub applications.");
318 else if (elem_found_in_sub_app > 1)
319 mooseError(
"MultiAppUserObjectTransfer: Master element with ",
320 n_points > 1 ?
"node" :
"centroid",
323 " found within the bounding box of two or more sub applications.");
329 for (
unsigned int i = 0; i <
_multi_app->numGlobalApps(); i++)
340 for (
auto & node : to_mesh->node_ptr_range())
342 if (node->n_dofs(to_sys_num, to_var_num) > 0)
347 dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0);
352 from_value = user_object.
spatialValue(*node - app_position);
355 if (from_value == std::numeric_limits<Real>::infinity())
358 mooseError(
"MultiAppUserObjectTransfer: Point corresponding to master node at (",
360 ") not found in the sub application.");
362 to_solution->set(dof, from_value);
369 std::vector<Point> points;
370 for (
auto & elem : as_range(to_mesh->elements_begin(), to_mesh->elements_end()))
373 if (elem->n_dofs(to_sys_num, to_var_num) < 1)
380 points.push_back(elem->centroid());
384 for (
auto & node : elem->node_ref_range())
385 points.push_back(node);
387 auto n_points = points.size();
388 unsigned int n_comp = elem->n_comp(to_sys_num, to_var_num);
390 if (n_points != n_comp)
393 " does not equal to number of variable components ",
396 unsigned int offset = 0;
397 for (
auto & point : points)
402 dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, offset++);
407 from_value = user_object.
spatialValue(point - app_position);
410 if (from_value == std::numeric_limits<Real>::infinity())
412 "MultiAppUserObjectTransfer: Point corresponding to element's centroid (",
414 ") not found in sub application.");
416 to_solution->set(dof, from_value);
423 to_solution->close();
430 _console <<
"Finished MultiAppUserObjectTransfer " <<
name() << std::endl;