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