https://mooseframework.inl.gov
MultiAppTransfer.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 
10 // MOOSE includes
11 #include "MultiAppTransfer.h"
12 #include "Transfer.h"
13 #include "MooseTypes.h"
14 #include "FEProblem.h"
15 #include "DisplacedProblem.h"
16 #include "MultiApp.h"
17 #include "MooseMesh.h"
18 
19 #include "libmesh/parallel_algebra.h"
20 #include "libmesh/mesh_tools.h"
21 
24 {
26  params.addDeprecatedParam<MultiAppName>("multi_app",
27  "The name of the MultiApp to transfer data with",
28  "Use to_multiapp & from_multiapp parameters now");
29  params.addParam<MultiAppName>("from_multi_app", "The name of the MultiApp to receive data from");
30  params.addParam<MultiAppName>("to_multi_app", "The name of the MultiApp to transfer the data to");
31 
32  // MultiAppTransfers by default will execute with their associated MultiApp. These flags will be
33  // added by FEProblemBase when the transfer is added.
34  ExecFlagEnum & exec_enum = params.set<ExecFlagEnum>("execute_on", true);
36  // Add the POST_ADAPTIVITY execution flag.
37 #ifdef LIBMESH_ENABLE_AMR
38  exec_enum.addAvailableFlags(EXEC_POST_ADAPTIVITY);
39 #endif
40  exec_enum = EXEC_SAME_AS_MULTIAPP;
41  params.setDocString("execute_on", exec_enum.getDocString());
42 
43  params.addParam<bool>(
44  "check_multiapp_execute_on",
45  true,
46  "When false the check between the multiapp and transfer execute on flags is not performed.");
47  params.addParam<bool>("displaced_source_mesh",
48  false,
49  "Whether or not to use the displaced mesh for the source mesh.");
50  params.addParam<bool>("displaced_target_mesh",
51  false,
52  "Whether or not to use the displaced mesh for the target mesh.");
54  return params;
55 }
56 
57 void
59 {
60  params.addRangeCheckedParam<Real>(
61  "bbox_factor",
62  1 + TOLERANCE,
63  "bbox_factor>0",
64  "Multiply bounding box width (in all directions) by the prescribed factor. Values less than "
65  "1 will shrink the bounding box; values greater than 1 will enlarge the bounding box. It is "
66  "generally not advised to ever shrink the bounding box. On the other hand it may be helpful "
67  "to enlarge the bounding box. Larger bounding boxes will lead to more accurate determination "
68  "of the closest node/element with the tradeoff of more communication.");
69 }
70 
71 void
73 {
74  params.addParam<bool>(
75  "skip_coordinate_collapsing",
76  true,
77  "Whether to skip coordinate collapsing (translation and rotation are still performed, only "
78  "XYZ, RZ etc collapsing is skipped) when performing mapping and inverse "
79  "mapping coordinate transformation operations. This parameter should only "
80  "be set by users who really know what they're doing.");
81  params.addParamNamesToGroup("skip_coordinate_collapsing", "Advanced");
82 }
83 
85  : Transfer(parameters),
86  _skip_coordinate_collapsing(getParam<bool>("skip_coordinate_collapsing")),
87  _displaced_source_mesh(getParam<bool>("displaced_source_mesh")),
88  _displaced_target_mesh(getParam<bool>("displaced_target_mesh")),
89  _bbox_factor(isParamValid("bbox_factor") ? getParam<Real>("bbox_factor") : 1)
90 {
91  // Get the multiapps from their names
92  if (!isParamValid("multi_app"))
93  {
94  if (isParamValid("from_multi_app"))
95  {
96  _from_multi_app = _fe_problem.getMultiApp(getParam<MultiAppName>("from_multi_app"));
98  }
99  if (isParamValid("to_multi_app"))
100  {
101  _to_multi_app = _fe_problem.getMultiApp(getParam<MultiAppName>("to_multi_app"));
103  }
104  if (!isParamValid("direction") && !isParamValid("from_multi_app") &&
105  !isParamValid("to_multi_app"))
106  mooseError("from_multi_app and/or to_multi_app must be specified");
107  }
108  else
109  {
110  // Check deprecated direction parameter
111  for (const auto & dir : _directions)
112  {
113  if (dir == FROM_MULTIAPP)
114  {
115  _from_multi_app = _fe_problem.getMultiApp(getParam<MultiAppName>("multi_app"));
117  }
118  else if (dir == TO_MULTIAPP)
119  {
120  _to_multi_app = _fe_problem.getMultiApp(getParam<MultiAppName>("multi_app"));
122  }
123  else
124  paramError("direction",
125  "BETWEN_MULTIAPP transfers should be specified using to/from_multi_app");
126  }
127  }
128 
129  if (getParam<bool>("check_multiapp_execute_on"))
131 
132  // Fill direction attributes, for backward compatibility but also convenience
133  if (!isParamValid("direction"))
134  {
136  _directions.setAdditionalValue("from_multiapp");
138  _directions.setAdditionalValue("to_multiapp");
140  _directions.setAdditionalValue("between_multiapp");
141 
142  // So it's available in the next constructors
143  _direction = _directions[0];
145  }
146 
147  // Handle deprecated parameters
148  if (parameters.isParamSetByUser("direction"))
149  {
150  if (!isParamValid("multi_app"))
151  paramError("direction",
152  "The deprecated 'direction' parameter is meant to be used in conjunction with the "
153  "'multi_app' parameter");
154  if (isParamValid("to_multi_app") || isParamValid("from_multi_app"))
155  paramError("direction",
156  "The deprecated 'direction' parameter is not meant to be used in conjunction with "
157  "the 'from_multi_app' or 'to_multi_app' parameters");
158  }
159 }
160 
161 void
163 {
165  if (getExecuteOnEnum() != _from_multi_app->getExecuteOnEnum())
166  mooseDoOnce(
167  mooseWarning("MultiAppTransfer execute_on flags do not match associated from_multi_app "
168  "execute_on flags"));
169 
171  if (getExecuteOnEnum() != _to_multi_app->getExecuteOnEnum())
172  mooseDoOnce(
173  mooseWarning("MultiAppTransfer execute_on flags do not match associated to_multi_app "
174  "execute_on flags"));
175 
176  // In the case of siblings transfer, the check will be looser
178  if (getExecuteOnEnum() != _from_multi_app->getExecuteOnEnum() &&
179  getExecuteOnEnum() != _to_multi_app->getExecuteOnEnum())
180  mooseDoOnce(
181  mooseWarning("MultiAppTransfer execute_on flags do not match associated to_multi_app "
182  "and from_multi_app execute_on flags"));
183 }
184 
185 void
186 MultiAppTransfer::variableIntegrityCheck(const AuxVariableName & var_name,
187  bool is_from_multiapp) const
188 {
189  bool variable_found = false;
190  bool has_an_app = false;
191 
192  // Check the from_multi_app for the variable
193  if (is_from_multiapp && _from_multi_app)
194  for (unsigned int i = 0; i < _from_multi_app->numGlobalApps(); i++)
195  if (_from_multi_app->hasLocalApp(i))
196  {
197  has_an_app = true;
198  if (_from_multi_app->appProblemBase(i).hasVariable(var_name))
199  variable_found = true;
200  }
201 
202  // Check the to_multi_app for the variable
203  if (!is_from_multiapp && _to_multi_app)
204  for (unsigned int i = 0; i < _to_multi_app->numGlobalApps(); i++)
205  if (_to_multi_app->hasLocalApp(i))
206  {
207  has_an_app = true;
208  if (_to_multi_app->appProblemBase(i).hasVariable(var_name))
209  variable_found = true;
210  }
211 
212  if (!variable_found && has_an_app)
213  mooseError("Cannot find variable ", var_name, " for ", name(), " Transfer");
214 }
215 
216 void
218 {
219  // Check for siblings transfer support
222 
223  getAppInfo();
224 
225  if (_from_multi_app)
226  _from_multi_app->addAssociatedTransfer(*this);
227  if (_to_multi_app)
228  _to_multi_app->addAssociatedTransfer(*this);
229 }
230 
231 void
233 {
234  // I would like to do all of this in initialSetup, but it will fail with
235  // multiapps that reset. A reset deletes and rebuilds the FEProblems so all
236  // of the pointers will be broken.
237 
238  // Clear the vectors since we've probably built them up from a previous call
239  _from_problems.clear();
240  _to_problems.clear();
241  _from_es.clear();
242  _to_es.clear();
243  _from_meshes.clear();
244  _to_meshes.clear();
245  _to_positions.clear();
246  _from_positions.clear();
247  _to_transforms.clear();
248  _from_transforms.clear();
249  // Clear this map since we build it from scratch every time we transfer
250  // Otherwise, this will cause two issues: 1) increasing memory usage
251  // for a simulation that requires many transfers, 2) producing wrong results
252  // when we do collective communication on this vector.
253  _to_local2global_map.clear();
254  _from_local2global_map.clear();
255 
256  // Build the vectors for to problems, from problems, and subapps positions.
258  {
259  _to_problems.push_back(&_from_multi_app->problemBase());
260  _to_positions.push_back(Point(0., 0., 0.));
262  }
263  else if (_current_direction == TO_MULTIAPP)
264  {
265  _from_problems.push_back(&_to_multi_app->problemBase());
266  _from_positions.push_back(Point(0., 0., 0.));
268  }
270  {
271  mooseAssert(&_from_multi_app->problemBase().coordTransform() ==
272  &_to_multi_app->problemBase().coordTransform(),
273  "I believe these should be the same. If not, then it will be difficult to define a "
274  "canonical reference frame.");
277  }
278 
279  // Build the from and to equation systems and mesh vectors.
280  for (unsigned int i = 0; i < _to_problems.size(); i++)
281  {
282  // TODO: Do I actually want es or displaced es?
283  _to_es.push_back(&_to_problems[i]->es());
284  if (_displaced_target_mesh && _to_problems[i]->getDisplacedProblem())
285  _to_meshes.push_back(&_to_problems[i]->getDisplacedProblem()->mesh());
286  else
287  _to_meshes.push_back(&_to_problems[i]->mesh());
288  }
289 
290  for (unsigned int i = 0; i < _from_problems.size(); i++)
291  {
292  _from_es.push_back(&_from_problems[i]->es());
293  if (_displaced_source_mesh && _from_problems[i]->getDisplacedProblem())
294  _from_meshes.push_back(&_from_problems[i]->getDisplacedProblem()->mesh());
295  else
296  _from_meshes.push_back(&_from_problems[i]->mesh());
297  }
298 
299  MooseAppCoordTransform::MinimalData from_app_transform_construction_data{};
300  if (_communicator.rank() == 0)
301  from_app_transform_construction_data =
303  ? _to_multi_app->problemBase().coordTransform().minimalDataDescription()
304  : _from_multi_app->appProblemBase(0).coordTransform().minimalDataDescription();
305  _communicator.broadcast(from_app_transform_construction_data);
307  std::make_unique<MooseAppCoordTransform>(from_app_transform_construction_data);
308 
309  MooseAppCoordTransform::MinimalData to_app_transform_construction_data{};
310  if (_communicator.rank() == 0)
311  to_app_transform_construction_data =
313  ? _from_multi_app->problemBase().coordTransform().minimalDataDescription()
314  : _to_multi_app->appProblemBase(0).coordTransform().minimalDataDescription();
315  _communicator.broadcast(to_app_transform_construction_data);
317  std::make_unique<MooseAppCoordTransform>(to_app_transform_construction_data);
318 
319  /*
320  * skip_coordinate_collapsing: whether to set the transform to skip coordinate collapsing
321  * (from XYZ to RZ for example)
322  * transforms: vector of transforms to add the new transforms to
323  * moose_app_transform: base for the new transform
324  * is_parent_app_transform: whether working on the transform for the parent app (this app, the
325  * one creating the transfer) or for child apps
326  * multiapp: pointer to the multiapp to obtain the position of the child apps
327  */
328  auto create_multiapp_transforms = [this](auto & transforms,
329  const auto & moose_app_transform,
330  const bool is_parent_app_transform,
331  const MultiApp * const multiapp = nullptr)
332  {
333  mooseAssert(is_parent_app_transform || multiapp,
334  "Coordinate transform must be created either for child app or parent app");
335  if (is_parent_app_transform)
336  {
337  transforms.push_back(std::make_unique<MultiAppCoordTransform>(moose_app_transform));
338  transforms.back()->skipCoordinateCollapsing(_skip_coordinate_collapsing);
339  // zero translation
340  }
341  else
342  {
343  mooseAssert(transforms.size() == 0, "transforms should not be initialized at this point");
344  for (const auto i : make_range(multiapp->numGlobalApps()))
345  {
346  transforms.push_back(std::make_unique<MultiAppCoordTransform>(moose_app_transform));
347  auto & transform = transforms[i];
348  transform->skipCoordinateCollapsing(_skip_coordinate_collapsing);
349  if (multiapp->usingPositions())
350  transform->setTranslationVector(multiapp->position(i));
351  }
352  }
353  };
354 
356  {
357  create_multiapp_transforms(
359  create_multiapp_transforms(_from_transforms, *_from_moose_app_transform, true);
360  }
362  {
363  create_multiapp_transforms(_to_transforms, *_to_moose_app_transform, true);
364  create_multiapp_transforms(
366  }
368  {
369  create_multiapp_transforms(
371  create_multiapp_transforms(
373  }
374 
375  auto check_transform_compatibility = [this](const MultiAppCoordTransform & transform)
376  {
377  if (transform.hasNonTranslationTransformation() && !usesMooseAppCoordTransform())
378  mooseWarning("Transfer '",
379  name(),
380  "' of type '",
381  type(),
382  "' has non-translation transformations but it does not implement coordinate "
383  "transformations using the 'MooseAppCoordTransform' class. Your data transfers "
384  "will not be performed in the expected transformed frame");
385  };
386 
387  // set the destination coordinate systems for each transform for the purposes of determining
388  // coordinate collapsing. For example if TO is XYZ and FROM is RZ, then TO will have its XYZ
389  // coordinates collapsed into RZ and FROM will have a no-op for coordinate collapsing
390 
391  for (const auto i : index_range(_from_transforms))
392  {
393  auto & from_transform = _from_transforms[i];
394  from_transform->setDestinationCoordTransform(*_to_moose_app_transform);
395  if (i == 0)
396  check_transform_compatibility(*from_transform);
397  }
398  for (const auto i : index_range(_to_transforms))
399  {
400  auto & to_transform = _to_transforms[i];
401  to_transform->setDestinationCoordTransform(*_from_moose_app_transform);
402  if (i == 0)
403  check_transform_compatibility(*to_transform);
404  }
405 }
406 
407 namespace
408 {
409 void
410 fillInfo(MultiApp & multi_app,
411  std::vector<unsigned int> & map,
412  std::vector<FEProblemBase *> & problems,
413  std::vector<Point> & positions)
414 {
415  for (unsigned int i_app = 0; i_app < multi_app.numGlobalApps(); i_app++)
416  {
417  if (!multi_app.hasLocalApp(i_app))
418  continue;
419 
420  auto & subapp_problem = multi_app.appProblemBase(i_app);
421 
422  map.push_back(i_app);
423  problems.push_back(&subapp_problem);
424  if (multi_app.usingPositions())
425  positions.push_back(multi_app.position(i_app));
426  }
427 }
428 }
429 
430 void
432 {
433  if (!_to_multi_app)
434  mooseError("There is no to_multiapp to get info from");
435 
437 }
438 
439 void
441 {
442  if (!_from_multi_app)
443  mooseError("There is no from_multiapp to get info from");
444 
446 }
447 
448 void
450 {
451  MultiApp::transformBoundingBox(box, transform);
452 }
453 
454 void
455 MultiAppTransfer::extendBoundingBoxes(const Real factor, std::vector<BoundingBox> & bboxes) const
456 {
457  const auto extension_factor = factor - 1;
458 
459  // Extend (or contract if the extension factor is negative) bounding boxes along all the
460  // directions by the same length. Greater than zero values of this member may be necessary because
461  // the nearest bounding box does not necessarily give you the closest node/element. It will depend
462  // on the partition and geometry. A node/element will more likely find its nearest source
463  // element/node by extending bounding boxes. If each of the bounding boxes covers the entire
464  // domain, a node/element will be able to find its nearest source element/node for sure, but at
465  // the same time, more communication will be involved and can be expensive.
466  for (auto & box : bboxes)
467  {
468  // libmesh set an invalid bounding box using this code
469  // for (unsigned int i=0; i<LIBMESH_DIM; i++)
470  // {
471  // this->first(i) = std::numeric_limits<Real>::max();
472  // this->second(i) = -std::numeric_limits<Real>::max();
473  // }
474  // If it is an invalid box, we should skip it
475  if (box.first(0) == std::numeric_limits<Real>::max())
476  continue;
477 
478  auto width = box.second - box.first;
479  box.second += width * extension_factor;
480  box.first -= width * extension_factor;
481  }
482 }
483 
484 std::vector<BoundingBox>
486 {
487  std::vector<std::pair<Point, Point>> bb_points(_from_meshes.size());
488  for (unsigned int i = 0; i < _from_meshes.size(); i++)
489  {
490  // Get a bounding box around the mesh elements that are local to the current
491  // processor.
492  BoundingBox bbox = MeshTools::create_local_bounding_box(*_from_meshes[i]);
493 
494  // Translate the bounding box to the from domain's position. We may have rotations so we must
495  // be careful in constructing the new min and max (first and second)
496  const auto from_global_num = getGlobalSourceAppIndex(i);
497  transformBoundingBox(bbox, *_from_transforms[from_global_num]);
498 
499  // Cast the bounding box into a pair of points (so it can be put through
500  // MPI communication).
501  bb_points[i] = static_cast<std::pair<Point, Point>>(bbox);
502  }
503 
504  // Serialize the bounding box points.
505  _communicator.allgather(bb_points);
506 
507  // Recast the points back into bounding boxes and return.
508  std::vector<BoundingBox> bboxes(bb_points.size());
509  for (unsigned int i = 0; i < bb_points.size(); i++)
510  bboxes[i] = static_cast<BoundingBox>(bb_points[i]);
511 
512  // possibly extend bounding boxes
514 
515  return bboxes;
516 }
517 
518 std::vector<BoundingBox>
520 {
521  std::vector<std::pair<Point, Point>> bb_points(_from_meshes.size());
522  const Real min_r = std::numeric_limits<Real>::lowest();
523  const Real max_r = std::numeric_limits<Real>::max();
524 
525  for (unsigned int i = 0; i < _from_meshes.size(); i++)
526  {
527 
528  Point min(max_r, max_r, max_r);
529  Point max(min_r, min_r, min_r);
530  bool at_least_one = false;
531 
532  // TODO: Factor this into mesh_tools after adding new boundary bounding box routine.
533  const ConstBndNodeRange & bnd_nodes = *_from_meshes[i]->getBoundaryNodeRange();
534  for (const auto & bnode : bnd_nodes)
535  {
536  if (bnode->_bnd_id == boundary_id &&
537  bnode->_node->processor_id() == _from_meshes[i]->processor_id())
538  {
539  at_least_one = true;
540  const auto & node = *bnode->_node;
541  for (const auto i : make_range(Moose::dim))
542  {
543  min(i) = std::min(min(i), node(i));
544  max(i) = std::max(max(i), node(i));
545  }
546  }
547  }
548 
549  BoundingBox bbox(min, max);
550  if (!at_least_one)
551  bbox.min() = max; // If we didn't hit any nodes, this will be _the_ minimum bbox
552  else
553  {
554  // Translate the bounding box to the from domain's position. We may have rotations so we must
555  // be careful in constructing the new min and max (first and second)
556  const auto from_global_num = getGlobalSourceAppIndex(i);
557  transformBoundingBox(bbox, *_from_transforms[from_global_num]);
558  }
559 
560  // Cast the bounding box into a pair of points (so it can be put through
561  // MPI communication).
562  bb_points[i] = static_cast<std::pair<Point, Point>>(bbox);
563  }
564 
565  // Serialize the bounding box points.
566  _communicator.allgather(bb_points);
567 
568  // Recast the points back into bounding boxes and return.
569  std::vector<BoundingBox> bboxes(bb_points.size());
570  for (unsigned int i = 0; i < bb_points.size(); i++)
571  bboxes[i] = static_cast<BoundingBox>(bb_points[i]);
572 
573  // possibly extend bounding boxes
575 
576  return bboxes;
577 }
578 
579 std::vector<unsigned int>
581 {
582  std::vector<unsigned int> froms_per_proc;
583  if (_to_multi_app)
584  froms_per_proc.resize(n_processors(), 1);
585  if (_from_multi_app)
586  {
587  froms_per_proc.resize(n_processors());
588  _communicator.allgather(_from_multi_app->numLocalApps(), froms_per_proc);
589  }
590  return froms_per_proc;
591 }
592 
593 NumericVector<Real> &
594 MultiAppTransfer::getTransferVector(unsigned int i_local, std::string var_name)
595 {
596  mooseAssert(_to_multi_app, "getTransferVector only works for transfers to multiapps");
597 
598  return _to_multi_app->appTransferVector(_to_local2global_map[i_local], var_name);
599 }
600 
601 void
603  const VariableName & var_name,
604  const std::string & param_name) const
605 {
606  if (!fe_problem.hasVariable(var_name))
607  {
608  if (param_name.empty())
609  mooseError("The variable '", var_name, "' does not exist.");
610  else
611  paramError(param_name, "The variable '", var_name, "' does not exist.");
612  }
613 }
614 
615 Point
617  unsigned int local_i_to,
618  const std::string & phase) const
619 {
620  const auto & to_transform = _to_transforms[getGlobalTargetAppIndex(local_i_to)];
621  if (to_transform->hasCoordinateSystemTypeChange())
622  {
624  mooseInfo(phase + " cannot use the point in the target app frame due to the "
625  "non-uniqueness of the coordinate collapsing reverse mapping."
626  " Coordinate collapse is ignored for this operation");
627  to_transform->skipCoordinateCollapsing(true);
628  const auto target_point = to_transform->mapBack(p);
629  to_transform->skipCoordinateCollapsing(false);
630  return target_point;
631  }
632  else
633  return to_transform->mapBack(p);
634 }
635 
636 unsigned int
638 {
639  mooseAssert(_current_direction == TO_MULTIAPP || i_from < _from_local2global_map.size(),
640  "Out of bounds local from-app index");
641  return _current_direction == TO_MULTIAPP ? 0 : _from_local2global_map[i_from];
642 }
643 
644 unsigned int
646 {
647  mooseAssert(_current_direction == FROM_MULTIAPP || i_to < _to_local2global_map.size(),
648  "Out of bounds local to-app index");
650 }
651 
652 unsigned int
654 {
656  ? 0
658 }
659 
660 void
662 {
663  // parent app is the source app, EXEC_TRANSFER is fine
664  if (!hasFromMultiApp())
665  return;
666  // Get the app and problem
667  const auto & app = getFromMultiApp();
668  if (!app->hasApp())
669  return;
670  const auto & problem = app->appProblemBase(app->firstLocalApp());
671  // Use the warehouse to find the object
672  std::vector<SetupInterface *> objects_with_exec_on;
673  problem.theWarehouse()
674  .query()
675  .template condition<AttribName>(object_name)
676  .template condition<AttribExecOns>(EXEC_TRANSFER)
677  .queryInto(objects_with_exec_on);
678  if (objects_with_exec_on.size())
679  mooseError("Object '" + object_name +
680  "' should not be executed on EXEC_TRANSFER, because this transfer has "
681  "indicated it does not support it.\nExecuting this object on TIMESTEP_END should be "
682  "sufficient to get updated values.");
683 }
libMesh::NumericVector< Real > & getTransferVector(unsigned int i_local, std::string var_name)
If we are transferring to a multiapp, return the appropriate solution vector.
virtual bool hasVariable(const std::string &var_name) const override
Whether or not this problem has the variable.
std::vector< std::unique_ptr< MultiAppCoordTransform > > _to_transforms
bool hasLocalApp(unsigned int global_app) const
Whether or not the given global app number is on this processor.
Definition: MultiApp.C:1061
std::tuple< short int, Real, short int, std::array< Real, 3 >, int, unsigned int, unsigned int, short int, short int, short int > MinimalData
A typedef for conveniency that describes the minimal data necessary to broadcast and build a MooseApp...
const ExecFlagType EXEC_TRANSFER
Definition: Moose.C:53
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
std::vector< libMesh::EquationSystems * > _to_es
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:21
std::unique_ptr< MooseAppCoordTransform > _to_moose_app_transform
The moose coordinate transformation object describing rotations, scaling, and coordinate system of th...
void addDeprecatedParam(const std::string &name, const T &value, const std::string &doc_string, const std::string &deprecation_message)
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
static void transformBoundingBox(libMesh::BoundingBox &box, const MultiAppCoordTransform &transform)
Transform a bounding box according to the transformations in the provided coordinate transformation o...
const bool _skip_coordinate_collapsing
Whether to skip coordinate collapsing (transformations of coordinates between applications using diff...
MooseEnum _current_direction
Definition: Transfer.h:106
void setDocString(const std::string &name, const std::string &doc)
Set the doc string of a parameter.
void variableIntegrityCheck(const AuxVariableName &var_name, bool is_from_multiapp) const
Utility to verify that the variable in the destination system exists.
void setAdditionalValue(const std::string &names)
Insert operators Operator to insert (push_back) values into the enum.
unsigned int getLocalSourceAppIndex(unsigned int i_from) const
Return the local app index from the global index in the "from-multiapp" transfer direction We use the...
void mooseInfo(Args &&... args) const
void checkMultiAppExecuteOn()
Helper method for checking the &#39;check_multiapp_execute_on&#39; flag.
std::shared_ptr< MultiApp > _from_multi_app
The MultiApps this Transfer is transferring data to or from.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
MultiAppTransfer(const InputParameters &parameters)
std::vector< libMesh::BoundingBox > getFromBoundingBoxes()
Return the bounding boxes of all the "from" domains, including all the domains not local to this proc...
MeshBase & mesh
std::vector< FEProblemBase * > _to_problems
processor_id_type rank() const
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition: Moose.h:154
FEProblemBase & _fe_problem
Definition: Transfer.h:97
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
Add additional execute_on flags to the list of possible flags.
Definition: ExecFlagEnum.h:82
std::vector< Point > _from_positions
const Parallel::Communicator & _communicator
std::shared_ptr< MultiApp > _multi_app
Deprecated class attribute for compatibility with the apps.
bool hasFromMultiApp() const
Whether the transfer owns a non-null from_multi_app.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:57
Point getPointInTargetAppFrame(const Point &p, unsigned int local_i_to, const std::string &phase) const
Get the target app point from a point in the reference frame.
void mooseWarning(Args &&... args) const
Emits a warning prefixed with object name and type.
auto max(const L &left, const R &right)
std::shared_ptr< MultiApp > getMultiApp(const std::string &multi_app_name) const
Get a MultiApp object by name.
std::vector< unsigned int > _to_local2global_map
Given local app index, returns global app index.
void checkVariable(const FEProblemBase &fe_problem, const VariableName &var_name, const std::string &param_name="") const
Helper for checking a problem for a variable.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
unsigned int getGlobalTargetAppIndex(unsigned int i_to) const
Return the global app index from the local index in the "to-multiapp" transfer direction.
bool _displaced_target_mesh
True if displaced mesh is used for the target mesh, otherwise false.
virtual bool usesMooseAppCoordTransform() const
Whether this transfer handles non-translation-based transformations, e.g.
processor_id_type n_processors() const
std::vector< libMesh::EquationSystems * > _from_es
std::vector< MooseMesh * > _from_meshes
static void transformBoundingBox(libMesh::BoundingBox &box, const MultiAppCoordTransform &transform)
Transform a bounding box according to the transformations in the provided coordinate transformation o...
Definition: MultiApp.C:893
void errorIfObjectExecutesOnTransferInSourceApp(const std::string &object_name) const
Error if executing this MooseObject on EXEC_TRANSFER in a source multiapp (from_multiapp, e.g.
unsigned int numGlobalApps() const
Definition: MultiApp.h:278
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
boundary_id_type BoundaryID
std::unique_ptr< MooseAppCoordTransform > _from_moose_app_transform
The moose coordinate transformation object describing rotations, scaling, and coordinate system of th...
const ExecFlagEnum & getExecuteOnEnum() const
Return the execute on MultiMooseEnum for this object.
std::vector< unsigned int > getFromsPerProc()
Return the number of "from" domains that each processor owns.
static InputParameters validParams()
Definition: Transfer.C:27
const std::string & type() const
Get the type of this class.
Definition: MooseBase.h:51
FEProblemBase & appProblemBase(unsigned int app)
Get the FEProblemBase for the global app desired.
Definition: MultiApp.C:1007
unsigned int getGlobalSourceAppIndex(unsigned int i_from) const
Return the global app index from the local index in the "from-multiapp" transfer direction.
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 ...
std::shared_ptr< MultiApp > _to_multi_app
static InputParameters validParams()
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
bool isParamSetByUser(const std::string &name) const
Method returns true if the parameter was set by the user.
bool usingPositions() const
Whether or not this MultiApp is using positions or its own way for constructing sub-apps.
Definition: MultiApp.h:363
std::vector< Point > _to_positions
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
MultiMooseEnum _directions
The directions this Transfer is to be executed on.
Definition: Transfer.h:110
Real _bbox_factor
Extend (or contract) bounding box by a factor in all directions Greater than one values of this membe...
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
IntRange< T > make_range(T beg, T end)
bool _displaced_source_mesh
True if displaced mesh is used for the source mesh, otherwise false.
const ExecFlagType EXEC_SAME_AS_MULTIAPP
Definition: Moose.C:51
std::vector< unsigned int > _from_local2global_map
Given local app index, returns global app index.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
static void addBBoxFactorParam(InputParameters &params)
Add the bounding box factor parameter to the supplied input parameters.
const InputParameters & parameters() const
Get the parameters of the object.
static void addSkipCoordCollapsingParam(InputParameters &params)
Add the option to skip coordinate collapsing in coordinate transformation operations.
void extendBoundingBoxes(const Real factor, std::vector< libMesh::BoundingBox > &bboxes) const
Extends bounding boxes to avoid missing points.
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...
MooseEnum _direction
Definition: Transfer.h:105
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
virtual void checkSiblingsTransferSupported() const
Whether the transfer supports siblings transfer.
A MultiApp represents one or more MOOSE applications that are running simultaneously.
Definition: MultiApp.h:112
virtual void getAppInfo()
This method will fill information into the convenience member variables (_to_problems, _from_meshes, etc.)
auto min(const L &left, const R &right)
std::vector< FEProblemBase * > _from_problems
auto index_range(const T &sizable)
const Point & position(unsigned int app) const
The physical position of a global App number.
Definition: MultiApp.C:1503
std::vector< MooseMesh * > _to_meshes
const ExecFlagType EXEC_POST_ADAPTIVITY
Definition: Moose.C:56
This class contains transformation information that only exists in a context in which there are multi...
Base class for all Transfer objects.
Definition: Transfer.h:36
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...