30 "Transfers functor data at the MultiApp position by evaluating the functor inside its domain "
31 "of definition and extrapolating with a user-selected behavior outside");
36 params.
suppressParameter<std::vector<unsigned int>>(
"source_variable_components");
39 "source_functors",
"Functors providing the values to transfer to the target variables");
48 MooseEnum extrapolation(
"flat evaluate_oob nearest-node nearest-elem",
"nearest-node");
51 "How to extrapolate the functors when a target point for the transfer "
52 "is outside the domain of evaluation");
55 params.
renameParam(
"use_nearest_app",
"assume_nearest_app_holds_evaluation_location",
"");
64 _functor_names(getParam<
std::vector<MooseFunctorName>>(
"source_functors")),
65 _extrapolation_behavior(getParam<
MooseEnum>(
"extrapolation_behavior"))
70 "Flat (single-constant) extrapolation must be selected if an extrapolation constant "
74 "Flat (single-constant) extrapolation must be selected if an extrapolation post-"
75 "treatment is specified");
79 paramError(
"source_functors",
"Should be the same size as target 'variable'");
151 unsigned int max_leaf_size = 0;
158 for (
const auto app_i : make_range(num_apps_per_tree))
172 const auto & functor =
_functors[i_from][var_index];
178 std::set<SubdomainID> from_blocks;
182 if (functor->hasBlocks(bl))
183 from_blocks.insert(bl);
191 for (
const auto & node : from_mesh.getMesh().local_node_ptr_range())
196 bool on_at_least_one_block =
false;
197 bool on_boundary =
false;
198 for (
const auto eid : libmesh_map_find(node_to_elem_map, node->id()))
200 bool has_block = functor->hasBlocks(from_mesh.elemPtr(eid)->subdomain_id());
202 on_at_least_one_block =
true;
206 const auto elem = from_mesh.elemPtr(eid);
207 for (
const auto side : elem->side_index_range())
208 if (!elem->neighbor_ptr(side) &&
209 elem->is_node_on_side(elem->get_node_index(node), side))
214 if (!on_at_least_one_block || !on_boundary)
241 tree_division_index != node_div_index)
263 _local_values[i_source].push_back((*functor)(node_arg, time_arg));
270 for (
const auto & elem : from_mesh.getMesh().local_element_ptr_range())
273 if (!functor->hasBlocks(elem->subdomain_id()))
277 bool at_a_boundary =
false;
278 for (
const auto side : elem->side_index_range())
281 if (!elem->neighbor_ptr(side))
283 at_a_boundary =
true;
287 else if (!functor->hasBlocks(elem->neighbor_ptr(side)->subdomain_id()))
289 at_a_boundary =
true;
309 const auto node_div_index =
322 tree_division_index != node_div_index)
327 const auto transformed_centroid =
345 _local_values[i_source].push_back((*functor)(elem_arg, time_arg));
348 max_leaf_size = std::max(max_leaf_size, from_mesh.getMaxLeafSize());
352 std::shared_ptr<KDTree> _kd_tree =
353 std::make_shared<KDTree>(
_local_points[i_source], max_leaf_size);
360 const unsigned int var_index,
361 const std::vector<std::pair<Point, unsigned int>> & incoming_points,
362 std::vector<std::pair<Real, Real>> & outgoing_vals)
369 const unsigned int var_index,
370 const std::vector<std::pair<Point, unsigned int>> & incoming_points,
371 std::vector<std::pair<Real, Real>> & outgoing_vals)
373 dof_id_type i_pt = 0;
374 std::set<const Elem *> elem_candidates;
377 for (
const auto & [pt, mesh_div] : incoming_points)
380 outgoing_vals[i_pt].second = std::numeric_limits<Real>::max();
381 bool point_found =
false;
395 for (
const auto app_i : make_range(num_apps_per_tree))
397 const auto app_index =
getAppIndex(i_source, app_i);
400 const Point app_local_pt =
404 const auto & functor = *
_functors[app_index][var_index];
407 std::set<SubdomainID> from_blocks;
411 :
_from_problems[app_index]->mesh().getMesh().get_mesh_subdomains())
412 if (functor.hasBlocks(bl))
413 from_blocks.insert(bl);
418 elem_candidates.clear();
419 if (from_blocks.size())
420 (*
_point_locators[app_index])(app_local_pt, elem_candidates, &from_blocks);
423 if (elem_candidates.size())
438 unsigned int num_values = 0;
439 for (
const auto elem : elem_candidates)
445 elem->processor_id() !=
_from_problems[app_index]->processor_id())
452 value += functor(elem_pt_arg, time_arg);
460 outgoing_vals[i_pt] = {value, 0};
493 const Point oob_local_pt =
495 const auto & functor = *
_functors[first_app][var_index];
503 for (
const auto index : return_index)
506 const auto new_distance = dist_sum / return_dist_sqr.size();
507 if (new_distance < outgoing_vals[i_pt].second)
511 outgoing_vals[i_pt] = {functor(elem_pt_arg, time_arg), new_distance};
const ExecFlagType EXEC_TRANSFER
registerMooseObject("MooseApp", MultiAppGeneralFieldFunctorTransfer)
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual void computeUserObjectByName(const ExecFlagType &type, const Moose::AuxGroup &group, const std::string &name)
Compute an user object with the given name.
bool hasUserObject(const std::string &name) const
Check if there if a user object of given name.
virtual MooseMesh & mesh() override
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.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
const std::unordered_map< dof_id_type, std::vector< dof_id_type > > & nodeToElemMap()
If not already created, creates a map from every node to all elements to which they are connected.
const std::vector< AuxVariableName > _to_var_names
Name of variables transferring to.
Transfers a functor (can be variable, function, functor material property, spatial UO,...
virtual void prepareEvaluationOfInterpValues(const unsigned int var_index) override
MultiAppGeneralFieldFunctorTransfer(const InputParameters ¶meters)
void execute() override
Execute the transfer.
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
static InputParameters validParams()
std::vector< bool > _functor_is_variable
Whether the functor is a variable.
std::vector< std::vector< const Moose::Functor< Real > * > > _functors
Pointers to the source functors.
std::vector< std::unique_ptr< libMesh::PointLocatorBase > > _point_locators
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) override
void buildKDTrees(const unsigned int var_index) override
void evaluateValues(const unsigned int var_index, const std::vector< std::pair< Point, unsigned int > > &incoming_points, std::vector< std::pair< Real, Real > > &outgoing_vals)
const MooseEnum _extrapolation_behavior
How to determine values where the target mesh does not overlap the source mesh.
const std::vector< MooseFunctorName > _functor_names
Names of the source functors.
Base class for working with KDTrees in transfers, whether for interpolation or extrapolation.
virtual void prepareEvaluationOfInterpValues(const unsigned int var_index) override
bool checkRestrictionsForSource(const Point &pt, const unsigned int valid_mesh_div, const unsigned int i_from) const
Examine all spatial restrictions that could preclude this source from being a valid source for this p...
unsigned int getNumAppsPerTree() const
Number of applications which contributed nearest-locations to each KD-tree.
std::vector< std::vector< Point > > _local_points
All the nodes that meet the spatial restrictions in all the local source apps.
std::vector< std::shared_ptr< KDTree > > _local_kdtrees
KD-Trees for all the local source apps.
unsigned int _num_sources
Number of KD-Trees to create.
unsigned int getAppIndex(unsigned int kdtree_index, unsigned int app_index_in_tree) const
Get the index of the app when inside of a KD-Tree source loop, where multiple applications could be l...
std::vector< std::vector< Real > > _local_values
Values of the variable being transferred at all the points in _local_points.
static InputParameters validParams()
void computeNumSources()
Pre-compute the number of sources Number of KDTrees used to hold the locations and variable value dat...
unsigned int _num_nearest_points
Number of points to consider.
const bool _group_subapps
Whether to group data when creating the nearest-point regions.
bool inBlocks(const std::set< SubdomainID > &blocks, const MooseMesh &mesh, const Elem *elem) const override
unsigned int getNumDivisions() const
Number of divisions (nearest-positions or source mesh divisions) used when building KD-Trees.
void evaluateNearestNodeFromKDTrees(const Point &pt, unsigned int source_index, std::pair< Real, Real > &outgoing_val, bool &point_found)
Search all local KD-trees for the nearest node/element and update outgoing_val.
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
const bool _use_nearest_app
Whether to keep track of the distance from the requested point to the app position.
const MooseEnum _post_transfer_extrapolation
How to post treat after the transfer.
const Positions * _nearest_positions_obj
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.
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
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.
std::set< SubdomainID > _from_blocks
Origin block(s) restriction.
std::vector< const MeshDivision * > _from_mesh_divisions
Division of the origin mesh.
std::set< BoundaryID > _from_boundaries
Origin boundary(ies) restriction.
bool _search_value_conflicts
Whether to look for conflicts between origin points, multiple valid values for a target point.
unsigned int getGlobalSourceAppIndex(unsigned int i_from) const
Return the global app index from the local index in the "from-multiapp" transfer direction.
void errorIfObjectExecutesOnTransferInSourceApp(const std::string &object_name) const
Error if executing this MooseObject on EXEC_TRANSFER in a source multiapp (from_multiapp,...
bool _displaced_source_mesh
True if displaced mesh is used for the source mesh, otherwise false.
std::vector< FEProblemBase * > _from_problems
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
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...
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.
An interface for accessing Moose::Functors for systems that do not care about automatic differentiati...
static InputParameters validParams()
FEProblemBase & _fe_problem
MooseEnum _current_direction
unsigned int INVALID_DIVISION_INDEX
Invalid subdomain id to return when outside the mesh division.
static constexpr Real TOLERANCE
A structure that is used to evaluate Moose functors logically at an element/cell center.
A structure that is used to evaluate Moose functors at an arbitrary physical point contained within a...
static const std::set< SubdomainID > undefined_subdomain_connection
A static member that can be used when the connection of a node to subdomains is unknown.
State argument for evaluating functors.