https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MultiAppGeneralFieldFunctorTransfer.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
11
12// MOOSE includes
13#include "FEProblem.h"
14#include "MooseMesh.h"
15#include "MooseTypes.h"
16#include "MooseVariableFE.h"
17#include "SystemBase.h"
18#include "Positions.h"
21
23
26{
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");
32
33 // Input variables as functors instead
34 params.suppressParameter<std::vector<VariableName>>("source_variable");
35 // NOTE: could rename this instead once we support array or vector functor component transfer
36 params.suppressParameter<std::vector<unsigned int>>("source_variable_components");
37
38 params.addRequiredParam<std::vector<MooseFunctorName>>(
39 "source_functors", "Functors providing the values to transfer to the target variables");
40
41 // Potential additional parameters:
42 // - functor evaluation spatial argument type
43 // - functor evaluation time argument type
44 // - number of points to use when creating extrapolation 'patches'
45 // - other 'nearest' locations: node, element, side or a general 'location'
46 // - options for a radius based search and build patches instead of 'nearest'
47
48 MooseEnum extrapolation("flat evaluate_oob nearest-node nearest-elem", "nearest-node");
49 params.addParam<MooseEnum>("extrapolation_behavior",
50 extrapolation,
51 "How to extrapolate the functors when a target point for the transfer "
52 "is outside the domain of evaluation");
53
54 // This is a convenient heuristic to limit communication
55 params.renameParam("use_nearest_app", "assume_nearest_app_holds_evaluation_location", "");
56
57 return params;
58}
59
61 const InputParameters & parameters)
64 _functor_names(getParam<std::vector<MooseFunctorName>>("source_functors")),
65 _extrapolation_behavior(getParam<MooseEnum>("extrapolation_behavior"))
66{
67 // Check extrapolation options
68 if (isParamSetByUser("extrapolation_constant") && _extrapolation_behavior != "flat")
69 paramError("extrapolation_behavior",
70 "Flat (single-constant) extrapolation must be selected if an extrapolation constant "
71 "is specified");
73 paramError("extrapolation_behavior",
74 "Flat (single-constant) extrapolation must be selected if an extrapolation post-"
75 "treatment is specified");
76
77 // Check size
78 if (_functor_names.size() != _to_var_names.size())
79 paramError("source_functors", "Should be the same size as target 'variable'");
80}
81
82void
84{
86
87 // Retrieve the functors
88 _functors.resize(_from_problems.size());
90 for (const auto i_functor : index_range(_functor_names))
91 {
92 const auto & fname = _functor_names[i_functor];
93
94 // Different functors for every source
95 for (const auto i_from : index_range(_from_problems))
96 _functors[i_from].push_back(
97 &_from_problems[i_from]->getFunctor<Real>(fname, /*thread*/ 0, name(), false));
98
99 // Need to keep track of variables because of ghosting needs
100 // NOTE: we don't really expect the functor type to vary between problems
101 for (const auto i_from : index_range(_from_problems))
102 _functor_is_variable[i_functor] =
103 _functor_is_variable[i_functor] || _from_problems[i_from]->hasVariable(fname);
104 }
105}
106
107void
109{
110 // Execute the user object if it was specified to execute on TRANSFER
111 for (const auto & fname : _functor_names)
112 switch (_current_direction)
113 {
114 case TO_MULTIAPP:
115 {
116 if (!_fe_problem.hasUserObject(fname))
117 continue;
121 break;
122 }
123 case FROM_MULTIAPP:
125 }
126
127 // Perfom the actual transfer
129}
130
131void
133{
135
136 // Get the point locators
137 _point_locators.resize(_from_problems.size());
138 for (const auto app_index : index_range(_from_problems))
139 _point_locators[app_index] =
140 _from_problems[app_index]->mesh(_displaced_source_mesh).getPointLocator();
141}
142
143void
145{
147 const auto num_apps_per_tree = getNumAppsPerTree();
151 unsigned int max_leaf_size = 0;
152
153 // Construct a local KDTree for each source. A source can be a single app or multiple apps
154 // combined (option for nearest-position / mesh-divisions)
155 for (const auto i_source : make_range(_num_sources))
156 {
157 // Nest a loop on apps in case multiple apps contribute to the same KD-Tree source
158 for (const auto app_i : make_range(num_apps_per_tree))
159 {
160 // Get the current app index
161 const auto i_from = getAppIndex(i_source, app_i);
162 // Current position index, if using nearest positions (not used for use_nearest_app)
163 const auto i_pos = _group_subapps ? i_source : (i_source % getNumDivisions());
164
165 // Get access to the variable and some variable information
166 FEProblemBase & from_problem = *_from_problems[i_from];
167 auto & from_mesh = from_problem.mesh(_displaced_source_mesh);
168 // No need for displaced mesh for checking domain of definition
169 const auto & node_to_elem_map = from_problem.mesh().nodeToElemMap();
170
171 // Get functor for that app
172 const auto & functor = _functors[i_from][var_index];
173
174 // Form the block restriction for evaluation. We need to prevent evaluation outside the
175 // domain of evaluation of the functor (could crash) or the transfer (disobeys user)
176 // Note: the functor subdomains of evaluation are checked below as well, so we
177 // should be fairly safe
178 std::set<SubdomainID> from_blocks;
179 if (_from_blocks.size())
180 {
181 for (const auto bl : _from_blocks)
182 if (functor->hasBlocks(bl))
183 from_blocks.insert(bl);
184 }
185 else
187
188 // We need to loop over the nodes at the edge of the domain of definition of the
189 // current functor
190 if (_extrapolation_behavior == 2) // nearest-node
191 for (const auto & node : from_mesh.getMesh().local_node_ptr_range())
192 {
193 // No way to check number of dofs for a functor
194 // Functor should be defined on at least one block by the block to have a value
195 // Node should be either on a functor or a mesh boundary to be relevant for extrapolation
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()))
199 {
200 bool has_block = functor->hasBlocks(from_mesh.elemPtr(eid)->subdomain_id());
201 if (has_block)
202 on_at_least_one_block = true;
203 else
204 on_boundary = true;
205 // Detect a mesh boundary
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))
210 on_boundary = true;
211 }
212
213 // Not on a boundary
214 if (!on_at_least_one_block || !on_boundary)
215 continue;
216
217 if (!_from_blocks.empty() && !inBlocks(_from_blocks, from_mesh, node))
218 continue;
219
220 if (!_from_boundaries.empty() && !onBoundaries(_from_boundaries, from_mesh, node))
221 continue;
222
223 // Handle the various source mesh divisions behaviors
224 // NOTE: This could be more efficient, as instead of rejecting points in the
225 // wrong division, we could just be adding them to the tree for the right division
226 if (!_from_mesh_divisions.empty())
227 {
228 const auto tree_division_index = i_source % getNumDivisions();
229 const auto node_div_index = _from_mesh_divisions[i_from]->divisionIndex(*node);
230
231 // Spatial restriction is always active
232 if (node_div_index == MooseMeshDivision::INVALID_DIVISION_INDEX)
233 continue;
234 // We fill one tree per division index for matching subapp index or division index. We
235 // only accept source data from the division index
241 tree_division_index != node_div_index)
242 continue;
243 }
244
245 // Transformed node is in the reference space, as is the _nearest_positions_obj
246 const auto transformed_node = (*_from_transforms[getGlobalSourceAppIndex(i_from)])(*node);
247
248 // Only add to the KDTree nodes that are closest to the 'position'
249 // When querying values at a target point, the KDTree associated to the closest
250 // position to the target point is queried
251 // We do not need to check the positions when using nearest app as we will assume
252 // (somewhat incorrectly) that all the points in each subapp are closer to that subapp
253 // than to any other
255 !closestToPosition(i_pos, transformed_node))
256 continue;
257
258 _local_points[i_source].push_back(transformed_node);
259
260 // Evaluate the functor on the boundary node
261 Moose::NodeArg node_arg = {node, &from_blocks};
263 _local_values[i_source].push_back((*functor)(node_arg, time_arg));
264 }
265 // Nearest-element option
266 // We also use this for 'evaluate_oob', which will influence the distance found and used to
267 // select the nearest value from out of bounds evaluations. It will not influence the result
268 // of the evaluation
269 else
270 for (const auto & elem : from_mesh.getMesh().local_element_ptr_range())
271 {
272 // No way to check number of dofs for a functor
273 if (!functor->hasBlocks(elem->subdomain_id()))
274 continue;
275
276 // Make sure sure it is at a boundary, for either the mesh or a functor
277 bool at_a_boundary = false;
278 for (const auto side : elem->side_index_range())
279 {
280 // Boundary of the mesh
281 if (!elem->neighbor_ptr(side))
282 {
283 at_a_boundary = true;
284 break;
285 }
286 // Boundary of the domain of definition of the functor
287 else if (!functor->hasBlocks(elem->neighbor_ptr(side)->subdomain_id()))
288 {
289 at_a_boundary = true;
290 break;
291 }
292 }
293 // Non boundary elements are not relevant as we can just evaluate the functor
294 if (!at_a_boundary)
295 continue;
296
297 if (!_from_blocks.empty() && !inBlocks(_from_blocks, from_mesh, elem))
298 continue;
299
300 if (!_from_boundaries.empty() && !onBoundaries(_from_boundaries, from_mesh, elem))
301 continue;
302
303 // Handle the various source mesh divisions behaviors
304 // NOTE: This could be more efficient, as instead of rejecting points in the
305 // wrong division, we could just be adding them to the tree for the right division
306 if (!_from_mesh_divisions.empty())
307 {
308 const auto tree_division_index = i_source % getNumDivisions();
309 const auto node_div_index =
310 _from_mesh_divisions[i_from]->divisionIndex(elem->vertex_average());
311
312 // Spatial restriction is always active
313 if (node_div_index == MooseMeshDivision::INVALID_DIVISION_INDEX)
314 continue;
315 // We fill one tree per division index for matching subapp index or division index. We
316 // only accept source data from the division index
322 tree_division_index != node_div_index)
323 continue;
324 }
325
326 // Transformed centroid is in the reference space, as is the _nearest_positions_obj
327 const auto transformed_centroid =
328 (*_from_transforms[getGlobalSourceAppIndex(i_from)])(elem->vertex_average());
329
330 // Only add to the KDTree nodes that are closest to the 'position'
331 // When querying values at a target point, the KDTree associated to the closest
332 // position to the target point is queried
333 // We do not need to check the positions when using nearest app as we will assume
334 // (somewhat incorrectly) that all the points in each subapp are closer to that subapp
335 // than to any other
337 !closestToPosition(i_pos, transformed_centroid))
338 continue;
339
340 _local_points[i_source].push_back(transformed_centroid);
341
342 // Evaluate the functor on the boundary node
343 Moose::ElemArg elem_arg = {elem, /*sknewness*/ false};
345 _local_values[i_source].push_back((*functor)(elem_arg, time_arg));
346 }
347
348 max_leaf_size = std::max(max_leaf_size, from_mesh.getMaxLeafSize());
349 }
350
351 // Make a KDTree from the accumulated points data
352 std::shared_ptr<KDTree> _kd_tree =
353 std::make_shared<KDTree>(_local_points[i_source], max_leaf_size);
354 _local_kdtrees[i_source] = _kd_tree;
355 }
356}
357
358void
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)
363{
364 evaluateValues(var_index, incoming_points, outgoing_vals);
365}
366
367void
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)
372{
373 dof_id_type i_pt = 0;
374 std::set<const Elem *> elem_candidates;
375 const auto num_apps_per_tree = getNumAppsPerTree();
376
377 for (const auto & [pt, mesh_div] : incoming_points)
378 {
379 // Reset distance
380 outgoing_vals[i_pt].second = std::numeric_limits<Real>::max();
381 bool point_found = false;
382
383 // Loop on all sources: locate the point and evaluate the functor if it is in-domain.
384 // Extrapolation (all modes) is handled after this loop, only when no in-domain hit is found.
385 for (const auto i_source : make_range(_num_sources))
386 {
387 // Examine all restrictions for the point. This source (KDTree+values) could be ruled out
388 if (!checkRestrictionsForSource(pt, mesh_div, i_source))
389 continue;
390 // Note: because this transfer is intended for extrapolation,
391 // this will usually not restrict the source. The distance comparisons will be crucial
392
393 // Inner loop: when group_subapps is true, multiple apps contribute to the same source
394 // (one KD-tree per position). Mirror the structure of buildKDTrees.
395 for (const auto app_i : make_range(num_apps_per_tree))
396 {
397 const auto app_index = getAppIndex(i_source, app_i);
398
399 // Point locators and functor evaluation work in each app's local frame
400 const Point app_local_pt =
401 getPointInSourceAppFrame(pt, app_index, "Functor value evaluation");
402
403 // Retrieve the functor
404 const auto & functor = *_functors[app_index][var_index];
405
406 // Get the intersection of the functor and transfer source block restrictions
407 std::set<SubdomainID> from_blocks;
408 for (const auto bl :
409 _from_blocks.size()
411 : _from_problems[app_index]->mesh().getMesh().get_mesh_subdomains())
412 if (functor.hasBlocks(bl))
413 from_blocks.insert(bl);
414
415 // If in domain, use the functor evaluation at the point
416 // Locate the point and an element
417 // Clear the nearest candidates
418 elem_candidates.clear();
419 if (from_blocks.size())
420 (*_point_locators[app_index])(app_local_pt, elem_candidates, &from_blocks);
421 else
422 (*_point_locators[app_index])(app_local_pt, elem_candidates);
423 if (elem_candidates.size())
424 {
425 // Register conflict if any
426 if (point_found && _search_value_conflicts)
427 {
428 // In the nearest-position/app mode, we save conflicts in the reference frame
430 registerConflict(i_source, /*dof*/ 0, pt, 0, true);
431 else
432 registerConflict(i_source, 0, app_local_pt, 0, true);
433 }
434
435 // Average the result for now
436 // TODO: if we knew the functor were continuous, we could return earlier
437 Real value = 0;
438 unsigned int num_values = 0;
439 for (const auto elem : elem_candidates)
440 {
441 // Variables would hit a ghosting error; compare against the sub-app communicator rank,
442 // not the parent communicator rank - each sub-app runs in its own sub-communicator
443 // where ranks start at 0, regardless of the global rank of the owning process
444 if (_functor_is_variable[var_index] &&
445 elem->processor_id() != _from_problems[app_index]->processor_id())
446 continue;
447 // Avoid evaluating outside of element
448 if (!elem->contains_point(app_local_pt, libMesh::TOLERANCE * libMesh::TOLERANCE))
449 continue;
450 Moose::ElemPointArg elem_pt_arg = {elem, app_local_pt, /*correct skewness*/ false};
452 value += functor(elem_pt_arg, time_arg);
453 num_values++;
454 }
455 if (num_values == 0)
456 continue;
457
458 value /= num_values;
459 point_found = true;
460 outgoing_vals[i_pt] = {value, 0};
461 }
462 }
463 }
464
465 // Extrapolation: only reached when no in-domain functor evaluation was found.
466 // flat: return OutOfMeshValue; the base class post-transfer step handles
467 // any user-specified constant or nearest-node fill on the target mesh
468 // evaluate_oob: find the nearest boundary point via KD-tree, then evaluate the functor
469 // there (out-of-bounds evaluation with a nullptr element)
470 // nearest-node / nearest-elem: delegate to the shared KD-tree method on the base class,
471 // which also handles search_value_conflicts detection
472 if (!point_found)
473 {
474 if (_extrapolation_behavior == 0) /*flat*/
475 // The base class will take care of replacing the value
476 outgoing_vals[i_pt] = {GeneralFieldTransfer::OutOfMeshValue,
478
479 else if (_extrapolation_behavior == 1) /*evaluate_oob*/
480 for (const auto i_source : make_range(_num_sources))
481 {
482 if (!checkRestrictionsForSource(pt, mesh_div, i_source))
483 continue;
484
485 // TODO: Pre-allocate these two work arrays. They will be regularly resized by the
486 // searches
487 std::vector<std::size_t> return_index(_num_nearest_points);
488 std::vector<Real> return_dist_sqr(_num_nearest_points);
489
490 // KD-tree neighbor search uses global pt (KD-trees store global coords);
491 // functor evaluation needs the per-app local coordinate
492 const auto first_app = getAppIndex(i_source, 0);
493 const Point oob_local_pt =
494 getPointInSourceAppFrame(pt, first_app, "Out-of-bounds functor extrapolation");
495 const auto & functor = *_functors[first_app][var_index];
496
497 if (_local_kdtrees[i_source]->numberCandidatePoints())
498 {
499 point_found = true;
500 _local_kdtrees[i_source]->neighborSearch(
501 pt, _num_nearest_points, return_index, return_dist_sqr);
502 Real dist_sum = 0;
503 for (const auto index : return_index)
504 dist_sum += (_local_points[i_source][index] - pt).norm();
505
506 const auto new_distance = dist_sum / return_dist_sqr.size();
507 if (new_distance < outgoing_vals[i_pt].second)
508 {
509 Moose::ElemPointArg elem_pt_arg = {nullptr, oob_local_pt, /*correct skewness*/ false};
511 outgoing_vals[i_pt] = {functor(elem_pt_arg, time_arg), new_distance};
512 }
513 }
514 }
515 else if (_extrapolation_behavior == 2 /*nearest-node*/ ||
516 _extrapolation_behavior == 3 /*nearest-elem*/)
517 evaluateNearestNodeFromKDTrees(pt, mesh_div, outgoing_vals[i_pt], point_found);
518 else
519 mooseAssert(false,
520 "Unexpected extrapolation behavior '" << std::to_string(_extrapolation_behavior)
521 << "'");
522 }
523
524 // Move to next point
525 i_pt++;
526 }
527}
const ExecFlagType EXEC_TRANSFER
Definition Moose.C:58
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
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void suppressParameter(const std::string &name)
This method suppresses an inherited parameter so that it isn't required or valid in the derived class...
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void renameParam(const std::string &old_name, const std::string &new_name, const std::string &new_docstring)
Rename a parameter and provide a new documentation string.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
const std::string & name() const
Get the name of the class.
Definition MooseBase.h:103
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
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.
Definition MooseBase.h:205
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
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.
Definition MooseMesh.C:1239
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 &parameters)
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
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.
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 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()
@ FROM_MULTIAPP
Definition Transfer.h:71
@ TO_MULTIAPP
Definition Transfer.h:70
FEProblemBase & _fe_problem
Definition Transfer.h:100
MooseEnum _current_direction
Definition Transfer.h:109
MeshBase & mesh
unsigned int INVALID_DIVISION_INDEX
Invalid subdomain id to return when outside the mesh division.
@ POST_AUX
Definition MooseTypes.h:761
@ PRE_AUX
Definition MooseTypes.h:760
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.