25 #include "libmesh/meshfree_interpolation.h" 26 #include "libmesh/system.h" 27 #include "libmesh/mesh_function.h" 28 #include "libmesh/mesh_tools.h" 38 params.
set<std::vector<VariableName>>(
"source_variable") = std::vector<VariableName>{};
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_parent_nodes_contained_in_sub_app",
46 "Set to true if every parent app node is mapped to a distinct point on one " 47 "of the subApps during a transfer from sub App to Parent App. If parent app" 48 " node cannot be found within bounding boxes of any of the subApps, an " 49 " error is generated.");
51 "all_master_nodes_contained_in_sub_app",
52 "Set to true if every parent app node is mapped to a distinct point on one " 53 "of the subApps during a transfer from sub App to Parent App. If parent app" 54 " node cannot be found within bounding boxes of any of the subApps, an " 55 " error is generated.",
56 "all_master_nodes_contained_in_sub_app is deprecated. Use " 57 "all_parent_nodes_contained_in_sub_app");
59 "skip_bounding_box_check",
61 "Skip the check if the to_elem is within the bounding box of the from_app.");
62 params.
addParam<std::vector<SubdomainName>>(
63 "block",
"The block we are transferring to (if not specified, whole domain is used).");
64 params.
addParam<std::vector<BoundaryName>>(
66 "The boundary we are transferring to (if not specified, whole domain is used unless 'block' " 67 "parameter is used).");
70 "Samples a variable's value in the Parent app domain at the point where the MultiApp is and " 71 "copies that value into a post-processor in the MultiApp");
73 params.
addParam<
bool>(
"nearest_sub_app",
75 "When True, a from_multiapp transfer will work by finding the nearest " 76 "(using the `location`) sub-app and query that for the value to transfer");
82 _user_object_name(getParam<UserObjectName>(
"user_object")),
83 _all_parent_nodes_contained_in_sub_app(
84 isParamValid(
"all_master_nodes_contained_in_sub_app")
85 ? getParam<bool>(
"all_master_nodes_contained_in_sub_app")
86 : getParam<bool>(
"all_parent_nodes_contained_in_sub_app")),
87 _skip_bbox_check(getParam<bool>(
"skip_bounding_box_check")),
88 _nearest_sub_app(getParam<bool>(
"nearest_sub_app"))
91 "MultiAppGeneralFieldUserObjectTransfer instead and adapt the parameters");
97 paramError(
"variable",
" Support single to-variable only ");
101 " You should not provide any source variables since the transfer takes values from " 105 mooseError(
name(),
": Transfer can be either block- or boundary-restricted. Not both.");
110 "Sibling multiapp transfer has not been implemented for this transfer.");
117 "MultiAppUserObjectTransfer::execute()", 5,
"Performing transfer with a user object");
138 for (
unsigned int i = 0; i <
getToMultiApp()->numGlobalApps(); i++)
147 unsigned int sys_num = to_sys->number();
148 unsigned int var_num = to_sys->variable_number(
_to_var_name);
163 const std::vector<SubdomainName> &
blocks =
164 getParam<std::vector<SubdomainName>>(
"block");
165 for (
const auto & b :
blocks)
167 paramError(
"block",
"The block '", b,
"' was not found in the mesh");
169 std::vector<SubdomainID> ids =
mesh->getSubdomainIDs(
blocks);
170 _blk_ids.insert(ids.begin(), ids.end());
174 const std::vector<BoundaryName> & boundary_names =
175 getParam<std::vector<BoundaryName>>(
"boundary");
176 for (
const auto & b : boundary_names)
178 paramError(
"boundary",
"The boundary '", b,
"' was not found in the mesh");
180 std::vector<BoundaryID> ids =
mesh->getBoundaryIDs(boundary_names,
true);
181 _bnd_ids.insert(ids.begin(), ids.end());
184 auto & fe_type = to_sys->variable_type(var_num);
185 bool is_constant = fe_type.order ==
CONSTANT;
186 bool is_nodal = fe_type.family ==
LAGRANGE;
188 if (fe_type.order >
FIRST && !is_nodal)
189 mooseError(
"We don't currently support second order or higher elemental variable ");
199 for (
auto & node :
mesh->getMesh().local_node_ptr_range())
207 if (node->n_dofs(sys_num, var_num) > 0)
210 dof_id_type dof = node->dof_number(sys_num, var_num, 0);
214 user_object.
spatialValue(from_transform.mapBack(to_transform(*node)));
217 solution.set(dof, from_value);
223 std::vector<Point> points;
224 for (
auto & elem :
as_range(
mesh->getMesh().local_elements_begin(),
225 mesh->getMesh().local_elements_end()))
234 if (elem->n_dofs(sys_num, var_num) < 1)
241 points.push_back(elem->vertex_average());
245 for (
auto & node : elem->node_ref_range())
246 points.push_back(node);
248 auto n_points = points.size();
249 unsigned int n_comp = elem->n_comp(sys_num, var_num);
251 if (n_points != n_comp)
254 " does not equal to number of variable components ",
257 unsigned int offset = 0;
258 for (
auto & point : points)
260 dof_id_type dof = elem->dof_number(sys_num, var_num, offset++);
264 user_object.
spatialValue(from_transform.mapBack(to_transform(point)));
267 solution.set(dof, from_value);
282 mooseAssert(
_to_transforms.size() == 1,
"This should only be size one");
288 System & to_sys = to_system_base.
system();
290 unsigned int to_sys_num = to_sys.
number();
293 mooseAssert(to_sys.get_mesh().is_serial(),
294 "MultiAppUserObjectTransfer only works with ReplicatedMesh!");
296 unsigned int to_var_num = to_sys.variable_number(to_var.
name());
308 to_mesh = &to_problem.
mesh();
314 const std::vector<SubdomainName> &
blocks = getParam<std::vector<SubdomainName>>(
"block");
315 for (
const auto & b :
blocks)
317 paramError(
"block",
"The block '", b,
"' was not found in the mesh");
320 _blk_ids.insert(ids.begin(), ids.end());
324 const std::vector<BoundaryName> & boundary_names =
325 getParam<std::vector<BoundaryName>>(
"boundary");
326 for (
const auto & b : boundary_names)
328 paramError(
"boundary",
"The boundary '", b,
"' was not found in the mesh");
330 std::vector<BoundaryID> ids = to_mesh->
getBoundaryIDs(boundary_names,
true);
331 _bnd_ids.insert(ids.begin(), ids.end());
334 auto & fe_type = to_sys.variable_type(to_var_num);
335 bool is_constant = fe_type.order ==
CONSTANT;
336 bool is_nodal = fe_type.family ==
LAGRANGE;
338 if (fe_type.order >
FIRST && !is_nodal)
339 mooseError(
"We don't currently support second order or higher elemental variable ");
347 for (
auto & node : to_mesh->
getMesh().node_ptr_range())
355 if (node->n_dofs(to_sys_num, to_var_num) > 0)
357 const auto transformed_node = to_transform(*node);
359 unsigned int node_found_in_sub_app = 0;
368 if (app_box.contains_point(transformed_node))
369 ++node_found_in_sub_app;
372 if (node_found_in_sub_app == 0)
373 mooseError(
"MultiAppUserObjectTransfer: Parent app node ",
375 " not found within the bounding box of any of the sub applications.");
376 else if (node_found_in_sub_app > 1)
377 mooseError(
"MultiAppUserObjectTransfer: Parent app node ",
379 " found within the bounding box of two or more sub applications.");
385 std::vector<Point> points;
396 if (elem->n_dofs(to_sys_num, to_var_num) < 1)
403 points.push_back(to_transform(elem->vertex_average()));
407 for (
auto & node : elem->node_ref_range())
408 points.push_back(to_transform(node));
410 auto n_points = points.size();
411 unsigned int n_comp = elem->n_comp(to_sys_num, to_var_num);
413 if (n_points != n_comp)
416 " does not equal to number of variable components ",
419 for (
auto & point : points)
421 unsigned int elem_found_in_sub_app = 0;
431 if (app_box.contains_point(point))
432 ++elem_found_in_sub_app;
435 if (elem_found_in_sub_app == 0)
436 mooseError(
"MultiAppUserObjectTransfer: Parent app element with ",
437 n_points > 1 ?
"node" :
"centroid",
440 " not found within the bounding box of any of the sub applications.");
442 else if (elem_found_in_sub_app > 1)
443 mooseError(
"MultiAppUserObjectTransfer: Parent app element with ",
444 n_points > 1 ?
"node" :
"centroid",
447 " found within the bounding box of two or more sub applications.");
455 for (
auto & node : to_mesh->
getMesh().node_ptr_range())
463 if (node->n_dofs(to_sys_num, to_var_num) > 0)
465 const auto transformed_node = to_transform(*node);
469 if (sub_app == static_cast<unsigned int>(-1))
475 dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0);
480 from_value = user_object.spatialValue(from_transform.mapBack(transformed_node));
483 if (from_value == std::numeric_limits<Real>::infinity())
484 mooseError(
"MultiAppUserObjectTransfer: Point corresponding to parent app node at (",
486 ") not found in the sub application.");
487 to_solution->
set(dof, from_value);
493 std::vector<Point> points;
504 if (elem->n_dofs(to_sys_num, to_var_num) < 1)
511 points.push_back(to_transform(elem->vertex_average()));
515 for (
auto & node : elem->node_ref_range())
516 points.push_back(to_transform(node));
518 auto n_points = points.size();
519 unsigned int n_comp = elem->n_comp(to_sys_num, to_var_num);
521 if (n_points != n_comp)
524 " does not equal to number of variable components ",
527 unsigned int offset = 0;
528 for (
auto & point : points)
533 if (sub_app == static_cast<unsigned int>(-1))
537 const auto & user_object =
540 dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, offset++);
545 from_value = user_object.spatialValue(from_transform.mapBack(point));
548 if (from_value == std::numeric_limits<Real>::infinity())
549 mooseError(
"MultiAppUserObjectTransfer: Point corresponding to element's centroid (",
551 ") not found in sub application.");
553 to_solution->
set(dof, from_value);
558 to_solution->
close();
589 const auto & node_blk_ids =
mesh->getNodeBlockIds(*node);
590 std::set<SubdomainID> u;
591 std::set_intersection(
_blk_ids.begin(),
593 node_blk_ids.begin(),
595 std::inserter(u, u.begin()));
603 if (
mesh->isBoundaryNode(node->id(), bid))
612 if (
mesh->isBoundaryElem(elem->id(), bid))
623 unsigned int closest_app = 0;
626 mooseAssert(
_multi_app->numGlobalApps() > 0,
"No Multiapps To Transfer From");
628 for (
unsigned int i = 0; i <
_multi_app->numGlobalApps(); i++)
631 const auto app_position =
_multi_app->runningInPosition()
656 for (
int i =
_multi_app->numGlobalApps() - 1; i >= 0; i--)
661 BoundingBox app_box =
665 return static_cast<unsigned int>(i);
std::vector< std::unique_ptr< MultiAppCoordTransform > > _to_transforms
const ExecFlagType EXEC_TRANSFER
bool hasBlocks(const Elem *elem) const
Check that element 'elem' is part of the domain this transfer is restricted to.
bool isBoundaryElem(const MooseMesh *mesh, const Elem *elem) const
Check that the element belongs to boundary this transfer is restricted to.
static InputParameters validParams()
void mooseDeprecated(Args &&... args) const
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
bool hasBoundaryName(const MeshBase &input_mesh, const BoundaryName &name)
Whether a particular boundary name exists in the mesh.
const bool _all_parent_nodes_contained_in_sub_app
Boolean variable to generate error if every parent app node cannot be mapped to a subApp during from_...
MooseEnum _current_direction
virtual void get(const std::vector< numeric_index_type > &index, Number *values) const
std::string _user_object_name
AuxVariableName _to_var_name
bool isBoundaryNode(const MooseMesh *mesh, const Node *node) const
Check that the node belongs to boundary this transfer is restricted to.
virtual void execute() override
Execute the transfer.
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
const std::vector< VariableName > _from_var_names
Name of variables transferring from.
const std::string & name() const override
Get the variable name.
const Parallel::Communicator & comm() const
virtual void postExecute()
Add some extra work if necessary after execute().
FEProblemBase & _fe_problem
const bool _skip_bbox_check
whether to check the bounding box check or not
const std::shared_ptr< MultiApp > getToMultiApp() const
Get the MultiApp to transfer data to.
This class provides an interface for common operations on field variables of both FE and FV types wit...
Base class for a system (of equations)
std::shared_ptr< MultiApp > _multi_app
Deprecated class attribute for compatibility with the apps.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
Real distance(const Point &p)
virtual const std::string & name() const
Get the name of the class.
std::vector< SubdomainID > getSubdomainIDs(const std::vector< SubdomainName > &subdomain_names) const
Get the associated subdomainIDs for the subdomain names that are passed in.
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const override
Returns the variable reference for requested variable which must be of the expected_var_type (Nonline...
auto max(const L &left, const R &right)
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
bool _displaced_target_mesh
True if displaced mesh is used for the target mesh, otherwise false.
void errorIfDistributedMesh(std::string name) const
Generate a unified error message if the underlying libMesh mesh is a DistributedMesh.
unsigned int number() const
void forceSwap()
Forcibly swap the currently swapped-out communicator back in to libmesh.
void errorIfObjectExecutesOnTransferInSourceApp(const std::string &object_name) const
Error if executing this MooseObject on EXEC_TRANSFER in a source multiapp (from_multiapp, e.g.
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
bool blockRestricted() const
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
std::set< SubdomainID > _blk_ids
Set of block ids this transfer is restricted to.
const std::vector< AuxVariableName > _to_var_names
Name of variables transferring to.
static libMesh::System * find_sys(libMesh::EquationSystems &es, const std::string &var_name)
Small helper function for finding the system containing the variable.
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
std::set< BoundaryID > _bnd_ids
Set of the boundary ids.
Transfers variables on possibly different meshes while conserving a user defined property (Postproces...
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 hasSubdomainName(const MeshBase &input_mesh, const SubdomainName &name)
Whether a particular subdomain name exists in the mesh.
Loops over a target mesh and uses either node or element centroid location (based on the target varia...
const bool & _nearest_sub_app
Whether to utilize the nearest sub-app to transfer from.
virtual Real spatialValue(const Point &) const
Optional interface function for "evaluating" a UserObject at a spatial position.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
unsigned int findSubAppToTransferFrom(const Point &p)
Gets the UserObject to transfer from when transferring from_multiapp.
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
virtual MooseMesh & mesh() override
bool _displaced_source_mesh
True if displaced mesh is used for the source mesh, otherwise false.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
static InputParameters validParams()
virtual void set(const numeric_index_type i, const Number value)=0
bool boundaryRestricted() const
std::vector< BoundaryID > getBoundaryIDs(const Elem *const elem, const unsigned short int side) const
Returns a vector of boundary IDs for the requested element on the requested side. ...
virtual void computeUserObjectByName(const ExecFlagType &type, const Moose::AuxGroup &group, const std::string &name)
Compute an user object with the given name.
MultiAppUserObjectTransfer(const InputParameters ¶meters)
virtual void getAppInfo()
This method will fill information into the convenience member variables (_to_problems, _from_meshes, etc.)
SystemBase & sys()
Get the system this variable is part of.
Base class for user-specific data.
registerMooseObjectDeprecated("MooseApp", MultiAppUserObjectTransfer, "12/31/2024 24:00")