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");
84 _user_object_name(getParam<UserObjectName>(
"user_object")),
85 _all_parent_nodes_contained_in_sub_app(
86 isParamValid(
"all_master_nodes_contained_in_sub_app")
87 ? getParam<bool>(
"all_master_nodes_contained_in_sub_app")
88 : getParam<bool>(
"all_parent_nodes_contained_in_sub_app")),
89 _skip_bbox_check(getParam<bool>(
"skip_bounding_box_check")),
90 _nearest_sub_app(getParam<bool>(
"nearest_sub_app"))
93 "MultiAppGeneralFieldUserObjectTransfer instead and adapt the parameters");
99 paramError(
"variable",
" Support single to-variable only ");
103 " You should not provide any source variables since the transfer takes values from " 107 mooseError(
name(),
": Transfer can be either block- or boundary-restricted. Not both.");
112 "Sibling multiapp transfer has not been implemented for this transfer.");
119 "MultiAppUserObjectTransfer::execute()", 5,
"Performing transfer with a user object");
141 for (
unsigned int i = 0; i <
getToMultiApp()->numGlobalApps(); i++)
150 unsigned int sys_num = to_sys->number();
151 unsigned int var_num = to_sys->variable_number(
_to_var_name);
166 const std::vector<SubdomainName> &
blocks =
167 getParam<std::vector<SubdomainName>>(
"block");
168 for (
const auto & b :
blocks)
170 paramError(
"block",
"The block '", b,
"' was not found in the mesh");
172 std::vector<SubdomainID> ids =
mesh->getSubdomainIDs(
blocks);
173 _blk_ids.insert(ids.begin(), ids.end());
177 const std::vector<BoundaryName> & boundary_names =
178 getParam<std::vector<BoundaryName>>(
"boundary");
179 for (
const auto & b : boundary_names)
181 paramError(
"boundary",
"The boundary '", b,
"' was not found in the mesh");
183 std::vector<BoundaryID> ids =
mesh->getBoundaryIDs(boundary_names,
true);
184 _bnd_ids.insert(ids.begin(), ids.end());
187 auto & fe_type = to_sys->variable_type(var_num);
188 bool is_constant = fe_type.order ==
CONSTANT;
189 bool is_nodal = fe_type.family ==
LAGRANGE;
191 if (fe_type.order >
FIRST && !is_nodal)
192 mooseError(
"We don't currently support second order or higher elemental variable ");
202 for (
auto & node :
mesh->getMesh().local_node_ptr_range())
210 if (node->n_dofs(sys_num, var_num) > 0)
213 dof_id_type dof = node->dof_number(sys_num, var_num, 0);
217 user_object.
spatialValue(from_transform.mapBack(to_transform(*node)));
220 solution.set(dof, from_value);
226 std::vector<Point> points;
227 for (
auto & elem :
as_range(
mesh->getMesh().local_elements_begin(),
228 mesh->getMesh().local_elements_end()))
237 if (elem->n_dofs(sys_num, var_num) < 1)
244 points.push_back(elem->vertex_average());
248 for (
auto & node : elem->node_ref_range())
249 points.push_back(node);
251 auto n_points = points.size();
252 unsigned int n_comp = elem->n_comp(sys_num, var_num);
254 if (n_points != n_comp)
257 " does not equal to number of variable components ",
260 unsigned int offset = 0;
261 for (
auto & point : points)
263 dof_id_type dof = elem->dof_number(sys_num, var_num, offset++);
267 user_object.
spatialValue(from_transform.mapBack(to_transform(point)));
270 solution.set(dof, from_value);
285 mooseAssert(
_to_transforms.size() == 1,
"This should only be size one");
291 System & to_sys = to_system_base.
system();
293 unsigned int to_sys_num = to_sys.
number();
296 mooseAssert(to_sys.get_mesh().is_serial(),
297 "MultiAppUserObjectTransfer only works with ReplicatedMesh!");
299 unsigned int to_var_num = to_sys.variable_number(to_var.
name());
311 to_mesh = &to_problem.
mesh();
317 const std::vector<SubdomainName> &
blocks = getParam<std::vector<SubdomainName>>(
"block");
318 for (
const auto & b :
blocks)
320 paramError(
"block",
"The block '", b,
"' was not found in the mesh");
323 _blk_ids.insert(ids.begin(), ids.end());
327 const std::vector<BoundaryName> & boundary_names =
328 getParam<std::vector<BoundaryName>>(
"boundary");
329 for (
const auto & b : boundary_names)
331 paramError(
"boundary",
"The boundary '", b,
"' was not found in the mesh");
333 std::vector<BoundaryID> ids = to_mesh->
getBoundaryIDs(boundary_names,
true);
334 _bnd_ids.insert(ids.begin(), ids.end());
337 auto & fe_type = to_sys.variable_type(to_var_num);
338 bool is_constant = fe_type.order ==
CONSTANT;
339 bool is_nodal = fe_type.family ==
LAGRANGE;
341 if (fe_type.order >
FIRST && !is_nodal)
342 mooseError(
"We don't currently support second order or higher elemental variable ");
350 for (
auto & node : to_mesh->
getMesh().node_ptr_range())
358 if (node->n_dofs(to_sys_num, to_var_num) > 0)
360 const auto transformed_node = to_transform(*node);
362 unsigned int node_found_in_sub_app = 0;
371 if (app_box.contains_point(transformed_node))
372 ++node_found_in_sub_app;
375 if (node_found_in_sub_app == 0)
376 mooseError(
"MultiAppUserObjectTransfer: Parent app node ",
378 " not found within the bounding box of any of the sub applications.");
379 else if (node_found_in_sub_app > 1)
380 mooseError(
"MultiAppUserObjectTransfer: Parent app node ",
382 " found within the bounding box of two or more sub applications.");
388 std::vector<Point> points;
399 if (elem->n_dofs(to_sys_num, to_var_num) < 1)
406 points.push_back(to_transform(elem->vertex_average()));
410 for (
auto & node : elem->node_ref_range())
411 points.push_back(to_transform(node));
413 auto n_points = points.size();
414 unsigned int n_comp = elem->n_comp(to_sys_num, to_var_num);
416 if (n_points != n_comp)
419 " does not equal to number of variable components ",
422 for (
auto & point : points)
424 unsigned int elem_found_in_sub_app = 0;
434 if (app_box.contains_point(point))
435 ++elem_found_in_sub_app;
438 if (elem_found_in_sub_app == 0)
439 mooseError(
"MultiAppUserObjectTransfer: Parent app element with ",
440 n_points > 1 ?
"node" :
"centroid",
443 " not found within the bounding box of any of the sub applications.");
445 else if (elem_found_in_sub_app > 1)
446 mooseError(
"MultiAppUserObjectTransfer: Parent app element with ",
447 n_points > 1 ?
"node" :
"centroid",
450 " found within the bounding box of two or more sub applications.");
458 for (
auto & node : to_mesh->
getMesh().node_ptr_range())
466 if (node->n_dofs(to_sys_num, to_var_num) > 0)
468 const auto transformed_node = to_transform(*node);
472 if (sub_app == static_cast<unsigned int>(-1))
478 dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0);
483 from_value = user_object.spatialValue(from_transform.mapBack(transformed_node));
486 if (from_value == std::numeric_limits<Real>::infinity())
487 mooseError(
"MultiAppUserObjectTransfer: Point corresponding to parent app node at (",
489 ") not found in the sub application.");
490 to_solution->
set(dof, from_value);
496 std::vector<Point> points;
507 if (elem->n_dofs(to_sys_num, to_var_num) < 1)
514 points.push_back(to_transform(elem->vertex_average()));
518 for (
auto & node : elem->node_ref_range())
519 points.push_back(to_transform(node));
521 auto n_points = points.size();
522 unsigned int n_comp = elem->n_comp(to_sys_num, to_var_num);
524 if (n_points != n_comp)
527 " does not equal to number of variable components ",
530 unsigned int offset = 0;
531 for (
auto & point : points)
536 if (sub_app == static_cast<unsigned int>(-1))
540 const auto & user_object =
543 dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, offset++);
548 from_value = user_object.spatialValue(from_transform.mapBack(point));
551 if (from_value == std::numeric_limits<Real>::infinity())
552 mooseError(
"MultiAppUserObjectTransfer: Point corresponding to element's centroid (",
554 ") not found in sub application.");
556 to_solution->
set(dof, from_value);
561 to_solution->
close();
592 const auto & node_blk_ids =
mesh->getNodeBlockIds(*node);
593 std::set<SubdomainID> u;
594 std::set_intersection(
_blk_ids.begin(),
596 node_blk_ids.begin(),
598 std::inserter(u, u.begin()));
606 if (
mesh->isBoundaryNode(node->id(), bid))
615 if (
mesh->isBoundaryElem(elem->id(), bid))
626 unsigned int closest_app = 0;
629 mooseAssert(
_multi_app->numGlobalApps() > 0,
"No Multiapps To Transfer From");
631 for (
unsigned int i = 0; i <
_multi_app->numGlobalApps(); i++)
634 const auto app_position =
_multi_app->runningInPosition()
659 for (
int i =
_multi_app->numGlobalApps() - 1; i >= 0; i--)
664 BoundingBox app_box =
668 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()
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.
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 ...
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.
static void addUserObjectExecutionCheckParam(InputParameters ¶ms)
Add the execution order check parameter (to skip the warning if needed)
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 Parallel::Communicator & comm() const
void checkParentAppUserObjectExecuteOn(const std::string &object_name) const
Checks the execute_on flags for user object transfers with user objects on the source app which is al...
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)
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 _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
const std::string & name() const
Get the name of the class.
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.
void mooseDeprecated(Args &&... args) const
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...
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 and optionally a file path to the top-level block p...
static InputParameters validParams()
virtual void set(const numeric_index_type i, const Number value)=0
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
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")