Line data Source code
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 :
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 :
19 : InputParameters
20 458 : MultiAppFXTransfer::validParams()
21 : {
22 458 : InputParameters params = MultiAppTransfer::validParams();
23 :
24 458 : 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 916 : params.addRequiredParam<std::string>(
29 : "this_app_object_name",
30 : "Name of the MutableCoefficientsInterface-derived object in this app (LocalApp).");
31 :
32 916 : params.addRequiredParam<std::string>(
33 : "multi_app_object_name",
34 : "Name of the MutableCoefficientsInterface-derived object in the MultiApp.");
35 :
36 458 : return params;
37 0 : }
38 :
39 229 : MultiAppFXTransfer::MultiAppFXTransfer(const InputParameters & parameters)
40 : : MultiAppTransfer(parameters),
41 229 : _this_app_object_name(getParam<std::string>("this_app_object_name")),
42 458 : _multi_app_object_name(getParam<std::string>("multi_app_object_name")),
43 229 : getMultiAppObject(NULL),
44 229 : getSubAppObject(NULL)
45 : {
46 229 : if (_directions.size() != 1)
47 0 : paramError("direction", "This transfer is only unidirectional");
48 229 : if (hasToMultiApp() && hasFromMultiApp())
49 0 : mooseError("This transfer does not currently support between_multiapp transfer");
50 229 : }
51 :
52 : void
53 221 : MultiAppFXTransfer::initialSetup()
54 : {
55 221 : const auto multi_app = hasFromMultiApp() ? getFromMultiApp() : getToMultiApp();
56 :
57 : // Search for the _this_app_object_name in the LocalApp
58 : getMultiAppObject =
59 221 : scanProblemBaseForObject(multi_app->problemBase(), _this_app_object_name, "MultiApp");
60 217 : if (getMultiAppObject == NULL)
61 2 : 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 430 : for (std::size_t i = 0; i < multi_app->numGlobalApps(); ++i)
66 215 : if (multi_app->hasLocalApp(i))
67 : {
68 215 : if (i == 0) // First time through, assign without checking against previous values
69 215 : getSubAppObject = scanProblemBaseForObject(
70 215 : multi_app->appProblemBase(i), _multi_app_object_name, multi_app->name());
71 0 : else if (getSubAppObject != scanProblemBaseForObject(multi_app->appProblemBase(i),
72 0 : _multi_app_object_name,
73 0 : multi_app->name()))
74 0 : mooseError("The name '",
75 : _multi_app_object_name,
76 : "' is assigned to two different object types. Please modify your input file and "
77 : "try again.");
78 : }
79 215 : if (getSubAppObject == NULL)
80 2 : mooseError(
81 2 : "Transfer '", name(), "': Cannot find object '", _multi_app_object_name, "' in SubApp");
82 213 : }
83 :
84 : MultiAppFXTransfer::GetProblemObject
85 436 : MultiAppFXTransfer::scanProblemBaseForObject(FEProblemBase & base,
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 436 : if (base.hasFunction(object_name))
104 : {
105 215 : Function & function = base.getFunction(object_name);
106 215 : interface = dynamic_cast<MutableCoefficientsInterface *>(&function);
107 :
108 : // Check to see if the function is a subclass of MutableCoefficientsInterface
109 215 : if (interface)
110 213 : return &MultiAppFXTransfer::getMutableCoefficientsFunction;
111 : else
112 2 : 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 221 : else if (base.hasUserObject(object_name))
121 : {
122 : // Get the non-const qualified UserObject, otherwise we would use getUserObject()
123 217 : auto & user_object = base.getUserObject<UserObject>(object_name);
124 217 : interface = dynamic_cast<MutableCoefficientsInterface *>(&user_object);
125 :
126 : // Check to see if the userObject is a subclass of MutableCoefficientsInterface
127 217 : if (interface)
128 215 : return &MultiAppFXTransfer::getMutableCoefficientsUserOject;
129 : else
130 2 : 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 4 : return NULL;
139 : }
140 :
141 : MutableCoefficientsInterface &
142 18428 : MultiAppFXTransfer::getMutableCoefficientsFunction(FEProblemBase & base,
143 : const std::string & object_name,
144 : THREAD_ID thread)
145 : {
146 18428 : return dynamic_cast<MutableCoefficientsInterface &>(base.getFunction(object_name, thread));
147 : }
148 :
149 : MutableCoefficientsInterface &
150 14360 : MultiAppFXTransfer::getMutableCoefficientsUserOject(FEProblemBase & base,
151 : const std::string & object_name,
152 : THREAD_ID thread)
153 : {
154 : // Get the non-const qualified UserObject, otherwise we would use getUserObject()
155 14360 : auto & user_object = base.getUserObject<UserObject>(object_name, thread);
156 14360 : return dynamic_cast<MutableCoefficientsInterface &>(user_object);
157 : }
158 :
159 : void
160 14360 : MultiAppFXTransfer::execute()
161 : {
162 14360 : _console << "Beginning MultiAppFXTransfer: " << name() << std::endl;
163 :
164 14360 : switch (_current_direction)
165 : {
166 : // LocalApp -> MultiApp
167 6970 : case TO_MULTIAPP:
168 : {
169 : // Get a reference to the object in the LocalApp
170 : const MutableCoefficientsInterface & from_object =
171 6970 : (this->*getMultiAppObject)(getToMultiApp()->problemBase(), _this_app_object_name, 0);
172 :
173 27876 : for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); ++i)
174 : {
175 6970 : if (getToMultiApp()->hasLocalApp(i))
176 15761 : for (THREAD_ID t = 0; t < libMesh::n_threads(); ++t)
177 : {
178 : // Get a reference to the object in each MultiApp
179 17586 : MutableCoefficientsInterface & to_object = (this->*getSubAppObject)(
180 8793 : getToMultiApp()->appProblemBase(i), _multi_app_object_name, t);
181 :
182 8793 : if (to_object.isCompatibleWith(from_object))
183 8791 : to_object.importCoefficients(from_object);
184 : else
185 2 : mooseError("'",
186 : _multi_app_object_name,
187 : "' is not compatible with '",
188 : _this_app_object_name,
189 : "'");
190 : }
191 : }
192 : break;
193 : }
194 :
195 : // MultiApp -> LocalApp
196 7390 : 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 14780 : if (getFromMultiApp()->hasLocalApp(0))
204 : {
205 : // Get a reference to the first thread object in the first MultiApp
206 14780 : const MutableCoefficientsInterface & from_object = (this->*getSubAppObject)(
207 7390 : getFromMultiApp()->appProblemBase(0), _multi_app_object_name, 0);
208 :
209 17025 : for (THREAD_ID t = 0; t < libMesh::n_threads(); ++t)
210 : {
211 : // Get a reference to the object in each LocalApp instance
212 19270 : MutableCoefficientsInterface & to_object = (this->*getMultiAppObject)(
213 9635 : getFromMultiApp()->problemBase(), _this_app_object_name, t);
214 :
215 9635 : if (to_object.isCompatibleWith(from_object))
216 9635 : to_object.importCoefficients(from_object);
217 : else
218 0 : mooseError("'",
219 : _multi_app_object_name,
220 : "' is not compatible with '",
221 : _this_app_object_name,
222 : "'");
223 : }
224 : }
225 : break;
226 : }
227 : }
228 :
229 14358 : _console << "Finished MultiAppFXTransfer: " << name() << std::endl;
230 14358 : }
|