https://mooseframework.inl.gov
MultiAppReporterTransfer.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 #include "MooseError.h"
12 #include "MultiApp.h"
13 
15 
18 {
21  params.addClassDescription("Transfers reporter data between two applications.");
22  params.addRequiredParam<std::vector<ReporterName>>(
23  "from_reporters",
24  "List of the reporter names (object_name/value_name) to transfer the value from.");
25  params.addRequiredParam<std::vector<ReporterName>>(
26  "to_reporters",
27  "List of the reporter names (object_name/value_name) to transfer the value to.");
28  params.addParam<unsigned int>(
29  "subapp_index",
31  "The MultiApp object sub-application index to use when transferring to/from the "
32  "sub-application. If unset and transferring to the sub-applications then all "
33  "sub-applications will receive data. The value must be set when transferring from a "
34  "sub-application.");
35  params.addParam<bool>(
36  "distribute_reporter_vector",
37  false,
38  "Transfer to/from a vector reporter from/to reporters on child applications. N "
39  "to 1 or 1 to N type of transfer. The number of child applications must "
40  "match the size of the vector reporter");
41  return params;
42 }
43 
45  : MultiAppTransfer(parameters),
47  _from_reporter_names(getParam<std::vector<ReporterName>>("from_reporters")),
48  _to_reporter_names(getParam<std::vector<ReporterName>>("to_reporters")),
49  _subapp_index(getParam<unsigned int>("subapp_index")),
50  _distribute_reporter_vector(getParam<bool>("distribute_reporter_vector"))
51 {
52  if (_from_reporter_names.size() != _to_reporter_names.size())
53  paramError("to_reporters", "from_reporters and to_reporters must be the same size.");
54 
55  if (_directions.size() > 1)
56  paramError("direction", "This transfer only supports a single direction.");
57 
58  if (isParamValid("to_multi_app") && isParamValid("from_multi_app") &&
60  paramError("subapp_index",
61  "The subapp_index parameter is not supported for transfers between two multiapps");
62 
63  if (hasFromMultiApp())
64  {
65  const auto multi_app = getFromMultiApp();
66  // Errors for sub app index.
68  _subapp_index >= multi_app->numGlobalApps())
69  paramError(
70  "subapp_index",
71  "The supplied sub-application index is greater than the number of sub-applications.");
74  multi_app->numGlobalApps() > 1 && !_distribute_reporter_vector)
75  paramError("from_multi_app",
76  "subapp_index must be provided when more than one subapp is present.");
77  }
78  else if (hasToMultiApp())
79  {
80  // Errors for sub app index.
82  _subapp_index >= getToMultiApp()->numGlobalApps())
83  paramError(
84  "subapp_index",
85  "The supplied sub-application index is greater than the number of sub-applications.");
86  }
87 }
88 
89 void
91 {
93 
94  // We need to get a reference to the data now so we can tell ReporterData
95  // that we consume a replicated version.
96  // Find proper FEProblem
97  FEProblemBase * problem_ptr = nullptr;
99  problem_ptr = &getToMultiApp()->problemBase();
101  getFromMultiApp()->hasLocalApp(0))
102  problem_ptr = &getFromMultiApp()->appProblemBase(0);
103  else if (getFromMultiApp()->hasLocalApp(_subapp_index))
104  problem_ptr = &getFromMultiApp()->appProblemBase(_subapp_index);
105 
106  // Tell ReporterData to consume with replicated
107  if (problem_ptr && !_distribute_reporter_vector)
108  for (const auto & fn : _from_reporter_names)
110 
111  // Check that we have the correct reporter modes setup.
113  {
114  if (hasFromMultiApp())
116  else if (hasToMultiApp())
118  }
119 }
120 
121 void
123 {
124  if (!hasToMultiApp())
125  return;
126 
127  std::vector<unsigned int> indices;
129  {
130  indices.resize(getToMultiApp()->numGlobalApps());
131  std::iota(indices.begin(), indices.end(), 0);
132  }
133  else
134  indices = {_subapp_index};
135 
136  for (const auto & ind : indices)
137  if (getToMultiApp()->hasLocalApp(ind) &&
138  (!hasFromMultiApp() || getFromMultiApp()->hasLocalApp(ind)))
139  for (unsigned int n = 0; n < _from_reporter_names.size(); ++n)
140  {
144  getToMultiApp()->problemBase(),
145  getToMultiApp()->appProblemBase(ind),
146  ind);
147  else
150  hasFromMultiApp() ? getFromMultiApp()->appProblemBase(ind)
151  : getToMultiApp()->problemBase(),
152  getToMultiApp()->appProblemBase(ind));
153  }
154 }
155 
156 void
158 {
159  if (!hasFromMultiApp())
160  return;
161 
162  // subapp indices to perform transfers on
163  std::vector<unsigned int> indices;
165  {
166  // If distributing, resize the indices vector to the number of global apps
167  indices.resize(getFromMultiApp()->numGlobalApps());
168  std::iota(indices.begin(), indices.end(), 0);
169  }
171  {
172  // if _subapp_index not set indices is set to 0
173  indices = {0};
174  }
175  else
176  // set indices to specific _subapp_index
177  indices = {_subapp_index};
178 
180  for (const auto n : index_range(_to_reporter_names))
181  {
182  // Clear all vector reporters and resize to the number of subapps.
183  // The summing process later will make sure the reporter values are
184  // consistent across the processors.
185  auto size = getFromMultiApp()->numGlobalApps();
187  resizeReporter(_to_reporter_names[n], getFromMultiApp()->problemBase(), size);
188  }
189 
190  for (const auto ind : indices)
191  if (getFromMultiApp()->hasLocalApp(ind) &&
192  (!hasToMultiApp() || getToMultiApp()->hasLocalApp(ind)))
193  for (const auto n : index_range(_from_reporter_names))
194  {
196  {
197  if (getFromMultiApp()->appProblemBase(ind).processor_id() == 0) // Subapp Root Rank only
200  getFromMultiApp()->appProblemBase(ind),
201  getFromMultiApp()->problemBase(),
202  ind);
203  }
204  else
207  getFromMultiApp()->appProblemBase(ind),
208  hasToMultiApp() ? getToMultiApp()->appProblemBase(ind) // !
209  : getFromMultiApp()->problemBase());
210  }
211 
213  for (const auto n : index_range(_to_reporter_names))
214  {
215  // Perform summing operation that makes sure all procs have the correct
216  // Reporter values.
218  }
219 }
220 
221 void
223 {
224  TIME_SECTION("MultiAppReporterTransfer::execute()", 5, "Transferring reporters");
225 
228  else
230 }
231 
232 void
234 {
235 
237  paramError("distribute_reporter_vector",
238  "Distributing reporter vectors is not implemented with sibling transfers.");
239 
240  // Check that we are in the supported configuration: same number of source and target apps
241  // The allocation of the child apps on the processors must be the same
242  if (getFromMultiApp()->numGlobalApps() == getToMultiApp()->numGlobalApps())
243  {
244  for (const auto i : make_range(getToMultiApp()->numGlobalApps()))
245  if (getFromMultiApp()->hasLocalApp(i) + getToMultiApp()->hasLocalApp(i) == 1)
246  mooseError("Child application allocation on parallel processes must be the same to support "
247  "siblings reporter transfer");
248  }
249  else
250  mooseError("Number of source and target child apps must match for siblings transfer");
251 }
252 
253 // Helper function to check reporter modes
254 void
256  const std::shared_ptr<MultiApp> & main_app,
257  const std::vector<ReporterName> & main_app_rep_names,
258  const std::vector<ReporterName> & sub_app_rep_names)
259 {
260  // Set reporter transfer modes for the main app.
261  for (const auto & rn : main_app_rep_names)
262  addReporterTransferMode(rn, REPORTER_MODE_REPLICATED, main_app->problemBase());
263 
264  std::vector<unsigned int> indices(main_app->numGlobalApps());
265  std::iota(indices.begin(), indices.end(), 0);
266 
267  // Set reporter transfer modes for sub app.
268  // Setting to ROOT means this works for ROOT and REPLICATED reports with no
269  // change to users.
270  for (const auto & ind : indices)
271  if (main_app->hasLocalApp(ind))
272  for (const auto & rn : sub_app_rep_names)
273  addReporterTransferMode(rn, REPORTER_MODE_ROOT, main_app->appProblemBase(ind));
274 }
void transferFromVectorReporter(const ReporterName &from_reporter, const ReporterName &to_reporter, const FEProblemBase &from_problem, FEProblemBase &to_problem, dof_id_type index, unsigned int time_index=0)
virtual void checkSiblingsTransferSupported() const override
Whether the transfer supports siblings transfer.
void clearVectorReporter(const ReporterName &name, FEProblemBase &problem)
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
void addReporterTransferMode(const ReporterName &name, const ReporterMode &mode, FEProblemBase &problem)
MooseEnum _current_direction
Definition: Transfer.h:106
const ReporterMode REPORTER_MODE_ROOT
unsigned int size() const
Return the number of active items in the MultiMooseEnum.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const std::shared_ptr< MultiApp > getToMultiApp() const
Get the MultiApp to transfer data to.
const unsigned int & _subapp_index
If set, indicates a particular subapp to transfer the reporter to/from.
bool hasFromMultiApp() const
Whether the transfer owns a non-null from_multi_app.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
const std::vector< ReporterName > & _from_reporter_names
Vector of reporters to transfer data from.
auto max(const L &left, const R &right)
void resizeReporter(const ReporterName &name, FEProblemBase &problem, dof_id_type n)
virtual void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
static InputParameters validParams()
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
MultiAppReporterTransfer(const InputParameters &parameters)
const std::vector< ReporterName > & _to_reporter_names
Vector of reporters to transfer data to.
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
void transferReporter(const ReporterName &from_reporter, const ReporterName &to_reporter, const FEProblemBase &from_problem, FEProblemBase &to_problem, unsigned int time_index=0)
bool _distribute_reporter_vector
determines transfer type
Transfer for migrating reporter values between the main and sub-application(s).
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 ...
bool isValueSet(const std::string &value) const
Methods for seeing if a value is set in the MultiMooseEnum.
virtual void execute() override
Execute the transfer.
static InputParameters validParams()
void setVectorReporterTransferModes(const std::shared_ptr< MultiApp > &main_app, const std::vector< ReporterName > &main_app_rep_names, const std::vector< ReporterName > &sub_app_rep_names)
Sets transfer modes for reporters when distributing.
MultiMooseEnum _directions
The directions this Transfer is to be executed on.
Definition: Transfer.h:110
Base class for all MultiAppTransfer objects.
void sumVectorReporter(const ReporterName &name, FEProblemBase &problem)
IntRange< T > make_range(T beg, T end)
bool hasToMultiApp() const
Whether the transfer owns a non-null to_multi_app.
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...
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
registerMooseObject("MooseApp", MultiAppReporterTransfer)
const ReporterMode REPORTER_MODE_REPLICATED
void transferToVectorReporter(const ReporterName &from_reporter, const ReporterName &to_reporter, const FEProblemBase &from_problem, FEProblemBase &to_problem, dof_id_type index, unsigned int time_index=0)
processor_id_type processor_id() const
static InputParameters validParams()
void ErrorVector unsigned int
auto index_range(const T &sizable)
The Reporter system is comprised of objects that can contain any number of data values.
Definition: ReporterName.h:30