www.mooseframework.org
MultiAppUserObjectTransfer.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 #include "MooseAppCoordTransform.h"
12 
13 #include <limits>
14 
15 // MOOSE includes
16 #include "DisplacedProblem.h"
17 #include "FEProblem.h"
18 #include "MooseMesh.h"
19 #include "MooseTypes.h"
20 #include "MooseVariableFE.h"
21 #include "MultiApp.h"
22 #include "UserObject.h"
23 
24 // libMesh
25 #include "libmesh/meshfree_interpolation.h"
26 #include "libmesh/system.h"
27 #include "libmesh/mesh_function.h"
28 #include "libmesh/mesh_tools.h"
29 
30 registerMooseObjectDeprecated("MooseApp", MultiAppUserObjectTransfer, "12/31/2024 24:00");
31 
34 {
36  // MultiAppUserObjectTransfer does not need source variable since it query values from user
37  // objects
38  params.set<std::vector<VariableName>>("source_variable") = std::vector<VariableName>{};
39  params.suppressParameter<std::vector<VariableName>>("source_variable");
40  params.addRequiredParam<UserObjectName>(
41  "user_object",
42  "The UserObject you want to transfer values from. Note: This might be a "
43  "UserObject from your MultiApp's input file!");
44  params.addParam<bool>("all_parent_nodes_contained_in_sub_app",
45  false,
46  "Set to true if every parent app node is mapped to a distinct point on one "
47  "of the subApps during a transfer from sub App to Parent App. If parent app"
48  " node cannot be found within bounding boxes of any of the subApps, an "
49  " error is generated.");
50  params.addDeprecatedParam<bool>(
51  "all_master_nodes_contained_in_sub_app",
52  "Set to true if every parent app node is mapped to a distinct point on one "
53  "of the subApps during a transfer from sub App to Parent App. If parent app"
54  " node cannot be found within bounding boxes of any of the subApps, an "
55  " error is generated.",
56  "all_master_nodes_contained_in_sub_app is deprecated. Use "
57  "all_parent_nodes_contained_in_sub_app");
58  params.addParam<bool>(
59  "skip_bounding_box_check",
60  false,
61  "Skip the check if the to_elem is within the bounding box of the from_app.");
62  params.addParam<std::vector<SubdomainName>>(
63  "block", "The block we are transferring to (if not specified, whole domain is used).");
64  params.addParam<std::vector<BoundaryName>>(
65  "boundary",
66  "The boundary we are transferring to (if not specified, whole domain is used unless 'block' "
67  "parameter is used).");
68 
69  params.addClassDescription(
70  "Samples a variable's value in the Parent app domain at the point where the MultiApp is and "
71  "copies that value into a post-processor in the MultiApp");
72 
73  params.addParam<bool>("nearest_sub_app",
74  false,
75  "When True, a from_multiapp transfer will work by finding the nearest "
76  "(using the `location`) sub-app and query that for the value to transfer");
77  return params;
78 }
79 
81  : MultiAppConservativeTransfer(parameters),
82  _user_object_name(getParam<UserObjectName>("user_object")),
83  _all_parent_nodes_contained_in_sub_app(
84  isParamValid("all_master_nodes_contained_in_sub_app")
85  ? getParam<bool>("all_master_nodes_contained_in_sub_app")
86  : getParam<bool>("all_parent_nodes_contained_in_sub_app")),
87  _skip_bbox_check(getParam<bool>("skip_bounding_box_check")),
88  _nearest_sub_app(getParam<bool>("nearest_sub_app"))
89 {
90  mooseDeprecated("MultiAppUserObjectTransfer is deprecated. Use "
91  "MultiAppGeneralFieldUserObjectTransfer instead and adapt the parameters");
92 
93  // This transfer does not work with DistributedMesh
94  _fe_problem.mesh().errorIfDistributedMesh("MultiAppUserObjectTransfer");
95 
96  if (_to_var_names.size() != 1)
97  paramError("variable", " Support single to-variable only ");
98 
99  if (_from_var_names.size() > 0)
100  paramError("source_variable",
101  " You should not provide any source variables since the transfer takes values from "
102  "user objects ");
103 
104  if (isParamValid("block") && isParamValid("boundary"))
105  mooseError(name(), ": Transfer can be either block- or boundary-restricted. Not both.");
106 
107  if (isParamValid("to_multi_app") && isParamValid("from_multi_app") &&
109  paramError("to_multi_app",
110  "Sibling multiapp transfer has not been implemented for this transfer.");
111 }
112 
113 void
115 {
116  TIME_SECTION(
117  "MultiAppUserObjectTransfer::execute()", 5, "Performing transfer with a user object");
118 
119  getAppInfo();
120 
121  switch (_current_direction)
122  {
123  case TO_MULTIAPP:
124  {
125  for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++)
126  {
127  if (getToMultiApp()->hasLocalApp(i))
128  {
130 
131  // Loop over the parent app nodes and set the value of the variable
132  System * to_sys = find_sys(getToMultiApp()->appProblemBase(i).es(), _to_var_name);
133 
134  unsigned int sys_num = to_sys->number();
135  unsigned int var_num = to_sys->variable_number(_to_var_name);
136 
137  NumericVector<Real> & solution = getToMultiApp()->appTransferVector(i, _to_var_name);
138 
139  MooseMesh * mesh = NULL;
140 
141  if (_displaced_target_mesh && getToMultiApp()->appProblemBase(i).getDisplacedProblem())
142  mesh = &getToMultiApp()->appProblemBase(i).getDisplacedProblem()->mesh();
143  else
144  mesh = &getToMultiApp()->appProblemBase(i).mesh();
145 
146  _blk_ids.clear();
147  _bnd_ids.clear();
148  if (isParamValid("block"))
149  {
150  const std::vector<SubdomainName> & blocks =
151  getParam<std::vector<SubdomainName>>("block");
152  for (const auto & b : blocks)
154  paramError("block", "The block '", b, "' was not found in the mesh");
155 
156  std::vector<SubdomainID> ids = mesh->getSubdomainIDs(blocks);
157  _blk_ids.insert(ids.begin(), ids.end());
158  }
159  else if (isParamValid("boundary"))
160  {
161  const std::vector<BoundaryName> & boundary_names =
162  getParam<std::vector<BoundaryName>>("boundary");
163  for (const auto & b : boundary_names)
165  paramError("boundary", "The boundary '", b, "' was not found in the mesh");
166 
167  std::vector<BoundaryID> ids = mesh->getBoundaryIDs(boundary_names, true);
168  _bnd_ids.insert(ids.begin(), ids.end());
169  }
170 
171  auto & fe_type = to_sys->variable_type(var_num);
172  bool is_constant = fe_type.order == CONSTANT;
173  bool is_nodal = fe_type.family == LAGRANGE;
174 
175  if (fe_type.order > FIRST && !is_nodal)
176  mooseError("We don't currently support second order or higher elemental variable ");
177 
178  const UserObject & user_object =
179  getToMultiApp()->problemBase().getUserObjectBase(_user_object_name);
180  mooseAssert(_from_transforms.size() == 1, "This should have size 1");
181  const auto & from_transform = *_from_transforms[0];
182  const auto & to_transform = *_to_transforms[i];
183 
184  if (is_nodal)
185  {
186  for (auto & node : mesh->getMesh().local_node_ptr_range())
187  {
188  if (blockRestricted() && !hasBlocks(mesh, node))
189  continue;
190 
191  if (boundaryRestricted() && !isBoundaryNode(mesh, node))
192  continue;
193 
194  if (node->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this node
195  {
196  // The zero only works for LAGRANGE!
197  dof_id_type dof = node->dof_number(sys_num, var_num, 0);
198 
199  swapper.forceSwap();
200  Real from_value =
201  user_object.spatialValue(from_transform.mapBack(to_transform(*node)));
202  swapper.forceSwap();
203 
204  solution.set(dof, from_value);
205  }
206  }
207  }
208  else // Elemental
209  {
210  std::vector<Point> points;
211  for (auto & elem : as_range(mesh->getMesh().local_elements_begin(),
212  mesh->getMesh().local_elements_end()))
213  {
214  if (blockRestricted() && !hasBlocks(elem))
215  continue;
216 
217  if (boundaryRestricted() && !isBoundaryElem(mesh, elem))
218  continue;
219 
220  // Skip this element if the variable has no dofs at it.
221  if (elem->n_dofs(sys_num, var_num) < 1)
222  continue;
223 
224  points.clear();
225  // grap sample points
226  // for constant shape function, we take the element centroid
227  if (is_constant)
228  points.push_back(elem->vertex_average());
229  // for higher order method, we take all nodes of element
230  // this works for the first order L2 Lagrange.
231  else
232  for (auto & node : elem->node_ref_range())
233  points.push_back(node);
234 
235  auto n_points = points.size();
236  unsigned int n_comp = elem->n_comp(sys_num, var_num);
237  // We assume each point corresponds to one component of elemental variable
238  if (n_points != n_comp)
239  mooseError(" Number of points ",
240  n_points,
241  " does not equal to number of variable components ",
242  n_comp);
243 
244  unsigned int offset = 0;
245  for (auto & point : points) // If this variable has dofs at this elem
246  {
247  dof_id_type dof = elem->dof_number(sys_num, var_num, offset++);
248 
249  swapper.forceSwap();
250  Real from_value =
251  user_object.spatialValue(from_transform.mapBack(to_transform(point)));
252  swapper.forceSwap();
253 
254  solution.set(dof, from_value);
255  }
256  }
257  }
258 
259  solution.close();
260  to_sys->update();
261  }
262  }
263 
264  break;
265  }
266  case FROM_MULTIAPP:
267  {
268  FEProblemBase & to_problem = getFromMultiApp()->problemBase();
269  mooseAssert(_to_transforms.size() == 1, "This should only be size one");
270  const auto & to_transform = *_to_transforms[0];
271  MooseVariableFEBase & to_var = to_problem.getVariable(
273  SystemBase & to_system_base = to_var.sys();
274 
275  System & to_sys = to_system_base.system();
276 
277  unsigned int to_sys_num = to_sys.number();
278 
279  // Only works with a serialized mesh to transfer to!
280  mooseAssert(to_sys.get_mesh().is_serial(),
281  "MultiAppUserObjectTransfer only works with ReplicatedMesh!");
282 
283  unsigned int to_var_num = to_sys.variable_number(to_var.name());
284 
285  // EquationSystems & to_es = to_sys.get_equation_systems();
286 
287  // Create a serialized version of the solution vector
288  NumericVector<Number> * to_solution = to_sys.solution.get();
289 
290  MooseMesh * to_mesh = NULL;
291 
292  if (_displaced_target_mesh && to_problem.getDisplacedProblem())
293  to_mesh = &to_problem.getDisplacedProblem()->mesh();
294  else
295  to_mesh = &to_problem.mesh();
296 
297  _blk_ids.clear();
298  _bnd_ids.clear();
299  if (isParamValid("block"))
300  {
301  const std::vector<SubdomainName> & blocks = getParam<std::vector<SubdomainName>>("block");
302  for (const auto & b : blocks)
303  if (!MooseMeshUtils::hasSubdomainName(*to_mesh, b))
304  paramError("block", "The block '", b, "' was not found in the mesh");
305 
306  std::vector<SubdomainID> ids = to_mesh->getSubdomainIDs(blocks);
307  _blk_ids.insert(ids.begin(), ids.end());
308  }
309  else if (isParamValid("boundary"))
310  {
311  const std::vector<BoundaryName> & boundary_names =
312  getParam<std::vector<BoundaryName>>("boundary");
313  for (const auto & b : boundary_names)
314  if (!MooseMeshUtils::hasBoundaryName(*to_mesh, b))
315  paramError("boundary", "The boundary '", b, "' was not found in the mesh");
316 
317  std::vector<BoundaryID> ids = to_mesh->getBoundaryIDs(boundary_names, true);
318  _bnd_ids.insert(ids.begin(), ids.end());
319  }
320 
321  auto & fe_type = to_sys.variable_type(to_var_num);
322  bool is_constant = fe_type.order == CONSTANT;
323  bool is_nodal = fe_type.family == LAGRANGE;
324 
325  if (fe_type.order > FIRST && !is_nodal)
326  mooseError("We don't currently support second order or higher elemental variable ");
327 
329  {
330  // check to see if parent app nodes or elements lies within any of the sub application
331  // bounding boxes
332  if (is_nodal)
333  {
334  for (auto & node : to_mesh->getMesh().node_ptr_range())
335  {
336  if (blockRestricted() && !hasBlocks(to_mesh, node))
337  continue;
338 
339  if (boundaryRestricted() && !isBoundaryNode(to_mesh, node))
340  continue;
341 
342  if (node->n_dofs(to_sys_num, to_var_num) > 0)
343  {
344  const auto transformed_node = to_transform(*node);
345 
346  unsigned int node_found_in_sub_app = 0;
347  for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++)
348  {
349  if (!getFromMultiApp()->hasLocalApp(i))
350  continue;
351 
352  BoundingBox app_box = getFromMultiApp()->getBoundingBox(
354 
355  if (app_box.contains_point(transformed_node))
356  ++node_found_in_sub_app;
357  }
358 
359  if (node_found_in_sub_app == 0)
360  mooseError("MultiAppUserObjectTransfer: Parent app node ",
361  transformed_node,
362  " not found within the bounding box of any of the sub applications.");
363  else if (node_found_in_sub_app > 1)
364  mooseError("MultiAppUserObjectTransfer: Parent app node ",
365  transformed_node,
366  " found within the bounding box of two or more sub applications.");
367  }
368  }
369  }
370  else // elemental
371  {
372  std::vector<Point> points;
373  for (auto & elem :
374  as_range(to_mesh->getMesh().elements_begin(), to_mesh->getMesh().elements_end()))
375  {
376  if (blockRestricted() && !hasBlocks(elem))
377  continue;
378 
379  if (boundaryRestricted() && !isBoundaryElem(to_mesh, elem))
380  continue;
381 
382  // Skip this element if the variable has no dofs at it.
383  if (elem->n_dofs(to_sys_num, to_var_num) < 1)
384  continue;
385 
386  points.clear();
387  // grap sample points
388  // for constant shape function, we take the element centroid
389  if (is_constant)
390  points.push_back(to_transform(elem->vertex_average()));
391  // for higher order method, we take all nodes of element
392  // this works for the first order L2 Lagrange.
393  else
394  for (auto & node : elem->node_ref_range())
395  points.push_back(to_transform(node));
396 
397  auto n_points = points.size();
398  unsigned int n_comp = elem->n_comp(to_sys_num, to_var_num);
399  // We assume each point corresponds to one component of elemental variable
400  if (n_points != n_comp)
401  mooseError(" Number of points ",
402  n_points,
403  " does not equal to number of variable components ",
404  n_comp);
405 
406  for (auto & point : points)
407  {
408  unsigned int elem_found_in_sub_app = 0;
409 
410  for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++)
411  {
412  if (!getFromMultiApp()->hasLocalApp(i))
413  continue;
414 
415  BoundingBox app_box = getFromMultiApp()->getBoundingBox(
417 
418  if (app_box.contains_point(point))
419  ++elem_found_in_sub_app;
420  }
421 
422  if (elem_found_in_sub_app == 0)
423  mooseError("MultiAppUserObjectTransfer: Parent app element with ",
424  n_points > 1 ? "node" : "centroid",
425  " at ",
426  point,
427  " not found within the bounding box of any of the sub applications.");
428 
429  else if (elem_found_in_sub_app > 1)
430  mooseError("MultiAppUserObjectTransfer: Parent app element with ",
431  n_points > 1 ? "node" : "centroid",
432  " at ",
433  point,
434  " found within the bounding box of two or more sub applications.");
435  }
436  }
437  }
438  }
439 
440  if (is_nodal)
441  {
442  for (auto & node : to_mesh->getMesh().node_ptr_range())
443  {
444  if (blockRestricted() && !hasBlocks(to_mesh, node))
445  continue;
446 
447  if (boundaryRestricted() && !isBoundaryNode(to_mesh, node))
448  continue;
449 
450  if (node->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this node
451  {
452  const auto transformed_node = to_transform(*node);
453  const auto sub_app = findSubAppToTransferFrom(transformed_node);
454 
455  // Check to see if a sub-app was found
456  if (sub_app == static_cast<unsigned int>(-1))
457  continue;
458 
459  const auto & from_transform = *_from_transforms[sub_app];
460  const auto & user_object = _multi_app->appUserObjectBase(sub_app, _user_object_name);
461 
462  dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0);
463 
464  Real from_value = 0;
465  {
467  from_value = user_object.spatialValue(from_transform.mapBack(transformed_node));
468  }
469 
470  if (from_value == std::numeric_limits<Real>::infinity())
471  mooseError("MultiAppUserObjectTransfer: Point corresponding to parent app node at (",
472  transformed_node,
473  ") not found in the sub application.");
474  to_solution->set(dof, from_value);
475  }
476  }
477  }
478  else // Elemental
479  {
480  std::vector<Point> points;
481  for (auto & elem :
482  as_range(to_mesh->getMesh().elements_begin(), to_mesh->getMesh().elements_end()))
483  {
484  if (blockRestricted() && !hasBlocks(elem))
485  continue;
486 
487  if (boundaryRestricted() && !isBoundaryElem(to_mesh, elem))
488  continue;
489 
490  // Skip this element if the variable has no dofs at it.
491  if (elem->n_dofs(to_sys_num, to_var_num) < 1)
492  continue;
493 
494  points.clear();
495  // grap sample points
496  // for constant shape function, we take the element centroid
497  if (is_constant)
498  points.push_back(to_transform(elem->vertex_average()));
499  // for higher order method, we take all nodes of element
500  // this works for the first order L2 Lagrange.
501  else
502  for (auto & node : elem->node_ref_range())
503  points.push_back(to_transform(node));
504 
505  auto n_points = points.size();
506  unsigned int n_comp = elem->n_comp(to_sys_num, to_var_num);
507  // We assume each point corresponds to one component of elemental variable
508  if (n_points != n_comp)
509  mooseError(" Number of points ",
510  n_points,
511  " does not equal to number of variable components ",
512  n_comp);
513 
514  unsigned int offset = 0;
515  for (auto & point : points) // If this variable has dofs at this elem
516  {
517  const auto sub_app = findSubAppToTransferFrom(point);
518 
519  // Check to see if a sub-app was found
520  if (sub_app == static_cast<unsigned int>(-1))
521  continue;
522 
523  const auto & from_transform = *_from_transforms[sub_app];
524  const auto & user_object =
525  getFromMultiApp()->appUserObjectBase(sub_app, _user_object_name);
526 
527  dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, offset++);
528 
529  Real from_value = 0;
530  {
532  from_value = user_object.spatialValue(from_transform.mapBack(point));
533  }
534 
535  if (from_value == std::numeric_limits<Real>::infinity())
536  mooseError("MultiAppUserObjectTransfer: Point corresponding to element's centroid (",
537  point,
538  ") not found in sub application.");
539 
540  to_solution->set(dof, from_value);
541  }
542  }
543  }
544 
545  to_solution->close();
546  to_sys.update();
547 
548  break;
549  }
550  }
551 
552  postExecute();
553 }
554 
555 bool
557 {
558  return !_blk_ids.empty();
559 }
560 
561 bool
563 {
564  return !_bnd_ids.empty();
565 }
566 
567 bool
569 {
570  return _blk_ids.find(elem->subdomain_id()) != _blk_ids.end();
571 }
572 
573 bool
574 MultiAppUserObjectTransfer::hasBlocks(const MooseMesh * mesh, const Node * node) const
575 {
576  const std::set<SubdomainID> & node_blk_ids = mesh->getNodeBlockIds(*node);
577  std::set<SubdomainID> u;
578  std::set_intersection(_blk_ids.begin(),
579  _blk_ids.end(),
580  node_blk_ids.begin(),
581  node_blk_ids.end(),
582  std::inserter(u, u.begin()));
583  return !u.empty();
584 }
585 
586 bool
587 MultiAppUserObjectTransfer::isBoundaryNode(const MooseMesh * mesh, const Node * node) const
588 {
589  for (auto & bid : _bnd_ids)
590  if (mesh->isBoundaryNode(node->id(), bid))
591  return true;
592  return false;
593 }
594 
595 bool
596 MultiAppUserObjectTransfer::isBoundaryElem(const MooseMesh * mesh, const Elem * elem) const
597 {
598  for (auto & bid : _bnd_ids)
599  if (mesh->isBoundaryElem(elem->id(), bid))
600  return true;
601  return false;
602 }
603 
604 unsigned int
606 {
607  // Just find the nearest app to this point
608  if (_nearest_sub_app)
609  {
610  unsigned int closest_app = 0;
611  Real closest_distance = std::numeric_limits<Real>::max();
612 
613  mooseAssert(_multi_app->numGlobalApps() > 0, "No Multiapps To Transfer From");
614 
615  for (unsigned int i = 0; i < _multi_app->numGlobalApps(); i++)
616  {
617  // Obtain the possibly transformed app position by querying the transform with the origin
618  const auto app_position = _multi_app->runningInPosition()
619  ? (*_from_transforms[i])(_multi_app->position(i))
620  : (*_from_transforms[i])(Point(0));
621 
622  auto distance = (p - app_position).norm();
623 
624  if (distance < closest_distance)
625  {
626  closest_app = i;
627  closest_distance = distance;
628  }
629  }
630 
631  // We can only get the value if we have this app
632  // otherwise - another processor will set it
633  if (_multi_app->hasLocalApp(closest_app))
634  return closest_app;
635  else
636  return -1;
637  }
638 
639  // Find the app that contains this point...
640 
641  // This loop counts _down_ so that it can preserve legacy behavior of the
642  // last sub-app "winning" to be able to set the value at this point
643  for (int i = _multi_app->numGlobalApps() - 1; i >= 0; i--)
644  {
645  if (!_multi_app->hasLocalApp(i))
646  continue;
647 
648  BoundingBox app_box =
649  _multi_app->getBoundingBox(i, _displaced_source_mesh, _from_transforms[i].get());
650 
651  if (_skip_bbox_check || app_box.contains_point(p))
652  return static_cast<unsigned int>(i);
653  }
654 
655  return -1;
656 }
LAGRANGE
std::vector< std::unique_ptr< MultiAppCoordTransform > > _to_transforms
bool hasBlocks(const Elem *elem) const
Check that element &#39;elem&#39; is part of the domain this transfer is restricted to.
bool isBoundaryElem(const MooseMesh *mesh, const Elem *elem) const
Check that the element belongs to boundary this transfer is restricted to.
static InputParameters validParams()
void addDeprecatedParam(const std::string &name, const T &value, const std::string &doc_string, const std::string &deprecation_message)
void mooseDeprecated(Args &&... args) const
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
bool hasBoundaryName(const MeshBase &input_mesh, const BoundaryName &name)
Whether a particular boundary name exists in the mesh.
const bool _all_parent_nodes_contained_in_sub_app
Boolean variable to generate error if every parent app node cannot be mapped to a subApp during from_...
MooseEnum _current_direction
Definition: Transfer.h:106
virtual void get(const std::vector< numeric_index_type > &index, Number *values) const
bool isBoundaryNode(const MooseMesh *mesh, const Node *node) const
Check that the node belongs to boundary this transfer is restricted to.
FIRST
virtual void execute() override
Execute the transfer.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
const std::vector< VariableName > _from_var_names
Name of variables transferring from.
MeshBase & mesh
const std::string & name() const override
Get the variable name.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & comm() const
virtual void postExecute()
Add some extra work if necessary after execute().
FEProblemBase & _fe_problem
Definition: Transfer.h:97
const bool _skip_bbox_check
whether to check the bounding box check or not
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...
Base class for a system (of equations)
Definition: SystemBase.h:84
std::shared_ptr< MultiApp > _multi_app
Deprecated class attribute for compatibility with the apps.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
Real distance(const Point &p)
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:56
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...
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)
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...
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
bool _displaced_target_mesh
True if displaced mesh is used for the target mesh, otherwise false.
void errorIfDistributedMesh(std::string name) const
Generate a unified error message if the underlying libMesh mesh is a DistributedMesh.
Definition: MooseMesh.C:3367
CONSTANT
void forceSwap()
Forcibly swap the currently swapped-out communicator back in to libmesh.
Definition: Moose.h:273
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:3198
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
std::set< SubdomainID > _blk_ids
Set of block ids this transfer is restricted to.
const std::vector< AuxVariableName > _to_var_names
Name of variables transferring to.
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:88
std::set< BoundaryID > _bnd_ids
Set of the boundary ids.
Transfers variables on possibly different meshes while conserving a user defined property (Postproces...
bool hasSubdomainName(MeshBase &input_mesh, const SubdomainName &name)
Whether a particular subdomain name exists in the mesh.
virtual System & system()=0
Get the reference to the libMesh system.
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 ...
auto norm(const T &a) -> decltype(std::abs(a))
virtual void close()=0
Loops over a target mesh and uses either node or element centroid location (based on the target varia...
const bool & _nearest_sub_app
Whether to utilize the nearest sub-app to transfer from.
virtual Real spatialValue(const Point &) const
Optional interface function for "evaluating" a UserObject at a spatial position.
Definition: UserObject.h:94
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
unsigned int findSubAppToTransferFrom(const Point &p)
Gets the UserObject to transfer from when transferring from_multiapp.
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
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.
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...
std::vector< BoundaryID > getBoundaryIDs(const Elem *const elem, const unsigned short int side) const
Returns a vector of boundary IDs for the requested element on the requested side. ...
Definition: MooseMesh.C:2719
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
std::vector< SubdomainID > getSubdomainIDs(const std::vector< SubdomainName > &subdomain_name) const
Get the associated subdomainIDs for the subdomain names that are passed in.
Definition: MooseMesh.C:1519
virtual void set(const numeric_index_type i, const Number value)=0
static System * find_sys(EquationSystems &es, const std::string &var_name)
Small helper function for finding the system containing the variable.
Definition: Transfer.C:89
MultiAppUserObjectTransfer(const InputParameters &parameters)
virtual void getAppInfo()
This method will fill information into the convenience member variables (_to_problems, _from_meshes, etc.)
SystemBase & sys()
Get the system this variable is part of.
Base class for user-specific data.
Definition: UserObject.h:39
registerMooseObjectDeprecated("MooseApp", MultiAppUserObjectTransfer, "12/31/2024 24:00")
uint8_t dof_id_type