https://mooseframework.inl.gov
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"
19 #include "MooseAppCoordTransform.h"
20 #include "MooseFunctorArguments.h"
21 
22 using namespace libMesh;
23 
25 
28 {
31  params.addClassDescription(
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");
74  if (_post_transfer_extrapolation != "none" && _extrapolation_behavior != "flat")
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 
84 void
86 {
88 
89  // Retrieve the functors
90  _functors.resize(_from_problems.size());
91  _functor_is_variable.resize(_functor_names.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 
109 void
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 
133 void
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 
145 void
147 {
149  const auto num_apps_per_tree = getNumAppsPerTree();
151  _local_points.resize(_num_sources);
152  _local_values.resize(_num_sources);
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().nodeToActiveSemilocalElemMap();
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
238  else if ((_from_mesh_division_behavior ==
239  MeshDivisionTransferUse::MATCH_DIVISION_INDEX ||
240  _to_mesh_division_behavior == MeshDivisionTransferUse::MATCH_DIVISION_INDEX ||
242  MeshDivisionTransferUse::MATCH_SUBAPP_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
319  else if ((_from_mesh_division_behavior ==
320  MeshDivisionTransferUse::MATCH_DIVISION_INDEX ||
321  _to_mesh_division_behavior == MeshDivisionTransferUse::MATCH_DIVISION_INDEX ||
323  MeshDivisionTransferUse::MATCH_SUBAPP_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 
360 void
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 
369 void
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()
412  ? _from_blocks
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 }
An interface for accessing Moose::Functors for systems that do not care about automatic differentiati...
void execute() override
Execute the transfer.
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.
const MooseEnum _post_transfer_extrapolation
How to post treat after the transfer.
const ExecFlagType EXEC_TRANSFER
Definition: Moose.C:55
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
unsigned int getNumDivisions() const
Number of divisions (nearest-positions or source mesh divisions) used when building KD-Trees...
const bool _group_subapps
Whether to group data when creating the nearest-point regions.
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.
Base class for working with KDTrees in transfers, whether for interpolation or extrapolation.
void computeNumSources()
Pre-compute the number of sources Number of KDTrees used to hold the locations and variable value dat...
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:467
MooseEnum _current_direction
Definition: Transfer.h:106
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.
MultiAppGeneralFieldFunctorTransfer(const InputParameters &parameters)
const std::map< dof_id_type, std::vector< dof_id_type > > & nodeToActiveSemilocalElemMap()
If not already created, creates a map from every node to all active semilocal elements to which they ...
Definition: MooseMesh.C:1229
void registerConflict(unsigned int problem, dof_id_type dof_id, Point p, Real dist, bool local)
Register a potential value conflict, e.g.
static constexpr Real TOLERANCE
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
Transfers a functor (can be variable, function, functor material property, spatial UO...
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...
virtual void execute() override
Execute the transfer.
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
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...
bool inBlocks(const std::set< SubdomainID > &blocks, const MooseMesh &mesh, const Elem *elem) const override
FEProblemBase & _fe_problem
Definition: Transfer.h:97
std::vector< const MeshDivision * > _from_mesh_divisions
Division of the origin mesh.
bool hasUserObject(const std::string &name) const
Check if there if a user object of given name.
A structure that is used to evaluate Moose functors at an arbitrary physical point contained within a...
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
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.
unsigned int _num_sources
Number of KD-Trees to create.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
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...
std::set< BoundaryID > _from_boundaries
Origin boundary(ies) restriction.
auto max(const L &left, const R &right)
void suppressParameter(const std::string &name)
This method suppresses an inherited parameter so that it isn&#39;t required or valid in the derived class...
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.
unsigned int getNumAppsPerTree() const
Number of applications which contributed nearest-locations to each KD-tree.
void buildKDTrees(const unsigned int var_index) override
virtual void prepareEvaluationOfInterpValues(const unsigned int var_index) override
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:103
const std::vector< MooseFunctorName > _functor_names
Names of the source functors.
void errorIfObjectExecutesOnTransferInSourceApp(const std::string &object_name) const
Error if executing this MooseObject on EXEC_TRANSFER in a source multiapp (from_multiapp, e.g.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
const std::vector< AuxVariableName > _to_var_names
Name of variables transferring to.
bool _search_value_conflicts
Whether to look for conflicts between origin points, multiple valid values for a target point...
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:54
A structure that is used to evaluate Moose functors logically at an element/cell center.
unsigned int getGlobalSourceAppIndex(unsigned int i_from) const
Return the global app index from the local index in the "from-multiapp" transfer direction.
std::vector< std::unique_ptr< libMesh::PointLocatorBase > > _point_locators
unsigned int INVALID_DIVISION_INDEX
Invalid subdomain id to return when outside the mesh division.
Definition: MeshDivision.h:28
const MooseEnum _extrapolation_behavior
How to determine values where the target mesh does not overlap the source mesh.
std::vector< std::vector< const Moose::Functor< Real > * > > _functors
Pointers to the source functors.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const MooseEnum & _to_mesh_division_behavior
How to use the target mesh divisions to restrict the transfer.
auto norm(const T &a)
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
IntRange< T > make_range(T beg, T end)
virtual MooseMesh & mesh() override
bool _displaced_source_mesh
True if displaced mesh is used for the source mesh, otherwise false.
std::set< SubdomainID > _from_blocks
Origin block(s) restriction.
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...
State argument for evaluating functors.
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...
static InputParameters validParams()
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...
registerMooseObject("MooseApp", MultiAppGeneralFieldFunctorTransfer)
virtual void prepareEvaluationOfInterpValues(const unsigned int var_index) override
unsigned int _num_nearest_points
Number of points to consider.
virtual void computeUserObjectByName(const ExecFlagType &type, const Moose::AuxGroup &group, const std::string &name)
Compute an user object with the given name.
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)
std::vector< bool > _functor_is_variable
Whether the functor is a variable.
std::vector< std::vector< Real > > _local_values
Values of the variable being transferred at all the points in _local_points.
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:215
bool onBoundaries(const std::set< BoundaryID > &boundaries, const MooseMesh &mesh, const Node *node) const
std::vector< std::vector< Point > > _local_points
All the nodes that meet the spatial restrictions in all the local source apps.
std::vector< FEProblemBase * > _from_problems
auto index_range(const T &sizable)
std::vector< std::shared_ptr< KDTree > > _local_kdtrees
KD-Trees for all the local source apps.
uint8_t dof_id_type
const MooseEnum & _from_mesh_division_behavior
How to use the origin mesh divisions to restrict the transfer.
const bool _use_nearest_app
Whether to keep track of the distance from the requested point to the app position.