https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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",
30 std::numeric_limits<unsigned int>::max(),
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") &&
59 _subapp_index != std::numeric_limits<unsigned int>::max())
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.
67 if (_subapp_index != std::numeric_limits<unsigned int>::max() &&
68 _subapp_index >= multi_app->numGlobalApps())
70 "subapp_index",
71 "The supplied sub-application index is greater than the number of sub-applications.");
73 _subapp_index == std::numeric_limits<unsigned int>::max() &&
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.
81 if (_subapp_index != std::numeric_limits<unsigned int>::max() &&
82 _subapp_index >= getToMultiApp()->numGlobalApps())
84 "subapp_index",
85 "The supplied sub-application index is greater than the number of sub-applications.");
86 }
87}
88
89void
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();
100 else if (_subapp_index == std::numeric_limits<unsigned int>::max() &&
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
121void
123{
124 if (!hasToMultiApp())
125 return;
126
127 std::vector<unsigned int> indices;
128 if (_subapp_index == std::numeric_limits<unsigned int>::max())
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
156void
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 }
170 else if (_subapp_index == std::numeric_limits<unsigned int>::max())
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
212 // With no to_multi_app, only the ranks owning the sub-app wrote above; if some ranks of
213 // this app do not own it, share the value from the lowest owning rank.
215 {
216 mooseAssert(indices.size() == 1, "Expected a single sub-app index when not distributing");
217 const bool owns_app = getFromMultiApp()->hasLocalApp(indices[0]);
218 bool all_own_app = owns_app;
219 _communicator.min(all_own_app);
220 if (!all_own_app)
221 {
222 processor_id_type root =
223 owns_app ? processor_id() : std::numeric_limits<processor_id_type>::max();
224 _communicator.min(root);
225 for (const auto n : index_range(_to_reporter_names))
226 broadcastReporter(_to_reporter_names[n], getFromMultiApp()->problemBase(), root);
227 }
228 }
229
231 for (const auto n : index_range(_to_reporter_names))
232 {
233 // Perform summing operation that makes sure all procs have the correct
234 // Reporter values.
236 }
237}
238
239void
241{
242 TIME_SECTION("MultiAppReporterTransfer::execute()", 5, "Transferring reporters");
243
246 else
248}
249
250void
252{
253
255 paramError("distribute_reporter_vector",
256 "Distributing reporter vectors is not implemented with sibling transfers.");
257
258 // Check that we are in the supported configuration: same number of source and target apps
259 // The allocation of the child apps on the processors must be the same
260 if (getFromMultiApp()->numGlobalApps() == getToMultiApp()->numGlobalApps())
261 {
262 for (const auto i : make_range(getToMultiApp()->numGlobalApps()))
263 if (getFromMultiApp()->hasLocalApp(i) + getToMultiApp()->hasLocalApp(i) == 1)
264 mooseError("Child application allocation on parallel processes must be the same to support "
265 "siblings reporter transfer",
266 ((getToMultiApp()->problemBase().numConcurrentMultiApps() == 1 ||
267 getFromMultiApp()->getParam<unsigned int>("execution_order_group") !=
268 getToMultiApp()->getParam<unsigned int>("execution_order_group"))
269 ? ""
270 : "\nConcurrent execution of the target and source multiapps is preventing "
271 "rank assignments to match. You will have to separate the "
272 "'execution_order_group' of the two applications, or have this feature "
273 "implemented."));
274 }
275 else
276 mooseError("Number of source and target child apps must match for siblings transfer");
277}
278
279// Helper function to check reporter modes
280void
282 const std::shared_ptr<MultiApp> & main_app,
283 const std::vector<ReporterName> & main_app_rep_names,
284 const std::vector<ReporterName> & sub_app_rep_names)
285{
286 // Set reporter transfer modes for the main app.
287 for (const auto & rn : main_app_rep_names)
288 addReporterTransferMode(rn, REPORTER_MODE_REPLICATED, main_app->problemBase());
289
290 std::vector<unsigned int> indices(main_app->numGlobalApps());
291 std::iota(indices.begin(), indices.end(), 0);
292
293 // Set reporter transfer modes for sub app.
294 // Setting to ROOT means this works for ROOT and REPLICATED reports with no
295 // change to users.
296 for (const auto & ind : indices)
297 if (main_app->hasLocalApp(ind))
298 for (const auto & rn : sub_app_rep_names)
299 addReporterTransferMode(rn, REPORTER_MODE_ROOT, main_app->appProblemBase(ind));
300}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
registerMooseObject("MooseApp", MultiAppReporterTransfer)
const ReporterMode REPORTER_MODE_REPLICATED
const ReporterMode REPORTER_MODE_ROOT
void ErrorVector unsigned int
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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.
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...
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 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:457
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
Transfer for migrating reporter values between the main and sub-application(s).
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.
virtual void execute() override
Execute the transfer.
bool _distribute_reporter_vector
determines transfer type
MultiAppReporterTransfer(const InputParameters &parameters)
const std::vector< ReporterName > & _to_reporter_names
Vector of reporters to transfer data to.
static InputParameters validParams()
virtual void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
virtual void checkSiblingsTransferSupported() const override
Whether the transfer supports siblings transfer.
const std::vector< ReporterName > & _from_reporter_names
Vector of reporters to transfer data from.
const unsigned int & _subapp_index
If set, indicates a particular subapp to transfer the reporter to/from.
Base class for all MultiAppTransfer objects.
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
bool hasToMultiApp() const
Whether the transfer owns a non-null to_multi_app.
const std::shared_ptr< MultiApp > getToMultiApp() const
Get the MultiApp to transfer data to.
static InputParameters validParams()
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
bool hasFromMultiApp() const
Whether the transfer owns a non-null from_multi_app.
bool isValueSet(const std::string &value) const
Methods for seeing if a value is set in the MultiMooseEnum.
unsigned int size() const
Return the number of active items in the MultiMooseEnum.
The Reporter system is comprised of objects that can contain any number of data values.
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)
void transferReporter(const ReporterName &from_reporter, const ReporterName &to_reporter, const FEProblemBase &from_problem, FEProblemBase &to_problem, unsigned int time_index=0)
void broadcastReporter(const ReporterName &name, FEProblemBase &problem, processor_id_type root)
void resizeReporter(const ReporterName &name, FEProblemBase &problem, dof_id_type n)
void clearVectorReporter(const ReporterName &name, FEProblemBase &problem)
void addReporterTransferMode(const ReporterName &name, const ReporterMode &mode, FEProblemBase &problem)
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)
static InputParameters validParams()
void sumVectorReporter(const ReporterName &name, FEProblemBase &problem)
void min(const T &r, T &o, Request &req) const
@ FROM_MULTIAPP
Definition Transfer.h:71
@ TO_MULTIAPP
Definition Transfer.h:70
MultiMooseEnum _directions
The directions this Transfer is to be executed on.
Definition Transfer.h:113
MooseEnum _current_direction
Definition Transfer.h:109
const Parallel::Communicator & _communicator
processor_id_type processor_id() const