https://mooseframework.inl.gov
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 {
27  params.addClassDescription(
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 
56  if (!_reduction_type.isValid())
57  mooseError("In MultiAppPostprocessorTransfer, must specify 'reduction_type' if direction = "
58  "from_multiapp");
59 
60  if (isParamValid("to_multi_app") && isParamValid("from_multi_app") &&
61  isParamValid("reduction_type"))
62  mooseError("Reductions are not supported for multiapp sibling transfers");
63 }
64 
65 void
67 {
68  TIME_SECTION("MultiAppPostprocessorTransfer::execute()", 5, "Transferring a postprocessor");
69 
70  // Execute the postprocessor if it was specified to execute on TRANSFER
71  switch (_current_direction)
72  {
73  case TO_MULTIAPP:
74  {
78  break;
79  }
80  case FROM_MULTIAPP:
81  case BETWEEN_MULTIAPP:
83  }
84 
85  switch (_current_direction)
86  {
87  case BETWEEN_MULTIAPP:
88  for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++)
89  {
90  // Get source postprocessor value
92  if (getFromMultiApp()->hasLocalApp(i))
93  {
94  FEProblemBase & from_problem = getFromMultiApp()->appProblemBase(i);
95  pp_value = from_problem.getPostprocessorValueByName(_from_pp_name);
96  }
97 
98  // Find the postprocessor value from another process
99  if (getFromMultiApp()->numGlobalApps() == 1)
100  _communicator.min(pp_value);
101  else
102  mooseAssert(pp_value != std::numeric_limits<Real>::max() ||
103  !getToMultiApp()->hasLocalApp(i),
104  "Source and target app parallel distribution must be the same");
105 
106  // Case 1: a single source app, multiple target apps
107  // All target apps must be local
108  if (getFromMultiApp()->numGlobalApps() == 1)
109  for (const auto j : make_range(getToMultiApp()->numGlobalApps()))
110  {
111  if (getToMultiApp()->hasLocalApp(j))
112  getToMultiApp()->appProblemBase(j).setPostprocessorValueByName(_to_pp_name, pp_value);
113  }
114 
115  // Case 2: same number of source and target apps
116  // The allocation of the child apps on the processors must be the same
117  else if (getToMultiApp()->hasLocalApp(i))
118  getToMultiApp()->appProblemBase(i).setPostprocessorValueByName(_to_pp_name, pp_value);
119  }
120  break;
121  case TO_MULTIAPP:
122  {
123  FEProblemBase & from_problem = getToMultiApp()->problemBase();
124 
125  const Real & pp_value = from_problem.getPostprocessorValueByName(_from_pp_name);
126 
127  for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++)
128  if (getToMultiApp()->hasLocalApp(i))
129  getToMultiApp()->appProblemBase(i).setPostprocessorValueByName(_to_pp_name, pp_value);
130  break;
131  }
132  case FROM_MULTIAPP:
133  {
134  FEProblemBase & to_problem = getFromMultiApp()->problemBase();
135 
136  Real reduced_pp_value;
137  switch (_reduction_type)
138  {
139  case AVERAGE:
140  case SUM:
141  reduced_pp_value = 0;
142  break;
143  case MAXIMUM:
144  reduced_pp_value = -std::numeric_limits<Real>::max();
145  break;
146  case MINIMUM:
147  reduced_pp_value = std::numeric_limits<Real>::max();
148  break;
149  default:
150  mooseError(
151  "Can't get here unless someone adds a new enum and fails to add it to this switch");
152  }
153 
154  const auto multi_app = hasFromMultiApp() ? getFromMultiApp() : getToMultiApp();
155 
156  for (unsigned int i = 0; i < multi_app->numGlobalApps(); i++)
157  {
158  if (multi_app->hasLocalApp(i) && multi_app->isRootProcessor())
159  {
160  const Real & curr_pp_value =
161  multi_app->appProblemBase(i).getPostprocessorValueByName(_from_pp_name);
162  switch (_reduction_type)
163  {
164  case AVERAGE:
165  case SUM:
166  reduced_pp_value += curr_pp_value;
167  break;
168  case MAXIMUM:
169  reduced_pp_value = std::max(curr_pp_value, reduced_pp_value);
170  break;
171  case MINIMUM:
172  reduced_pp_value = std::min(curr_pp_value, reduced_pp_value);
173  break;
174  default:
175  mooseError("Can't get here unless someone adds a new enum and fails to add it to "
176  "this switch");
177  }
178  }
179  }
180 
181  switch (_reduction_type)
182  {
183  case AVERAGE:
184  _communicator.sum(reduced_pp_value);
185  reduced_pp_value /= static_cast<Real>(multi_app->numGlobalApps());
186  break;
187  case SUM:
188  _communicator.sum(reduced_pp_value);
189  break;
190  case MAXIMUM:
191  _communicator.max(reduced_pp_value);
192  break;
193  case MINIMUM:
194  _communicator.min(reduced_pp_value);
195  break;
196  default:
197  mooseError(
198  "Can't get here unless someone adds a new enum and fails to add it to this switch");
199  }
200 
201  to_problem.setPostprocessorValueByName(_to_pp_name, reduced_pp_value);
202  break;
203  }
204  }
205 }
206 
207 void
209 {
210  // Check that we are in one of the supported configurations
211  // Case 2: same number of source and target apps
212  // The allocation of the child apps on the processors must be the same
213  if (getFromMultiApp()->numGlobalApps() == getToMultiApp()->numGlobalApps())
214  {
215  for (const auto i : make_range(getToMultiApp()->numGlobalApps()))
216  if (getFromMultiApp()->hasLocalApp(i) + getToMultiApp()->hasLocalApp(i) == 1)
217  mooseError("Child application allocation on parallel processes must be the same to support "
218  "siblings postprocessor transfer");
219  }
220  // Unsupported, we dont know how to choose a postprocessor value
221  // We could default to 'any' value is good enough in the future, but it would not be reproducible
222  // in parallel. Also every process will not necessarily have a 'source' value
223  else if (getFromMultiApp()->numGlobalApps() != 1)
224  mooseError("Number of source and target child apps must either match or only a single source "
225  "app may be used");
226 }
virtual void checkSiblingsTransferSupported() const override
Siblings transfers only supported for a single origin app.
const ExecFlagType EXEC_TRANSFER
Definition: Moose.C:55
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
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:435
MooseEnum _current_direction
Definition: Transfer.h:106
PostprocessorName _from_pp_name
Name of the postprocessor to transfer data from.
void setPostprocessorValueByName(const PostprocessorName &name, const PostprocessorValue &value, std::size_t t_index=0)
Set the value of a PostprocessorValue.
registerMooseObject("MooseApp", MultiAppPostprocessorTransfer)
static void addUserObjectExecutionCheckParam(InputParameters &params)
Add the execution order check parameter (to skip the warning if needed)
MultiAppPostprocessorTransfer(const InputParameters &parameters)
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...
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...
FEProblemBase & _fe_problem
Definition: Transfer.h:97
const std::shared_ptr< MultiApp > getToMultiApp() const
Get the MultiApp to transfer data to.
const Parallel::Communicator & _communicator
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...
auto max(const L &left, const R &right)
void errorIfObjectExecutesOnTransferInSourceApp(const std::string &object_name) const
Error if executing this MooseObject on EXEC_TRANSFER in a source multiapp (from_multiapp, e.g.
void min(const T &r, T &o, Request &req) const
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
static InputParameters validParams()
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.
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
void max(const T &r, T &o, Request &req) const
Base class for all MultiAppTransfer objects.
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:267
MooseEnum _reduction_type
Reduction operation to perform when transferring from multiple child apps to the parent app...
PostprocessorName _to_pp_name
Name of the postprocessor to transfer data to.
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...
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseBase.h:195
virtual void computeUserObjectByName(const ExecFlagType &type, const Moose::AuxGroup &group, const std::string &name)
Compute an user object with the given name.
auto min(const L &left, const R &right)
Copies the value of a Postprocessor either:
virtual void execute() override
Execute the transfer.
virtual bool isValid() const override
IsValid.
Definition: MooseEnum.h:118