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");
125 for (
unsigned int i = 0; i <
getToMultiApp()->numGlobalApps(); i++)
134 unsigned int sys_num = to_sys->number();
135 unsigned int var_num = to_sys->variable_number(
_to_var_name);
150 const std::vector<SubdomainName> & blocks =
151 getParam<std::vector<SubdomainName>>(
"block");
152 for (
const auto & b : blocks)
154 paramError(
"block",
"The block '", b,
"' was not found in the mesh");
156 std::vector<SubdomainID> ids =
mesh->getSubdomainIDs(blocks);
157 _blk_ids.insert(ids.begin(), ids.end());
161 const std::vector<BoundaryName> & boundary_names =
162 getParam<std::vector<BoundaryName>>(
"boundary");
163 for (
const auto & b : boundary_names)
165 paramError(
"boundary",
"The boundary '", b,
"' was not found in the mesh");
167 std::vector<BoundaryID> ids =
mesh->getBoundaryIDs(boundary_names,
true);
168 _bnd_ids.insert(ids.begin(), ids.end());
171 auto & fe_type = to_sys->variable_type(var_num);
172 bool is_constant = fe_type.order ==
CONSTANT;
173 bool is_nodal = fe_type.family ==
LAGRANGE;
175 if (fe_type.order >
FIRST && !is_nodal)
176 mooseError(
"We don't currently support second order or higher elemental variable ");
186 for (
auto & node :
mesh->getMesh().local_node_ptr_range())
194 if (node->n_dofs(sys_num, var_num) > 0)
197 dof_id_type dof = node->dof_number(sys_num, var_num, 0);
201 user_object.
spatialValue(from_transform.mapBack(to_transform(*node)));
204 solution.set(dof, from_value);
210 std::vector<Point> points;
211 for (
auto & elem :
as_range(
mesh->getMesh().local_elements_begin(),
212 mesh->getMesh().local_elements_end()))
221 if (elem->n_dofs(sys_num, var_num) < 1)
228 points.push_back(elem->vertex_average());
232 for (
auto & node : elem->node_ref_range())
233 points.push_back(node);
235 auto n_points = points.size();
236 unsigned int n_comp = elem->n_comp(sys_num, var_num);
238 if (n_points != n_comp)
241 " does not equal to number of variable components ",
244 unsigned int offset = 0;
245 for (
auto & point : points)
247 dof_id_type dof = elem->dof_number(sys_num, var_num, offset++);
251 user_object.
spatialValue(from_transform.mapBack(to_transform(point)));
254 solution.set(dof, from_value);
269 mooseAssert(
_to_transforms.size() == 1,
"This should only be size one");
275 System & to_sys = to_system_base.
system();
277 unsigned int to_sys_num = to_sys.number();
280 mooseAssert(to_sys.get_mesh().is_serial(),
281 "MultiAppUserObjectTransfer only works with ReplicatedMesh!");
283 unsigned int to_var_num = to_sys.variable_number(to_var.
name());
295 to_mesh = &to_problem.
mesh();
301 const std::vector<SubdomainName> & blocks = getParam<std::vector<SubdomainName>>(
"block");
302 for (
const auto & b : blocks)
304 paramError(
"block",
"The block '", b,
"' was not found in the mesh");
307 _blk_ids.insert(ids.begin(), ids.end());
311 const std::vector<BoundaryName> & boundary_names =
312 getParam<std::vector<BoundaryName>>(
"boundary");
313 for (
const auto & b : boundary_names)
315 paramError(
"boundary",
"The boundary '", b,
"' was not found in the mesh");
317 std::vector<BoundaryID> ids = to_mesh->
getBoundaryIDs(boundary_names,
true);
318 _bnd_ids.insert(ids.begin(), ids.end());
321 auto & fe_type = to_sys.variable_type(to_var_num);
322 bool is_constant = fe_type.order ==
CONSTANT;
323 bool is_nodal = fe_type.family ==
LAGRANGE;
325 if (fe_type.order >
FIRST && !is_nodal)
326 mooseError(
"We don't currently support second order or higher elemental variable ");
334 for (
auto & node : to_mesh->
getMesh().node_ptr_range())
342 if (node->n_dofs(to_sys_num, to_var_num) > 0)
344 const auto transformed_node = to_transform(*node);
346 unsigned int node_found_in_sub_app = 0;
355 if (app_box.contains_point(transformed_node))
356 ++node_found_in_sub_app;
359 if (node_found_in_sub_app == 0)
360 mooseError(
"MultiAppUserObjectTransfer: Parent app node ",
362 " not found within the bounding box of any of the sub applications.");
363 else if (node_found_in_sub_app > 1)
364 mooseError(
"MultiAppUserObjectTransfer: Parent app node ",
366 " found within the bounding box of two or more sub applications.");
372 std::vector<Point> points;
383 if (elem->n_dofs(to_sys_num, to_var_num) < 1)
390 points.push_back(to_transform(elem->vertex_average()));
394 for (
auto & node : elem->node_ref_range())
395 points.push_back(to_transform(node));
397 auto n_points = points.size();
398 unsigned int n_comp = elem->n_comp(to_sys_num, to_var_num);
400 if (n_points != n_comp)
403 " does not equal to number of variable components ",
406 for (
auto & point : points)
408 unsigned int elem_found_in_sub_app = 0;
418 if (app_box.contains_point(point))
419 ++elem_found_in_sub_app;
422 if (elem_found_in_sub_app == 0)
423 mooseError(
"MultiAppUserObjectTransfer: Parent app element with ",
424 n_points > 1 ?
"node" :
"centroid",
427 " not found within the bounding box of any of the sub applications.");
429 else if (elem_found_in_sub_app > 1)
430 mooseError(
"MultiAppUserObjectTransfer: Parent app element with ",
431 n_points > 1 ?
"node" :
"centroid",
434 " found within the bounding box of two or more sub applications.");
442 for (
auto & node : to_mesh->
getMesh().node_ptr_range())
450 if (node->n_dofs(to_sys_num, to_var_num) > 0)
452 const auto transformed_node = to_transform(*node);
456 if (sub_app == static_cast<unsigned int>(-1))
462 dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0);
467 from_value = user_object.spatialValue(from_transform.mapBack(transformed_node));
470 if (from_value == std::numeric_limits<Real>::infinity())
471 mooseError(
"MultiAppUserObjectTransfer: Point corresponding to parent app node at (",
473 ") not found in the sub application.");
474 to_solution->
set(dof, from_value);
480 std::vector<Point> points;
491 if (elem->n_dofs(to_sys_num, to_var_num) < 1)
498 points.push_back(to_transform(elem->vertex_average()));
502 for (
auto & node : elem->node_ref_range())
503 points.push_back(to_transform(node));
505 auto n_points = points.size();
506 unsigned int n_comp = elem->n_comp(to_sys_num, to_var_num);
508 if (n_points != n_comp)
511 " does not equal to number of variable components ",
514 unsigned int offset = 0;
515 for (
auto & point : points)
520 if (sub_app == static_cast<unsigned int>(-1))
524 const auto & user_object =
527 dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, offset++);
532 from_value = user_object.spatialValue(from_transform.mapBack(point));
535 if (from_value == std::numeric_limits<Real>::infinity())
536 mooseError(
"MultiAppUserObjectTransfer: Point corresponding to element's centroid (",
538 ") not found in sub application.");
540 to_solution->
set(dof, from_value);
545 to_solution->
close();
576 const std::set<SubdomainID> & node_blk_ids =
mesh->getNodeBlockIds(*node);
577 std::set<SubdomainID> u;
578 std::set_intersection(
_blk_ids.begin(),
580 node_blk_ids.begin(),
582 std::inserter(u, u.begin()));
590 if (
mesh->isBoundaryNode(node->id(), bid))
599 if (
mesh->isBoundaryElem(elem->id(), bid))
610 unsigned int closest_app = 0;
613 mooseAssert(
_multi_app->numGlobalApps() > 0,
"No Multiapps To Transfer From");
615 for (
unsigned int i = 0; i <
_multi_app->numGlobalApps(); i++)
618 const auto app_position =
_multi_app->runningInPosition()
643 for (
int i =
_multi_app->numGlobalApps() - 1; i >= 0; i--)
648 BoundingBox app_box =
652 return static_cast<unsigned int>(i);
std::vector< std::unique_ptr< MultiAppCoordTransform > > _to_transforms
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.
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.
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.
void forceSwap()
Forcibly swap the currently swapped-out communicator back in to libmesh.
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.
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...
bool hasSubdomainName(MeshBase &input_mesh, const SubdomainName &name)
Whether a particular subdomain name exists in the mesh.
virtual System & system()=0
Get the reference to the libMesh system.
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 ...
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()
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. ...
std::vector< SubdomainID > getSubdomainIDs(const std::vector< SubdomainName > &subdomain_name) const
Get the associated subdomainIDs for the subdomain names that are passed in.
virtual void set(const numeric_index_type i, const Number value)=0
bool boundaryRestricted() const
static System * find_sys(EquationSystems &es, const std::string &var_name)
Small helper function for finding the system containing the variable.
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")