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");
41  return params;
42 }
43 
45  : MultiAppTransfer(parameters),
46  _from_pp_name(getParam<PostprocessorName>("from_postprocessor")),
47  _to_pp_name(getParam<PostprocessorName>("to_postprocessor")),
48  _reduction_type(getParam<MooseEnum>("reduction_type"))
49 {
50  if (_directions.size() != 1)
51  paramError("direction", "This transfer is only unidirectional");
52 
54  if (!_reduction_type.isValid())
55  mooseError("In MultiAppPostprocessorTransfer, must specify 'reduction_type' if direction = "
56  "from_multiapp");
57 
58  if (isParamValid("to_multi_app") && isParamValid("from_multi_app") &&
59  isParamValid("reduction_type"))
60  mooseError("Reductions are not supported for multiapp sibling transfers");
61 }
62 
63 void
65 {
66  TIME_SECTION("MultiAppPostprocessorTransfer::execute()", 5, "Transferring a postprocessor");
67 
68  // Execute the postprocessor if it was specified to execute on TRANSFER
69  switch (_current_direction)
70  {
71  case TO_MULTIAPP:
72  {
75  break;
76  }
77  case FROM_MULTIAPP:
78  case BETWEEN_MULTIAPP:
80  }
81 
82  switch (_current_direction)
83  {
84  case BETWEEN_MULTIAPP:
85  for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++)
86  {
87  // Get source postprocessor value
89  if (getFromMultiApp()->hasLocalApp(i))
90  {
91  FEProblemBase & from_problem = getFromMultiApp()->appProblemBase(i);
92  pp_value = from_problem.getPostprocessorValueByName(_from_pp_name);
93  }
94 
95  // Find the postprocessor value from another process
96  if (getFromMultiApp()->numGlobalApps() == 1)
97  _communicator.min(pp_value);
98  else
99  mooseAssert(pp_value != std::numeric_limits<Real>::max() ||
100  !getToMultiApp()->hasLocalApp(i),
101  "Source and target app parallel distribution must be the same");
102 
103  // Case 1: a single source app, multiple target apps
104  // All target apps must be local
105  if (getFromMultiApp()->numGlobalApps() == 1)
106  for (const auto j : make_range(getToMultiApp()->numGlobalApps()))
107  {
108  if (getToMultiApp()->hasLocalApp(j))
109  getToMultiApp()->appProblemBase(j).setPostprocessorValueByName(_to_pp_name, pp_value);
110  }
111 
112  // Case 2: same number of source and target apps
113  // The allocation of the child apps on the processors must be the same
114  else if (getToMultiApp()->hasLocalApp(i))
115  getToMultiApp()->appProblemBase(i).setPostprocessorValueByName(_to_pp_name, pp_value);
116  }
117  break;
118  case TO_MULTIAPP:
119  {
120  FEProblemBase & from_problem = getToMultiApp()->problemBase();
121 
122  const Real & pp_value = from_problem.getPostprocessorValueByName(_from_pp_name);
123 
124  for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++)
125  if (getToMultiApp()->hasLocalApp(i))
126  getToMultiApp()->appProblemBase(i).setPostprocessorValueByName(_to_pp_name, pp_value);
127  break;
128  }
129  case FROM_MULTIAPP:
130  {
131  FEProblemBase & to_problem = getFromMultiApp()->problemBase();
132 
133  Real reduced_pp_value;
134  switch (_reduction_type)
135  {
136  case AVERAGE:
137  case SUM:
138  reduced_pp_value = 0;
139  break;
140  case MAXIMUM:
141  reduced_pp_value = -std::numeric_limits<Real>::max();
142  break;
143  case MINIMUM:
144  reduced_pp_value = std::numeric_limits<Real>::max();
145  break;
146  default:
147  mooseError(
148  "Can't get here unless someone adds a new enum and fails to add it to this switch");
149  }
150 
151  const auto multi_app = hasFromMultiApp() ? getFromMultiApp() : getToMultiApp();
152 
153  for (unsigned int i = 0; i < multi_app->numGlobalApps(); i++)
154  {
155  if (multi_app->hasLocalApp(i) && multi_app->isRootProcessor())
156  {
157  const Real & curr_pp_value =
158  multi_app->appProblemBase(i).getPostprocessorValueByName(_from_pp_name);
159  switch (_reduction_type)
160  {
161  case AVERAGE:
162  case SUM:
163  reduced_pp_value += curr_pp_value;
164  break;
165  case MAXIMUM:
166  reduced_pp_value = std::max(curr_pp_value, reduced_pp_value);
167  break;
168  case MINIMUM:
169  reduced_pp_value = std::min(curr_pp_value, reduced_pp_value);
170  break;
171  default:
172  mooseError("Can't get here unless someone adds a new enum and fails to add it to "
173  "this switch");
174  }
175  }
176  }
177 
178  switch (_reduction_type)
179  {
180  case AVERAGE:
181  _communicator.sum(reduced_pp_value);
182  reduced_pp_value /= static_cast<Real>(multi_app->numGlobalApps());
183  break;
184  case SUM:
185  _communicator.sum(reduced_pp_value);
186  break;
187  case MAXIMUM:
188  _communicator.max(reduced_pp_value);
189  break;
190  case MINIMUM:
191  _communicator.min(reduced_pp_value);
192  break;
193  default:
194  mooseError(
195  "Can't get here unless someone adds a new enum and fails to add it to this switch");
196  }
197 
198  to_problem.setPostprocessorValueByName(_to_pp_name, reduced_pp_value);
199  break;
200  }
201  }
202 }
203 
204 void
206 {
207  // Check that we are in one of the supported configurations
208  // Case 2: same number of source and target apps
209  // The allocation of the child apps on the processors must be the same
210  if (getFromMultiApp()->numGlobalApps() == getToMultiApp()->numGlobalApps())
211  {
212  for (const auto i : make_range(getToMultiApp()->numGlobalApps()))
213  if (getFromMultiApp()->hasLocalApp(i) + getToMultiApp()->hasLocalApp(i) == 1)
214  mooseError("Child application allocation on parallel processes must be the same to support "
215  "siblings postprocessor transfer");
216  }
217  // Unsupported, we dont know how to choose a postprocessor value
218  // We could default to 'any' value is good enough in the future, but it would not be reproducible
219  // in parallel. Also every process will not necessarily have a 'source' value
220  else if (getFromMultiApp()->numGlobalApps() != 1)
221  mooseError("Number of source and target child apps must either match or only a single source "
222  "app may be used");
223 }
virtual void checkSiblingsTransferSupported() const override
Siblings transfers only supported for a single origin app.
const ExecFlagType EXEC_TRANSFER
Definition: Moose.C:53
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
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)
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...
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)
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
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
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 ...
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)
MooseEnum _reduction_type
Reduction operation to perform when transferring from multiple child apps to the parent app...
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
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...
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