www.mooseframework.org
MultiAppTransfer.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 
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 
23 
26 {
28  params.addRequiredParam<MultiAppName>("multi_app", "The name of the MultiApp to use.");
29 
30  // MultiAppTransfers by default will execute with their associated MultiApp. These flags will be
31  // added by FEProblemBase when the transfer is added.
32  ExecFlagEnum & exec_enum = params.set<ExecFlagEnum>("execute_on", true);
34  exec_enum = EXEC_SAME_AS_MULTIAPP;
35  params.setDocString("execute_on", exec_enum.getDocString());
36 
37  params.addParam<bool>(
38  "check_multiapp_execute_on",
39  true,
40  "When false the check between the multiapp and transfer execute on flags is not preformed.");
41  params.addParam<bool>("displaced_source_mesh",
42  false,
43  "Whether or not to use the displaced mesh for the source mesh.");
44  params.addParam<bool>("displaced_target_mesh",
45  false,
46  "Whether or not to use the displaced mesh for the target mesh.");
47  return params;
48 }
49 
51  : Transfer(parameters),
52  _multi_app(_fe_problem.getMultiApp(getParam<MultiAppName>("multi_app"))),
53  _displaced_source_mesh(getParam<bool>("displaced_source_mesh")),
54  _displaced_target_mesh(getParam<bool>("displaced_target_mesh"))
55 {
56  if (getParam<bool>("check_multiapp_execute_on"))
58 
59  if (_directions.size() == 0)
60  paramError("direction", "At least one direction is required");
61 
62  // If we have just one direction in _directions, set it now so that it can be used in the
63  // constructor
64  if (_directions.size() == 1)
65  {
66  int only_direction = _directions.get(0);
67  _current_direction = only_direction;
68  _direction = only_direction;
69  }
70 }
71 
72 void
74 {
75  if (getExecuteOnEnum() != _multi_app->getExecuteOnEnum())
76  mooseDoOnce(mooseWarning("MultiAppTransfer execute_on flags do not match associated Multiapp "
77  "execute_on flags"));
78 }
79 
80 void
81 MultiAppTransfer::variableIntegrityCheck(const AuxVariableName & var_name) const
82 {
83  for (unsigned int i = 0; i < _multi_app->numGlobalApps(); i++)
84  if (_multi_app->hasLocalApp(i) && !_multi_app->appProblemBase(i).hasVariable(var_name))
85  mooseError("Cannot find variable ", var_name, " for ", name(), " Transfer");
86 }
87 
88 const std::vector<ExecFlagType> &
90 {
91  mooseDeprecated("The execFlags() methos is being removed because MOOSE has been updated to use a "
92  "ExecFlagEnum for execute flags. The current flags should be retrieved from "
93  "the \"exeucte_on\" parameters of your object or by using the \"_execute_enum\" "
94  "reference to the parameter or the getExecuteOnEnum() method.");
95  return _exec_flags;
96 }
97 
98 void
100 {
101  // I would like to do all of this in initialSetup, but it will fail with
102  // multiapps that reset. A reset deletes and rebuilds the FEProblems so all
103  // of the pointers will be broken.
104 
105  // Clear the vectors since we've probably built them up from a previous call
106  _from_problems.clear();
107  _to_problems.clear();
108  _from_es.clear();
109  _to_es.clear();
110  _from_meshes.clear();
111  _to_meshes.clear();
112  _to_positions.clear();
113  _from_positions.clear();
114 
115  // Build the vectors for to problems, from problems, and subapps positions.
116  switch (_direction)
117  {
118  case TO_MULTIAPP:
119  _from_problems.push_back(&_multi_app->problemBase());
120  _from_positions.push_back(Point(0., 0., 0.));
121  for (unsigned int i_app = 0; i_app < _multi_app->numGlobalApps(); i_app++)
122  {
123  if (!_multi_app->hasLocalApp(i_app))
124  continue;
125  _local2global_map.push_back(i_app);
126  _to_problems.push_back(&_multi_app->appProblemBase(i_app));
127  _to_positions.push_back(_multi_app->position(i_app));
128  }
129  break;
130 
131  case FROM_MULTIAPP:
132  _to_problems.push_back(&_multi_app->problemBase());
133  _to_positions.push_back(Point(0., 0., 0.));
134  for (unsigned int i_app = 0; i_app < _multi_app->numGlobalApps(); i_app++)
135  {
136  if (!_multi_app->hasLocalApp(i_app))
137  continue;
138  _local2global_map.push_back(i_app);
139  _from_problems.push_back(&_multi_app->appProblemBase(i_app));
140  _from_positions.push_back(_multi_app->position(i_app));
141  }
142  break;
143  }
144 
145  // Build the from and to equation systems and mesh vectors.
146  for (unsigned int i = 0; i < _to_problems.size(); i++)
147  {
148  // TODO: Do I actually want es or displaced es?
149  _to_es.push_back(&_to_problems[i]->es());
150  if (_displaced_target_mesh && _to_problems[i]->getDisplacedProblem())
151  _to_meshes.push_back(&_to_problems[i]->getDisplacedProblem()->mesh());
152  else
153  _to_meshes.push_back(&_to_problems[i]->mesh());
154  }
155  for (unsigned int i = 0; i < _from_problems.size(); i++)
156  {
157  _from_es.push_back(&_from_problems[i]->es());
158  if (_displaced_source_mesh && _from_problems[i]->getDisplacedProblem())
159  _from_meshes.push_back(&_from_problems[i]->getDisplacedProblem()->mesh());
160  else
161  _from_meshes.push_back(&_from_problems[i]->mesh());
162  }
163 }
164 
165 std::vector<BoundingBox>
167 {
168  std::vector<std::pair<Point, Point>> bb_points(_from_meshes.size());
169  for (unsigned int i = 0; i < _from_meshes.size(); i++)
170  {
171  // Get a bounding box around the mesh elements that are local to the current
172  // processor.
173  BoundingBox bbox = MeshTools::create_local_bounding_box(*_from_meshes[i]);
174 
175  // Translate the bounding box to the from domain's position.
176  bbox.first += _from_positions[i];
177  bbox.second += _from_positions[i];
178 
179  // Cast the bounding box into a pair of points (so it can be put through
180  // MPI communication).
181  bb_points[i] = static_cast<std::pair<Point, Point>>(bbox);
182  }
183 
184  // Serialize the bounding box points.
185  _communicator.allgather(bb_points);
186 
187  // Recast the points back into bounding boxes and return.
188  std::vector<BoundingBox> bboxes(bb_points.size());
189  for (unsigned int i = 0; i < bb_points.size(); i++)
190  bboxes[i] = static_cast<BoundingBox>(bb_points[i]);
191 
192  return bboxes;
193 }
194 
195 std::vector<BoundingBox>
197 {
198  std::vector<std::pair<Point, Point>> bb_points(_from_meshes.size());
199  const Real min_r = std::numeric_limits<Real>::lowest();
200  const Real max_r = std::numeric_limits<Real>::max();
201 
202  for (unsigned int i = 0; i < _from_meshes.size(); i++)
203  {
204 
205  Point min(max_r, max_r, max_r);
206  Point max(min_r, min_r, min_r);
207  bool at_least_one = false;
208 
209  // TODO: Factor this into mesh_tools after adding new boundary bounding box routine.
210  const ConstBndNodeRange & bnd_nodes = *_from_meshes[i]->getBoundaryNodeRange();
211  for (const auto & bnode : bnd_nodes)
212  {
213  if (bnode->_bnd_id == boundary_id && bnode->_node->processor_id() == processor_id())
214  {
215  const auto & node = *bnode->_node;
216  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
217  {
218  min = std::min(min(i), node(i));
219  max = std::max(max(i), node(i));
220  at_least_one = true;
221  }
222  }
223  }
224 
225  BoundingBox bbox(min, max);
226  if (!at_least_one)
227  bbox.min() = max; // If we didn't hit any nodes, this will be _the_ minimum bbox
228  else
229  {
230  // Translate the bounding box to the from domain's position.
231  bbox.first += _from_positions[i];
232  bbox.second += _from_positions[i];
233  }
234 
235  // Cast the bounding box into a pair of points (so it can be put through
236  // MPI communication).
237  bb_points[i] = static_cast<std::pair<Point, Point>>(bbox);
238  }
239 
240  // Serialize the bounding box points.
241  _communicator.allgather(bb_points);
242 
243  // Recast the points back into bounding boxes and return.
244  std::vector<BoundingBox> bboxes(bb_points.size());
245  for (unsigned int i = 0; i < bb_points.size(); i++)
246  bboxes[i] = static_cast<BoundingBox>(bb_points[i]);
247 
248  return bboxes;
249 }
250 
251 std::vector<unsigned int>
253 {
254  std::vector<unsigned int> froms_per_proc;
255  switch (_direction)
256  {
257  case TO_MULTIAPP:
258  froms_per_proc.resize(n_processors(), 1);
259  break;
260  case FROM_MULTIAPP:
261  froms_per_proc.resize(n_processors());
262  _communicator.allgather(_multi_app->numLocalApps(), froms_per_proc);
263  break;
264  }
265  return froms_per_proc;
266 }
267 
268 NumericVector<Real> &
269 MultiAppTransfer::getTransferVector(unsigned int i_local, std::string var_name)
270 {
271  mooseAssert(_direction == TO_MULTIAPP, "getTransferVector only works for transfers to multiapps");
272 
273  return _multi_app->appTransferVector(_local2global_map[i_local], var_name);
274 }
275 
276 void
278  const VariableName & var_name,
279  const std::string & param_name) const
280 {
281  if (!fe_problem.hasVariable(var_name))
282  {
283  if (param_name.empty())
284  mooseError("The variable '", var_name, "' does not exist.");
285  else
286  paramError(param_name, "The variable '", var_name, "' does not exist.");
287  }
288 }
MultiAppTransfer::variableIntegrityCheck
void variableIntegrityCheck(const AuxVariableName &var_name) const
Utility to verify that the variable in the destination system exists.
Definition: MultiAppTransfer.C:81
MultiAppTransfer::_from_positions
std::vector< Point > _from_positions
Definition: MultiAppTransfer.h:70
Transfer::FROM_MULTIAPP
Definition: Transfer.h:72
MooseMesh.h
FEProblem.h
MultiAppTransfer::MultiAppTransfer
MultiAppTransfer(const InputParameters &parameters)
Definition: MultiAppTransfer.C:50
MultiAppTransfer::_multi_app
std::shared_ptr< MultiApp > _multi_app
The MultiApp this Transfer is transferring data to or from.
Definition: MultiAppTransfer.h:55
MooseObject::mooseError
void mooseError(Args &&... args) const
Definition: MooseObject.h:141
ConstBndNodeRange
StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > ConstBndNodeRange
Some useful StoredRange typedefs.
Definition: MooseMesh.h:1301
MultiAppTransfer::_to_meshes
std::vector< MooseMesh * > _to_meshes
Definition: MultiAppTransfer.h:67
ExecFlagEnum::addAvailableFlags
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
Add additional execute_on flags to the list of possible flags.
Definition: ExecFlagEnum.h:85
InputParameters::setDocString
void setDocString(const std::string &name, const std::string &doc)
Set the doc string of a parameter.
Definition: InputParameters.C:240
MultiAppTransfer::_to_problems
std::vector< FEProblemBase * > _to_problems
Definition: MultiAppTransfer.h:63
InputParameters::addParam
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.
Definition: InputParameters.h:1198
MultiMooseEnum::get
unsigned int get(unsigned int i) const
Indexing operator Operator to retrieve an item from the MultiMooseEnum.
Definition: MultiMooseEnum.C:171
MultiAppTransfer::_displaced_source_mesh
bool _displaced_source_mesh
True if displaced mesh is used for the source mesh, otherwise false.
Definition: MultiAppTransfer.h:73
MultiAppTransfer::checkMultiAppExecuteOn
void checkMultiAppExecuteOn()
Helper method for checking the 'check_multiapp_execute_on' flag.
Definition: MultiAppTransfer.C:73
MultiAppTransfer::getFromBoundingBoxes
std::vector< BoundingBox > getFromBoundingBoxes()
Return the bounding boxes of all the "from" domains, including all the domains not local to this proc...
Definition: MultiAppTransfer.C:166
Transfer::_current_direction
MooseEnum _current_direction
Definition: Transfer.h:106
MooseObject::paramError
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: MooseObject.h:215
MultiAppTransfer::getFromsPerProc
std::vector< unsigned int > getFromsPerProc()
Return the number of "from" domains that each processor owns.
Definition: MultiAppTransfer.C:252
InputParameters
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
Definition: InputParameters.h:53
InputParameters::set
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
Definition: InputParameters.h:987
Transfer
Base class for all Transfer objects.
Definition: Transfer.h:40
SetupInterface::getExecuteOnEnum
const ExecFlagEnum & getExecuteOnEnum() const
Return the execute on MultiMooseEnum for this object.
Definition: SetupInterface.C:69
Transfer::_direction
MooseEnum _direction
Definition: Transfer.h:105
FEProblemBase::hasVariable
virtual bool hasVariable(const std::string &var_name) const override
Whether or not this problem has the variable.
Definition: FEProblemBase.C:4196
MultiAppTransfer::_to_positions
std::vector< Point > _to_positions
Definition: MultiAppTransfer.h:69
MultiMooseEnum::size
unsigned int size() const
Return the number of active items in the MultiMooseEnum.
Definition: MultiMooseEnum.C:233
MultiAppTransfer::_displaced_target_mesh
bool _displaced_target_mesh
True if displaced mesh is used for the target mesh, otherwise false.
Definition: MultiAppTransfer.h:75
BoundaryID
boundary_id_type BoundaryID
Definition: AutomaticMortarGeneration.h:47
MultiAppTransfer::checkVariable
void checkVariable(const FEProblemBase &fe_problem, const VariableName &var_name, const std::string &param_name="") const
Helper for checking a problem for a variable.
Definition: MultiAppTransfer.C:277
defineLegacyParams
defineLegacyParams(MultiAppTransfer)
SetupInterface::_exec_flags
const std::vector< ExecFlagType > _exec_flags
(DEPRECATED) execution flag (when is the object executed/evaluated) TODO: ExecFlagType
Definition: SetupInterface.h:96
MultiApp.h
MultiAppTransfer
Base class for all MultiAppTransfer objects.
Definition: MultiAppTransfer.h:35
MultiAppTransfer::_local2global_map
std::vector< unsigned int > _local2global_map
Definition: MultiAppTransfer.h:100
Transfer::validParams
static InputParameters validParams()
Definition: Transfer.C:27
MultiAppTransfer::getAppInfo
void getAppInfo()
This method will fill information into the convenience member variables (_to_problems,...
Definition: MultiAppTransfer.C:99
MultiAppTransfer::validParams
static InputParameters validParams()
Definition: MultiAppTransfer.C:25
DisplacedProblem.h
Transfer::TO_MULTIAPP
Definition: Transfer.h:71
MultiAppTransfer::_to_es
std::vector< EquationSystems * > _to_es
Definition: MultiAppTransfer.h:65
MultiAppTransfer::getTransferVector
NumericVector< Real > & getTransferVector(unsigned int i_local, std::string var_name)
If we are transferring to a multiapp, return the appropriate solution vector.
Definition: MultiAppTransfer.C:269
Transfer.h
MultiAppTransfer::_from_problems
std::vector< FEProblemBase * > _from_problems
Definition: MultiAppTransfer.h:64
Transfer::_directions
const MultiMooseEnum _directions
The directions this Transfer is to be executed on.
Definition: Transfer.h:110
MultiAppTransfer.h
MultiAppTransfer::execFlags
virtual const std::vector< ExecFlagType > & execFlags() const
Return the execution flags, handling "same_as_multiapp".
Definition: MultiAppTransfer.C:89
MooseTypes.h
MultiAppTransfer::_from_meshes
std::vector< MooseMesh * > _from_meshes
Definition: MultiAppTransfer.h:68
MultiAppTransfer::_from_es
std::vector< EquationSystems * > _from_es
Definition: MultiAppTransfer.h:66
FEProblemBase
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
Definition: FEProblemBase.h:139
ExecFlagEnum
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:24
MooseObject::mooseDeprecated
void mooseDeprecated(Args &&... args) const
Definition: MooseObject.h:156
InputParameters::addRequiredParam
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...
Definition: InputParameters.h:1176
EXEC_SAME_AS_MULTIAPP
const ExecFlagType EXEC_SAME_AS_MULTIAPP
MooseObject::mooseWarning
void mooseWarning(Args &&... args) const
Definition: MooseObject.h:150
MooseObject::name
virtual const std::string & name() const
Get the name of the object.
Definition: MooseObject.h:70