https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MultiAppPostprocessorTransfer.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
11
12// MOOSE includes
13#include "MooseTypes.h"
14#include "FEProblem.h"
15#include "MultiApp.h"
16
17// libMesh
18#include "libmesh/meshfree_interpolation.h"
19#include "libmesh/system.h"
20
22
25{
28 "Transfers postprocessor data between the master application and sub-application(s).");
29 params.addRequiredParam<PostprocessorName>(
30 "from_postprocessor",
31 "The name of the Postprocessor in the Master to transfer the value from.");
32 params.addRequiredParam<PostprocessorName>(
33 "to_postprocessor",
34 "The name of the Postprocessor in the MultiApp to transfer the value to. "
35 " This should most likely be a Reporter Postprocessor.");
36 MooseEnum reduction_type("average sum maximum minimum");
37 params.addParam<MooseEnum>("reduction_type",
38 reduction_type,
39 "The type of reduction to perform to reduce postprocessor "
40 "values from multiple SubApps to a single value");
42
43 return params;
44}
45
47 : MultiAppTransfer(parameters),
48 _from_pp_name(getParam<PostprocessorName>("from_postprocessor")),
49 _to_pp_name(getParam<PostprocessorName>("to_postprocessor")),
50 _reduction_type(getParam<MooseEnum>("reduction_type"))
51{
52 if (_directions.size() != 1)
53 paramError("direction", "This transfer is only unidirectional");
54
55 if (isParamValid("from_multi_app") && !isParamValid("to_multi_app") &&
56 !isParamValid("reduction_type"))
57 paramError("reduction_type",
58 "In MultiAppPostprocessorTransfer, must specify 'reduction_type' if "
59 "'from_multi_app' is set");
60
61 if (isParamValid("to_multi_app") && !isParamValid("from_multi_app") &&
62 isParamValid("reduction_type"))
63 paramError("reduction_type", "Reduction is not supported for transfer from parent application");
64
65 if (isParamValid("to_multi_app") && isParamValid("from_multi_app") &&
66 isParamValid("reduction_type"))
67 paramError("reduction_type", "Reductions are not supported for multiapp sibling transfers");
68}
69
70void
72{
73 TIME_SECTION("MultiAppPostprocessorTransfer::execute()", 5, "Transferring a postprocessor");
74
75 // Execute the postprocessor if it was specified to execute on TRANSFER
76 switch (_current_direction)
77 {
78 case TO_MULTIAPP:
79 {
83 break;
84 }
85 case FROM_MULTIAPP:
88 }
89
90 switch (_current_direction)
91 {
93 for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++)
94 {
95 // Get source postprocessor value
96 Real pp_value = std::numeric_limits<Real>::max();
97 if (getFromMultiApp()->hasLocalApp(i))
98 {
99 FEProblemBase & from_problem = getFromMultiApp()->appProblemBase(i);
100 pp_value = from_problem.getPostprocessorValueByName(_from_pp_name);
101 }
102
103 // Find the postprocessor value from another process
104 if (getFromMultiApp()->numGlobalApps() == 1)
105 _communicator.min(pp_value);
106 else
107 mooseAssert(pp_value != std::numeric_limits<Real>::max() ||
108 !getToMultiApp()->hasLocalApp(i),
109 "Source and target app parallel distribution must be the same");
110
111 // Case 1: a single source app, multiple target apps
112 // All target apps must be local
113 if (getFromMultiApp()->numGlobalApps() == 1)
114 for (const auto j : make_range(getToMultiApp()->numGlobalApps()))
115 {
116 if (getToMultiApp()->hasLocalApp(j))
117 getToMultiApp()->appProblemBase(j).setPostprocessorValueByName(_to_pp_name, pp_value);
118 }
119
120 // Case 2: same number of source and target apps
121 // The allocation of the child apps on the processors must be the same
122 else if (getToMultiApp()->hasLocalApp(i))
123 getToMultiApp()->appProblemBase(i).setPostprocessorValueByName(_to_pp_name, pp_value);
124 }
125 break;
126 case TO_MULTIAPP:
127 {
128 FEProblemBase & from_problem = getToMultiApp()->problemBase();
129
130 const Real & pp_value = from_problem.getPostprocessorValueByName(_from_pp_name);
131
132 for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++)
133 if (getToMultiApp()->hasLocalApp(i))
134 getToMultiApp()->appProblemBase(i).setPostprocessorValueByName(_to_pp_name, pp_value);
135 break;
136 }
137 case FROM_MULTIAPP:
138 {
139 FEProblemBase & to_problem = getFromMultiApp()->problemBase();
140
141 Real reduced_pp_value;
142 switch (_reduction_type)
143 {
144 case AVERAGE:
145 case SUM:
146 reduced_pp_value = 0;
147 break;
148 case MAXIMUM:
149 reduced_pp_value = -std::numeric_limits<Real>::max();
150 break;
151 case MINIMUM:
152 reduced_pp_value = std::numeric_limits<Real>::max();
153 break;
154 default:
156 "Can't get here unless someone adds a new enum and fails to add it to this switch");
157 }
158
159 const auto multi_app = hasFromMultiApp() ? getFromMultiApp() : getToMultiApp();
160
161 for (unsigned int i = 0; i < multi_app->numGlobalApps(); i++)
162 {
163 if (multi_app->hasLocalApp(i) && multi_app->isRootProcessor())
164 {
165 const Real & curr_pp_value =
166 multi_app->appProblemBase(i).getPostprocessorValueByName(_from_pp_name);
167 switch (_reduction_type)
168 {
169 case AVERAGE:
170 case SUM:
171 reduced_pp_value += curr_pp_value;
172 break;
173 case MAXIMUM:
174 reduced_pp_value = std::max(curr_pp_value, reduced_pp_value);
175 break;
176 case MINIMUM:
177 reduced_pp_value = std::min(curr_pp_value, reduced_pp_value);
178 break;
179 default:
180 mooseError("Can't get here unless someone adds a new enum and fails to add it to "
181 "this switch");
182 }
183 }
184 }
185
186 switch (_reduction_type)
187 {
188 case AVERAGE:
189 _communicator.sum(reduced_pp_value);
190 reduced_pp_value /= static_cast<Real>(multi_app->numGlobalApps());
191 break;
192 case SUM:
193 _communicator.sum(reduced_pp_value);
194 break;
195 case MAXIMUM:
196 _communicator.max(reduced_pp_value);
197 break;
198 case MINIMUM:
199 _communicator.min(reduced_pp_value);
200 break;
201 default:
203 "Can't get here unless someone adds a new enum and fails to add it to this switch");
204 }
205
206 to_problem.setPostprocessorValueByName(_to_pp_name, reduced_pp_value);
207 break;
208 }
209 }
210}
211
212void
214{
215 // Check that we are in one of the supported configurations
216 // Case 2: same number of source and target apps
217 // The allocation of the child apps on the processors must be the same
218 if (getFromMultiApp()->numGlobalApps() == getToMultiApp()->numGlobalApps())
219 {
220 for (const auto i : make_range(getToMultiApp()->numGlobalApps()))
221 if (getFromMultiApp()->hasLocalApp(i) + getToMultiApp()->hasLocalApp(i) == 1)
222 mooseError("Child application allocation on parallel processes must be the same to support "
223 "siblings postprocessor transfer");
224 }
225 // Unsupported, we dont know how to choose a postprocessor value
226 // We could default to 'any' value is good enough in the future, but it would not be reproducible
227 // in parallel. Also every process will not necessarily have a 'source' value
228 else if (getFromMultiApp()->numGlobalApps() != 1)
229 mooseError("Number of source and target child apps must either match or only a single source "
230 "app may be used");
231}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
const ExecFlagType EXEC_TRANSFER
Definition Moose.C:57
registerMooseObject("MooseApp", MultiAppPostprocessorTransfer)
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
const PostprocessorValue & getPostprocessorValueByName(const PostprocessorName &name, std::size_t t_index=0) const
Get a read-only reference to the value associated with a Postprocessor that exists.
virtual void computeUserObjectByName(const ExecFlagType &type, const Moose::AuxGroup &group, const std::string &name)
Compute an user object with the given name.
void setPostprocessorValueByName(const PostprocessorName &name, const PostprocessorValue &value, std::size_t t_index=0)
Set the value of a PostprocessorValue.
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
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
Copies the value of a Postprocessor either:
MooseEnum _reduction_type
Reduction operation to perform when transferring from multiple child apps to the parent app.
virtual void execute() override
Execute the transfer.
PostprocessorName _to_pp_name
Name of the postprocessor to transfer data to.
PostprocessorName _from_pp_name
Name of the postprocessor to transfer data from.
virtual void checkSiblingsTransferSupported() const override
Siblings transfers only supported for a single origin app.
MultiAppPostprocessorTransfer(const InputParameters &parameters)
Base class for all MultiAppTransfer objects.
void errorIfObjectExecutesOnTransferInSourceApp(const std::string &object_name) const
Error if executing this MooseObject on EXEC_TRANSFER in a source multiapp (from_multiapp,...
static void addUserObjectExecutionCheckParam(InputParameters &params)
Add the execution order check parameter (to skip the warning if needed)
void checkParentAppUserObjectExecuteOn(const std::string &object_name) const
Checks the execute_on flags for user object transfers with user objects on the source app which is al...
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.
unsigned int size() const
Return the number of active items in the MultiMooseEnum.
void max(const T &r, T &o, Request &req) const
void min(const T &r, T &o, Request &req) const
@ FROM_MULTIAPP
Definition Transfer.h:71
@ TO_MULTIAPP
Definition Transfer.h:70
@ BETWEEN_MULTIAPP
Definition Transfer.h:72
MultiMooseEnum _directions
The directions this Transfer is to be executed on.
Definition Transfer.h:110
FEProblemBase & _fe_problem
Definition Transfer.h:97
MooseEnum _current_direction
Definition Transfer.h:106
const Parallel::Communicator & _communicator
@ POST_AUX
Definition MooseTypes.h:761
@ PRE_AUX
Definition MooseTypes.h:760