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 
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 
70 void
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:
86  case BETWEEN_MULTIAPP:
88  }
89 
90  switch (_current_direction)
91  {
92  case BETWEEN_MULTIAPP:
93  for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++)
94  {
95  // Get source postprocessor value
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:
155  mooseError(
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:
202  mooseError(
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 
212 void
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 }
virtual void checkSiblingsTransferSupported() const override
Siblings transfers only supported for a single origin app.
const ExecFlagType EXEC_TRANSFER
Definition: Moose.C:57
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:457
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:54
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:271
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:199
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.