https://mooseframework.inl.gov
MultiAppGeometricInterpolationTransfer.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 "DisplacedProblem.h"
14 #include "FEProblem.h"
15 #include "MooseMesh.h"
16 #include "MooseTypes.h"
17 #include "MooseVariableFE.h"
18 #include "MultiApp.h"
19 #include "MooseAppCoordTransform.h"
20 
21 #include "libmesh/parallel_algebra.h"
22 #include "libmesh/meshfree_interpolation.h"
23 #include "libmesh/system.h"
24 #include "libmesh/radial_basis_interpolation.h"
25 
26 using namespace libMesh;
27 
30  MultiAppInterpolationTransfer,
31  "12/31/2023 24:00",
33 
36 {
38  params.addClassDescription(
39  "Transfers the value to the target domain from a combination/interpolation of the values on "
40  "the nearest nodes in the source domain, using coefficients based on the distance to each "
41  "node.");
42  params.addParam<unsigned int>(
43  "num_points", 3, "The number of nearest points to use for interpolation.");
44  params.addParam<Real>(
45  "power", 2, "The polynomial power to use for calculation of the decay in the interpolation.");
46 
47  MooseEnum interp_type("inverse_distance radial_basis", "inverse_distance");
48  params.addParam<MooseEnum>("interp_type", interp_type, "The algorithm to use for interpolation.");
49 
50  params.addParam<Real>("radius",
51  -1,
52  "Radius to use for radial_basis interpolation. If negative "
53  "then the radius is taken as the max distance between "
54  "points.");
55  params.addParam<Real>(
56  "shrink_gap_width",
57  0,
58  "gap width with which we want to temporarily shrink mesh in transfering solution");
59 
60  MooseEnum shrink_type("SOURCE TARGET", "SOURCE");
61  params.addParam<MooseEnum>("shrink_mesh", shrink_type, "Which mesh we want to shrink");
62 
63  params.addParam<std::vector<SubdomainName>>(
64  "exclude_gap_blocks",
65  {},
66  "Gap subdomains we want to exclude when constructing/using virtually translated points");
67 
68  params.addParam<Real>("distance_tol",
69  1e-10,
70  "If the distance between two points is smaller than distance_tol, two "
71  "points will be considered as identical");
72 
73  return params;
74 }
75 
77  const InputParameters & parameters)
78  : MultiAppConservativeTransfer(parameters),
79  _num_points(getParam<unsigned int>("num_points")),
80  _power(getParam<Real>("power")),
81  _interp_type(getParam<MooseEnum>("interp_type")),
82  _radius(getParam<Real>("radius")),
83  _shrink_gap_width(getParam<Real>("shrink_gap_width")),
84  _shrink_mesh(getParam<MooseEnum>("shrink_mesh")),
85  _exclude_gap_blocks(getParam<std::vector<SubdomainName>>("exclude_gap_blocks")),
86  _distance_tol(getParam<Real>("distance_tol"))
87 {
88  // This transfer does not work with DistributedMesh
89  _fe_problem.mesh().errorIfDistributedMesh("MultiAppGeometricInterpolationTransfer");
90 
91  if (_to_var_names.size() != 1)
92  paramError("variable", " Support single to-variable only ");
93 
94  if (_from_var_names.size() != 1)
95  paramError("source_variable", " Support single from-variable only ");
96 }
97 
98 void
100  const Node & node,
101  std::set<subdomain_id_type> & subdomainids)
102 {
103  // We need this map to figure out to which subdomains a given mesh point is attached
104  // We can not make mesh const here because we may need to create a node-to-elems map
105  // if it does not exists
106  auto & node_to_elem = mesh.nodeToElemMap();
107  auto node_to_elem_pair = node_to_elem.find(node.id());
108 
109  if (node_to_elem_pair == node_to_elem.end())
110  mooseError("Can not find elements for node ", node.id());
111 
112  subdomainids.clear();
113  // Add all subdomain IDs that are attached to node
114  for (auto element : node_to_elem_pair->second)
115  {
116  auto & elem = mesh.getMesh().elem_ref(element);
117  auto subdomain = elem.subdomain_id();
118 
119  subdomainids.insert(subdomain);
120  }
121 }
122 
123 void
125  FEProblemBase & from_problem,
126  const MooseVariableFieldBase & from_var,
127  const MultiAppCoordTransform & from_app_transform,
128  std::unique_ptr<InverseDistanceInterpolation<LIBMESH_DIM>> & idi)
129 {
130  auto & from_moose_mesh = from_problem.mesh(_displaced_source_mesh);
131  const auto & from_mesh = from_moose_mesh.getMesh();
132 
133  // Moose system
134  const SystemBase & from_system_base = from_var.sys();
135  // libmesh system
136  const System & from_sys = from_system_base.system();
137 
138  // System number and var number
139  auto from_sys_num = from_sys.number();
140  auto from_var_num = from_sys.variable_number(from_var.name());
141 
142  // Check FE type so we can figure out how to sample points
143  const auto & fe_type = from_sys.variable_type(from_var_num);
144  bool from_is_constant = fe_type.order == CONSTANT;
145  bool from_is_nodal = fe_type.family == LAGRANGE;
146 
147  // Currently, for an elemental variable, we support the constant and first order
148  if (fe_type.order > FIRST && !from_is_nodal)
149  mooseError("We don't currently support second order or higher elemental variable ");
150 
151  // Containers for points and values
152  // We later will push data into these containers
153  std::vector<Point> & src_pts(idi->get_source_points());
154  std::vector<Number> & src_vals(idi->get_source_vals());
155 
156  // How much we want to translate mesh if users ask
157  std::unordered_map<dof_id_type, Point> from_tranforms;
158  std::set<subdomain_id_type> exclude_block_ids;
159  if (_shrink_gap_width > 0 && _shrink_mesh == "source")
160  {
161  computeTransformation(from_moose_mesh, from_tranforms);
162  auto exclude_subdomainids = from_moose_mesh.getSubdomainIDs(_exclude_gap_blocks);
163  exclude_block_ids.insert(exclude_subdomainids.begin(), exclude_subdomainids.end());
164  }
165 
166  // The solution from the system with which the from_var is associated
167  const NumericVector<Number> & from_solution = *from_sys.solution;
168 
169  std::set<subdomain_id_type> subdomainids;
170  std::vector<subdomain_id_type> include_block_ids;
171  if (from_is_nodal)
172  {
173  for (const auto * const from_node : from_mesh.local_node_ptr_range())
174  {
175  // Assuming LAGRANGE!
176  if (from_node->n_comp(from_sys_num, from_var_num) == 0)
177  continue;
178 
179  Point translate(0);
180 
181  if (from_tranforms.size() > 0)
182  {
183  subdomainIDsNode(const_cast<MooseMesh &>(from_moose_mesh), *from_node, subdomainids);
184  // Check if node is excluded
185  // Node will be excluded if it is in the interior of excluded subdomains
186  include_block_ids.clear();
187  include_block_ids.resize(std::max(subdomainids.size(), exclude_block_ids.size()));
188  auto it = std::set_difference(subdomainids.begin(),
189  subdomainids.end(),
190  exclude_block_ids.begin(),
191  exclude_block_ids.end(),
192  include_block_ids.begin());
193 
194  include_block_ids.resize(it - include_block_ids.begin());
195  // Node is not excluded
196  if (include_block_ids.size())
197  translate = from_tranforms[*include_block_ids.begin()];
198  else
199  continue;
200  }
201 
202  // Push value and point to KDTree
203  dof_id_type from_dof = from_node->dof_number(from_sys_num, from_var_num, 0);
204  src_vals.push_back(from_solution(from_dof));
205  src_pts.push_back(from_app_transform(*from_node) + translate);
206  }
207  }
208  else
209  {
210  std::vector<Point> points;
211  for (const auto * const from_elem :
212  as_range(from_mesh.local_elements_begin(), from_mesh.local_elements_end()))
213  {
214  // Skip this element if the variable has no dofs at it.
215  if (from_elem->n_dofs(from_sys_num, from_var_num) < 1)
216  continue;
217 
218  points.clear();
219  if (from_is_constant)
220  points.push_back(from_elem->vertex_average());
221  else
222  for (const auto & node : from_elem->node_ref_range())
223  points.push_back(node);
224 
225  unsigned int n_comp = from_elem->n_comp(from_sys_num, from_var_num);
226  auto n_points = points.size();
227  // We assume each point corresponds to one component of elemental variable
228  if (n_points != n_comp)
229  mooseError(" Number of points ",
230  n_points,
231  " does not equal to number of variable components ",
232  n_comp);
233 
234  unsigned int offset = 0;
235 
236  Point translate(0);
237 
238  if (from_tranforms.size() > 0)
239  {
240  auto subdomain = from_elem->subdomain_id();
241 
242  if (subdomain == Moose::INVALID_BLOCK_ID)
243  mooseError("subdomain id does not make sense", subdomain);
244 
245  // subdomain is not excluded
246  if (exclude_block_ids.find(subdomain) == exclude_block_ids.end())
247  translate = from_tranforms[subdomain];
248  else
249  continue;
250  }
251 
252  for (const auto & point : points)
253  {
254  dof_id_type from_dof = from_elem->dof_number(from_sys_num, from_var_num, offset++);
255  src_vals.push_back(from_solution(from_dof));
256  src_pts.push_back(from_app_transform(point) + translate);
257  }
258  }
259  }
260 }
261 
262 void
264  FEProblemBase & to_problem,
265  MooseVariableFieldBase & to_var,
266  NumericVector<Real> & to_solution,
267  const MultiAppCoordTransform & to_app_transform,
268  const std::unique_ptr<InverseDistanceInterpolation<LIBMESH_DIM>> & idi)
269 {
270  // Moose system
271  SystemBase & to_system_base = to_var.sys();
272  // libmesh system
273  System & to_sys = to_system_base.system();
274 
275  // System number and var number
276  auto to_sys_num = to_sys.number();
277  auto to_var_num = to_sys.variable_number(to_var.name());
278 
279  const MooseMesh & to_moose_mesh = to_problem.mesh(_displaced_target_mesh);
280  const MeshBase & to_mesh = to_moose_mesh.getMesh();
281 
282  // Compute transform info
283  std::unordered_map<dof_id_type, Point> to_tranforms;
284  std::set<subdomain_id_type> exclude_block_ids;
285  if (_shrink_gap_width > 0 && _shrink_mesh == "target")
286  {
287  computeTransformation(to_moose_mesh, to_tranforms);
288  auto exclude_subdomainids = to_moose_mesh.getSubdomainIDs(_exclude_gap_blocks);
289  exclude_block_ids.insert(exclude_subdomainids.begin(), exclude_subdomainids.end());
290  }
291 
292  const auto & to_fe_type = to_sys.variable_type(to_var_num);
293  bool to_is_constant = to_fe_type.order == CONSTANT;
294  bool to_is_nodal = to_fe_type.family == LAGRANGE;
295 
296  if (to_fe_type.order > FIRST && !to_is_nodal)
297  mooseError("We don't currently support second order or higher elemental variable ");
298 
299  std::set<subdomain_id_type> subdomainids;
300  std::vector<subdomain_id_type> include_block_ids;
301  std::vector<Point> pts;
302  std::vector<Number> vals;
303  if (to_is_nodal)
304  {
305  for (const auto * const node : to_mesh.local_node_ptr_range())
306  {
307  if (node->n_dofs(to_sys_num, to_var_num) <= 0) // If this variable has dofs at this node
308  continue;
309 
310  Point translate(0);
311  if (to_tranforms.size() > 0)
312  {
313  subdomainIDsNode(const_cast<MooseMesh &>(to_moose_mesh), *node, subdomainids);
314  // Check if node is excluded
315  // Node will be excluded if it is in the interior of excluded subdomains
316  include_block_ids.clear();
317  include_block_ids.resize(std::max(subdomainids.size(), exclude_block_ids.size()));
318  auto it = std::set_difference(subdomainids.begin(),
319  subdomainids.end(),
320  exclude_block_ids.begin(),
321  exclude_block_ids.end(),
322  include_block_ids.begin());
323  include_block_ids.resize(it - include_block_ids.begin());
324  if (include_block_ids.size())
325  translate = to_tranforms[*include_block_ids.begin()];
326  else
327  continue;
328  }
329 
330  pts.clear();
331  pts.push_back(to_app_transform(*node) + translate);
332  vals.resize(1);
333 
334  idi->interpolate_field_data({_to_var_name}, pts, vals);
335  dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0);
336  to_solution.set(dof, vals.front());
337  }
338  }
339  else // Elemental
340  {
341  std::vector<Point> points;
342  for (const auto * const elem :
343  as_range(to_mesh.local_elements_begin(), to_mesh.local_elements_end()))
344  {
345  // Skip this element if the variable has no dofs at it.
346  if (elem->n_dofs(to_sys_num, to_var_num) < 1)
347  continue;
348 
349  points.clear();
350  if (to_is_constant)
351  points.push_back(elem->vertex_average());
352  else
353  for (const auto & node : elem->node_ref_range())
354  points.push_back(node);
355 
356  auto n_points = points.size();
357  unsigned int n_comp = elem->n_comp(to_sys_num, to_var_num);
358  // We assume each point corresponds to one component of elemental variable
359  if (n_points != n_comp)
360  mooseError(" Number of points ",
361  n_points,
362  " does not equal to number of variable components ",
363  n_comp);
364 
365  Point translate(0);
366 
367  if (to_tranforms.size() > 0)
368  {
369  auto subdomain = elem->subdomain_id();
370 
371  if (subdomain == Moose::INVALID_BLOCK_ID)
372  mooseError("subdomain id does not make sense", subdomain);
373 
374  if (exclude_block_ids.find(subdomain) == exclude_block_ids.end())
375  translate = to_tranforms[subdomain];
376  else
377  continue;
378  }
379 
380  unsigned int offset = 0;
381  for (const auto & point : points)
382  {
383  pts.clear();
384  pts.push_back(to_app_transform(point) + translate);
385  vals.resize(1);
386 
387  idi->interpolate_field_data({_to_var_name}, pts, vals);
388  dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, offset++);
389  to_solution.set(dof, vals.front());
390  } // point
391  } // auto elem
392  } // else
393 
394  to_solution.close();
395  to_sys.update();
396 }
397 
398 void
400 {
401  TIME_SECTION("MultiAppGeometricInterpolationTransfer::execute()",
402  5,
403  "Transferring variables based on node interpolation");
404 
405  const FEProblemBase & fe_problem =
406  hasFromMultiApp() ? getFromMultiApp()->problemBase() : getToMultiApp()->problemBase();
407  std::unique_ptr<InverseDistanceInterpolation<LIBMESH_DIM>> idi;
408  switch (_interp_type)
409  {
410  case 0:
411  idi = std::make_unique<InverseDistanceInterpolation<LIBMESH_DIM>>(
412  fe_problem.comm(), _num_points, _power);
413  break;
414  case 1:
415  idi = std::make_unique<RadialBasisInterpolation<LIBMESH_DIM>>(fe_problem.comm(), _radius);
416  break;
417  default:
418  mooseError("Unknown interpolation type!");
419  }
420 
421  idi->set_field_variables({_to_var_name});
422 
423  switch (_current_direction)
424  {
425  case TO_MULTIAPP:
426  {
427  FEProblemBase & from_problem = getToMultiApp()->problemBase();
428  const auto & from_var = from_problem.getVariable(
430 
431  mooseAssert(_from_transforms.size() == 1, "This should be size 1");
432  fillSourceInterpolationPoints(from_problem, from_var, *_from_transforms[0], idi);
433 
434  // We have only set local values - prepare for use by gathering remote gata
435  idi->prepare_for_use();
436 
437  for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++)
438  {
439  if (getToMultiApp()->hasLocalApp(i))
440  {
441  auto & to_problem = getToMultiApp()->appProblemBase(i);
442  Moose::ScopedCommSwapper swapper(to_problem.comm().get());
443  auto & to_var = to_problem.getVariable(0,
444  _to_var_name,
447 
448  auto & to_solution = getToMultiApp()->appTransferVector(i, _to_var_name);
449 
450  interpolateTargetPoints(to_problem, to_var, to_solution, *_to_transforms[i], idi);
451  }
452  }
453 
454  break;
455  }
456 
457  case FROM_MULTIAPP:
458  {
459  for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++)
460  {
461  if (getFromMultiApp()->hasLocalApp(i))
462  {
463  auto & from_problem = getFromMultiApp()->appProblemBase(i);
464  Moose::ScopedCommSwapper swapper(from_problem.comm().get());
465  const auto & from_var = from_problem.getVariable(0,
469 
470  fillSourceInterpolationPoints(from_problem, from_var, *_from_transforms[i], idi);
471  }
472  }
473 
474  idi->prepare_for_use();
475 
476  FEProblemBase & to_problem = getFromMultiApp()->problemBase();
477  MooseVariableFieldBase & to_var = to_problem.getVariable(
479 
480  auto & to_solution = *to_var.sys().system().solution;
481 
482  mooseAssert(_to_transforms.size() == 1, "This should be size 1");
483  interpolateTargetPoints(to_problem, to_var, to_solution, *_to_transforms[0], idi);
484 
485  break;
486  }
487  default:
488  {
489  mooseError("Unsupported transfer direction ", _current_direction);
490  break;
491  }
492  }
493 }
494 
495 void
497  const MooseMesh & mesh, std::unordered_map<dof_id_type, Point> & transformation)
498 {
499  auto & libmesh_mesh = mesh.getMesh();
500 
501  auto & subdomainids = mesh.meshSubdomains();
502 
503  subdomain_id_type max_subdomain_id = 0;
504 
505  // max_subdomain_id will be used to represent the center of the entire domain
506  for (auto subdomain_id : subdomainids)
507  {
508  max_subdomain_id = max_subdomain_id > subdomain_id ? max_subdomain_id : subdomain_id;
509  }
510 
511  max_subdomain_id += 1;
512 
513  std::unordered_map<dof_id_type, Point> subdomain_centers;
514  std::unordered_map<dof_id_type, dof_id_type> nelems;
515 
516  for (auto & elem :
517  as_range(libmesh_mesh.local_elements_begin(), libmesh_mesh.local_elements_end()))
518  {
519  // Compute center of the entire domain
520  subdomain_centers[max_subdomain_id] += elem->vertex_average();
521  nelems[max_subdomain_id] += 1;
522 
523  auto subdomain = elem->subdomain_id();
524 
525  if (subdomain == Moose::INVALID_BLOCK_ID)
526  mooseError("block is invalid");
527 
528  // Centers for subdomains
529  subdomain_centers[subdomain] += elem->vertex_average();
530 
531  nelems[subdomain] += 1;
532  }
533 
534  comm().sum(subdomain_centers);
535 
536  comm().sum(nelems);
537 
538  subdomain_centers[max_subdomain_id] /= nelems[max_subdomain_id];
539 
540  for (auto subdomain_id : subdomainids)
541  {
542  subdomain_centers[subdomain_id] /= nelems[subdomain_id];
543  }
544 
545  // Compute unit vectors representing directions in which we want to shrink mesh
546  // The unit vectors is scaled by 'shrink_gap_width'
547  transformation.clear();
548  for (auto subdomain_id : subdomainids)
549  {
550  transformation[subdomain_id] =
551  subdomain_centers[max_subdomain_id] - subdomain_centers[subdomain_id];
552 
553  auto norm = transformation[subdomain_id].norm();
554 
555  // The current subdomain is the center of the entire domain,
556  // then we do not move this subdomain
557  if (norm > _distance_tol)
558  transformation[subdomain_id] /= norm;
559 
560  transformation[subdomain_id] *= _shrink_gap_width;
561  }
562 }
LAGRANGE
std::vector< std::unique_ptr< MultiAppCoordTransform > > _to_transforms
void interpolateTargetPoints(FEProblemBase &to_problem, MooseVariableFieldBase &to_var, NumericVector< Real > &to_solution, const MultiAppCoordTransform &to_app_transform, const std::unique_ptr< libMesh::InverseDistanceInterpolation< Moose::dim >> &idi)
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
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:435
MooseEnum _current_direction
Definition: Transfer.h:106
FIRST
Interpolate variable values using geometry/mesh-based coefficients.
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
const std::vector< VariableName > _from_var_names
Name of variables transferring from.
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & comm() const
FEProblemBase & _fe_problem
Definition: Transfer.h:97
OrderWrapper order
const std::shared_ptr< MultiApp > getToMultiApp() const
Get the MultiApp to transfer data to.
This class provides an interface for common operations on field variables of both FE and FV types wit...
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
Base class for a system (of equations)
Definition: SystemBase.h:84
bool hasFromMultiApp() const
Whether the transfer owns a non-null from_multi_app.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
std::vector< SubdomainID > getSubdomainIDs(const std::vector< SubdomainName > &subdomain_names) const
Get the associated subdomainIDs for the subdomain names that are passed in.
Definition: MooseMesh.C:1737
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const override
Returns the variable reference for requested variable which must be of the expected_var_type (Nonline...
auto max(const L &left, const R &right)
unsigned int variable_number(std::string_view var) const
bool _displaced_target_mesh
True if displaced mesh is used for the target mesh, otherwise false.
const SubdomainID INVALID_BLOCK_ID
Definition: MooseTypes.C:20
void errorIfDistributedMesh(std::string name) const
Generate a unified error message if the underlying libMesh mesh is a DistributedMesh.
Definition: MooseMesh.C:3617
CONSTANT
unsigned int number() const
registerMooseObjectRenamed("MooseApp", MultiAppInterpolationTransfer, "12/31/2023 24:00", MultiAppGeometricInterpolationTransfer)
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:99
dof_id_type id() const
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:3448
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
const std::vector< AuxVariableName > _to_var_names
Name of variables transferring to.
std::unique_ptr< NumericVector< Number > > solution
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:88
registerMooseObject("MooseApp", MultiAppGeometricInterpolationTransfer)
void computeTransformation(const MooseMesh &mesh, std::unordered_map< dof_id_type, Point > &transformation)
Transfers variables on possibly different meshes while conserving a user defined property (Postproces...
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
auto norm(const T &a) -> decltype(std::abs(a))
void translate(MeshBase &mesh, const Real xt=0., const Real yt=0., const Real zt=0.)
virtual void close()=0
void fillSourceInterpolationPoints(FEProblemBase &from_problem, const MooseVariableFieldBase &from_var, const MultiAppCoordTransform &from_app_transform, std::unique_ptr< libMesh::InverseDistanceInterpolation< Moose::dim >> &idi)
virtual void update()
const FEType & variable_type(const unsigned int i) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
subdomain_id_type subdomain_id() const
virtual const Elem & elem_ref(const dof_id_type i) const
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
MultiAppGeometricInterpolationTransfer(const InputParameters &parameters)
virtual MooseMesh & mesh() override
bool _displaced_source_mesh
True if displaced mesh is used for the source mesh, otherwise false.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:267
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...
void subdomainIDsNode(MooseMesh &mesh, const Node &node, std::set< subdomain_id_type > &subdomainids)
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...
virtual void set(const numeric_index_type i, const T value)=0
SystemBase & sys()
Get the system this variable is part of.
void ErrorVector unsigned int
uint8_t dof_id_type
This class contains transformation information that only exists in a context in which there are multi...
virtual void execute() override
Execute the transfer.
VariableName _from_var_name
This values are used if a derived class only supports one variable.