www.mooseframework.org
MultiAppFXTransfer.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "FEProblemBase.h"
11 #include "Function.h"
12 #include "MultiApp.h"
13 #include "UserObject.h"
14 
15 #include "MultiAppFXTransfer.h"
16 
17 registerMooseObject("FunctionalExpansionToolsApp", MultiAppFXTransfer);
18 
21 {
23 
24  params.addClassDescription("Transfers coefficient arrays between objects that are derived from "
25  "MutableCoefficientsInterface; currently includes the following "
26  "types: FunctionSeries, FXBoundaryUserObject, and FXVolumeUserObject");
27 
28  params.addRequiredParam<std::string>(
29  "this_app_object_name",
30  "Name of the MutableCoefficientsInterface-derived object in this app (LocalApp).");
31 
32  params.addRequiredParam<std::string>(
33  "multi_app_object_name",
34  "Name of the MutableCoefficientsInterface-derived object in the MultiApp.");
35 
36  return params;
37 }
38 
40  : MultiAppTransfer(parameters),
41  _this_app_object_name(getParam<std::string>("this_app_object_name")),
42  _multi_app_object_name(getParam<std::string>("multi_app_object_name")),
43  getMultiAppObject(NULL),
44  getSubAppObject(NULL)
45 {
46  if (_directions.size() != 1)
47  paramError("direction", "This transfer is only unidirectional");
48  if (hasToMultiApp() && hasFromMultiApp())
49  mooseError("This transfer does not currently support between_multiapp transfer");
50 }
51 
52 void
54 {
55  const auto multi_app = hasFromMultiApp() ? getFromMultiApp() : getToMultiApp();
56 
57  // Search for the _this_app_object_name in the LocalApp
59  scanProblemBaseForObject(multi_app->problemBase(), _this_app_object_name, "MultiApp");
60  if (getMultiAppObject == NULL)
61  mooseError(
62  "Transfer '", name(), "': Cannot find object '", _this_app_object_name, "' in MultiApp");
63 
64  // Search for the _multi_app_object_name in each of the MultiApps
65  for (std::size_t i = 0; i < multi_app->numGlobalApps(); ++i)
66  if (multi_app->hasLocalApp(i))
67  {
68  if (i == 0) // First time through, assign without checking against previous values
70  multi_app->appProblemBase(i), _multi_app_object_name, multi_app->name());
71  else if (getSubAppObject != scanProblemBaseForObject(multi_app->appProblemBase(i),
73  multi_app->name()))
74  mooseError("The name '",
76  "' is assigned to two different object types. Please modify your input file and "
77  "try again.");
78  }
79  if (getSubAppObject == NULL)
80  mooseError(
81  "Transfer '", name(), "': Cannot find object '", _multi_app_object_name, "' in SubApp");
82 }
83 
86  const std::string & object_name,
87  const std::string & app_name)
88 {
89  /*
90  * For now we are only considering Functions and UserObjects, as they are the only types currently
91  * implemented with MutableCoefficientsInterface. Others may be added later.
92  *
93  * Functions:
94  * FunctionSeries
95  *
96  * UserObjects:
97  * FXBoundaryUserObject (via FXBaseUserObject)
98  * FXVolumeUserObject (via FXBaseUserObject)
99  */
100  MutableCoefficientsInterface * interface;
101 
102  // Check to see if the object with object_name is a Function
103  if (base.hasFunction(object_name))
104  {
105  Function & function = base.getFunction(object_name);
106  interface = dynamic_cast<MutableCoefficientsInterface *>(&function);
107 
108  // Check to see if the function is a subclass of MutableCoefficientsInterface
109  if (interface)
111  else
112  mooseError("Function '",
113  object_name,
114  "' in '",
115  app_name,
116  "' does not inherit from MutableCoefficientsInterface.",
117  " Please change the function type and try again.");
118  }
119  // Check to see if the object with object_name is a UserObject
120  else if (base.hasUserObject(object_name))
121  {
122  // Get the non-const qualified UserObject, otherwise we would use getUserObject()
123  auto & user_object = base.getUserObject<UserObject>(object_name);
124  interface = dynamic_cast<MutableCoefficientsInterface *>(&user_object);
125 
126  // Check to see if the userObject is a subclass of MutableCoefficientsInterface
127  if (interface)
129  else
130  mooseError("UserObject '",
131  object_name,
132  "' in '",
133  app_name,
134  "' does not inherit from MutableCoefficientsInterface.",
135  " Please change the function type and try again.");
136  }
137 
138  return NULL;
139 }
140 
143  const std::string & object_name,
144  THREAD_ID thread)
145 {
146  return dynamic_cast<MutableCoefficientsInterface &>(base.getFunction(object_name, thread));
147 }
148 
151  const std::string & object_name,
152  THREAD_ID thread)
153 {
154  // Get the non-const qualified UserObject, otherwise we would use getUserObject()
155  auto & user_object = base.getUserObject<UserObject>(object_name, thread);
156  return dynamic_cast<MutableCoefficientsInterface &>(user_object);
157 }
158 
159 void
161 {
162  _console << "Beginning MultiAppFXTransfer: " << name() << std::endl;
163 
164  switch (_current_direction)
165  {
166  // LocalApp -> MultiApp
167  case TO_MULTIAPP:
168  {
169  // Get a reference to the object in the LocalApp
170  const MutableCoefficientsInterface & from_object =
171  (this->*getMultiAppObject)(getToMultiApp()->problemBase(), _this_app_object_name, 0);
172 
173  for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); ++i)
174  {
175  if (getToMultiApp()->hasLocalApp(i))
176  for (THREAD_ID t = 0; t < libMesh::n_threads(); ++t)
177  {
178  // Get a reference to the object in each MultiApp
179  MutableCoefficientsInterface & to_object = (this->*getSubAppObject)(
180  getToMultiApp()->appProblemBase(i), _multi_app_object_name, t);
181 
182  if (to_object.isCompatibleWith(from_object))
183  to_object.importCoefficients(from_object);
184  else
185  mooseError("'",
187  "' is not compatible with '",
189  "'");
190  }
191  }
192  break;
193  }
194 
195  // MultiApp -> LocalApp
196  case FROM_MULTIAPP:
197  {
198  /*
199  * For now we will assume that the transfers are 1:1 and the coefficients are synchronized
200  * among all instances, thus we only need to grab the set of coefficients from the first
201  * SubApp.
202  */
203  if (getFromMultiApp()->hasLocalApp(0))
204  {
205  // Get a reference to the first thread object in the first MultiApp
206  const MutableCoefficientsInterface & from_object = (this->*getSubAppObject)(
207  getFromMultiApp()->appProblemBase(0), _multi_app_object_name, 0);
208 
209  for (THREAD_ID t = 0; t < libMesh::n_threads(); ++t)
210  {
211  // Get a reference to the object in each LocalApp instance
212  MutableCoefficientsInterface & to_object = (this->*getMultiAppObject)(
213  getFromMultiApp()->problemBase(), _this_app_object_name, t);
214 
215  if (to_object.isCompatibleWith(from_object))
216  to_object.importCoefficients(from_object);
217  else
218  mooseError("'",
220  "' is not compatible with '",
222  "'");
223  }
224  }
225  break;
226  }
227  }
228 
229  _console << "Finished MultiAppFXTransfer: " << name() << std::endl;
230 }
Transfers mutable coefficient arrays between supported object types.
MutableCoefficientsInterface &(MultiAppFXTransfer::* GetProblemObject)(FEProblemBase &base, const std::string &object_name, THREAD_ID thread)
Function pointer typedef for functions used to find, convert, and return the appropriate MutableCoeff...
static InputParameters validParams()
unsigned int n_threads()
T & getUserObject(const std::string &name, unsigned int tid=0) const
const std::shared_ptr< MultiApp > getFromMultiApp() const
MooseEnum _current_direction
MutableCoefficientsInterface & getMutableCoefficientsUserOject(FEProblemBase &base, const std::string &object_name, THREAD_ID thread)
Gets a MutableCoefficientsInterface-based UserObject, intended for use via function pointer...
MultiAppFXTransfer(const InputParameters &parameters)
const std::string _this_app_object_name
Name of the MutableCoefficientsInterface-derived object in the creating app.
unsigned int size() const
const std::shared_ptr< MultiApp > getToMultiApp() const
bool hasUserObject(const std::string &name) const
const std::string _multi_app_object_name
Name of the MutableCoefficientsInterface-derived object in the MultiApp.
MutableCoefficientsInterface & getMutableCoefficientsFunction(FEProblemBase &base, const std::string &object_name, THREAD_ID thread)
Gets a MutableCoefficientsInterface-based Function, intented for use via function pointer...
bool hasFromMultiApp() const
virtual const std::string & name() const
GetProblemObject getSubAppObject
Function pointer for grabbing the SubApp object.
void addRequiredParam(const std::string &name, const std::string &doc_string)
virtual Function & getFunction(const std::string &name, const THREAD_ID tid=0)
registerMooseObject("FunctionalExpansionToolsApp", MultiAppFXTransfer)
bool isCompatibleWith(const MutableCoefficientsInterface &other) const
Checks to see if another instance is compatible.
virtual GetProblemObject scanProblemBaseForObject(FEProblemBase &base, const std::string &object_name, const std::string &app_name)
Searches an FEProblemBase for a MutableCoefficientsInterface-based object and returns a function poin...
void paramError(const std::string &param, Args... args) const
static InputParameters validParams()
MultiMooseEnum _directions
virtual void execute() override
bool hasToMultiApp() const
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
This class is designed to provide a uniform interface for any class that uses an array of coefficient...
virtual void initialSetup() override
const ConsoleStream _console
void importCoefficients(const MutableCoefficientsInterface &other)
Import the coefficients from another instance.
GetProblemObject getMultiAppObject
Function pointer for grabbing the MultiApp object.
virtual bool hasFunction(const std::string &name, const THREAD_ID tid=0)
unsigned int THREAD_ID