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 "Component.h"
11 : #include "THMMesh.h"
12 : #include "ThermalHydraulicsApp.h"
13 : #include "ConstantFunction.h"
14 : #include "Numerics.h"
15 : #include "RelationshipManager.h"
16 :
17 : InputParameters
18 16604 : Component::validParams()
19 : {
20 16604 : InputParameters params = THMObject::validParams();
21 16604 : params += ADFunctorInterface::validParams();
22 16604 : params.addPrivateParam<THMProblem *>("_thm_problem");
23 16604 : params.addPrivateParam<Component *>("_parent", nullptr);
24 33208 : params.addPrivateParam<std::string>("built_by_action", "add_component");
25 :
26 16604 : params.registerBase("Component");
27 :
28 16604 : return params;
29 0 : }
30 :
31 : /*
32 : * Component implementation
33 : */
34 :
35 8297 : Component::Component(const InputParameters & parameters)
36 : : THMObject(parameters),
37 16594 : LoggingInterface(getCheckedPointerParam<THMProblem *>("_thm_problem")->log()),
38 : NamingInterface(),
39 : ADFunctorInterface(this),
40 :
41 8297 : _parent(getParam<Component *>("_parent")),
42 16594 : _sim(*getCheckedPointerParam<THMProblem *>("_thm_problem")),
43 8297 : _factory(_app.getFactory()),
44 8297 : _zero(_sim._real_zero[0]),
45 8297 : _mesh(static_cast<THMMesh &>(_sim.mesh())),
46 24891 : _component_setup_status(CREATED)
47 : {
48 8297 : }
49 :
50 : const std::string &
51 351 : Component::cname() const
52 : {
53 351 : if (_parent)
54 : return _parent->cname();
55 : else
56 : return name();
57 : }
58 :
59 : THMMesh &
60 942418 : Component::mesh()
61 : {
62 942418 : if (_component_setup_status >= MESH_PREPARED)
63 0 : mooseError(
64 : "A non-const reference to the THM mesh cannot be obtained after mesh setup is complete.");
65 : else
66 942418 : return _mesh;
67 : }
68 :
69 : void
70 8219 : Component::executeInit()
71 : {
72 8219 : init();
73 8217 : _component_setup_status = INITIALIZED_PRIMARY;
74 8217 : }
75 :
76 : void
77 8217 : Component::executeInitSecondary()
78 : {
79 8217 : initSecondary();
80 8217 : _component_setup_status = INITIALIZED_SECONDARY;
81 8217 : }
82 :
83 : void
84 8082 : Component::executeCheck() const
85 : {
86 8082 : check();
87 8082 : _component_setup_status = CHECKED;
88 8082 : }
89 :
90 : void
91 8295 : Component::executeSetupMesh()
92 : {
93 8295 : setupMesh();
94 8295 : _component_setup_status = MESH_PREPARED;
95 8295 : }
96 :
97 : void
98 2868 : Component::connectObject(const InputParameters & obj_params,
99 : const std::string & obj_name,
100 : const std::string & param) const
101 : {
102 2868 : connectObject(obj_params, obj_name, param, param);
103 2868 : }
104 :
105 : void
106 5405 : Component::connectObject(const InputParameters & obj_params,
107 : const std::string & obj_name,
108 : const std::string & comp_param,
109 : const std::string & obj_param) const
110 : {
111 10810 : MooseObjectParameterName alias("component", this->name(), comp_param, "::");
112 5405 : MooseObjectParameterName obj_controlled_param(obj_params.getBase(), obj_name, obj_param);
113 5405 : _app.getInputParameterWarehouse().addControllableParameterAlias(alias, obj_controlled_param);
114 5405 : }
115 :
116 : void
117 176595 : Component::checkSetupStatus(const EComponentSetupStatus & status) const
118 : {
119 176595 : if (_component_setup_status < status)
120 2 : mooseError(name(),
121 : ": The component setup status (",
122 2 : stringify(_component_setup_status),
123 : ") is less than the required status (",
124 2 : stringify(status),
125 : ")");
126 176593 : }
127 :
128 : void
129 5627 : Component::addDependency(const std::string & dependency)
130 : {
131 5627 : _dependencies.push_back(dependency);
132 5627 : }
133 :
134 : THMProblem &
135 128222 : Component::getTHMProblem() const
136 : {
137 128222 : return _sim;
138 : }
139 :
140 : void
141 0 : Component::checkComponentExistsByName(const std::string & comp_name) const
142 : {
143 0 : if (!_sim.hasComponent(comp_name))
144 0 : logError("The component '", comp_name, "' does not exist");
145 0 : }
146 :
147 : void
148 21 : Component::addRelationshipManagersFromParameters(const InputParameters & moose_object_pars)
149 : {
150 21 : const auto & buildable_types = moose_object_pars.getBuildableRelationshipManagerTypes();
151 :
152 21 : for (const auto & buildable_type : buildable_types)
153 : {
154 : auto & rm_name = std::get<0>(buildable_type);
155 : auto & rm_type = std::get<1>(buildable_type);
156 0 : auto rm_input_parameter_func = std::get<2>(buildable_type);
157 :
158 0 : addRelationshipManager(moose_object_pars, rm_name, rm_type, rm_input_parameter_func);
159 : }
160 21 : }
161 :
162 : void
163 0 : Component::addRelationshipManager(
164 : const InputParameters & moose_object_pars,
165 : std::string rm_name,
166 : Moose::RelationshipManagerType rm_type,
167 : Moose::RelationshipManagerInputParameterCallback rm_input_parameter_func,
168 : Moose::RMSystemType)
169 : {
170 : // These need unique names
171 : static unsigned int unique_object_id = 0;
172 :
173 0 : auto new_name = moose_object_pars.getBase() + '_' + name() + '_' + rm_name + "_" +
174 0 : Moose::stringify(rm_type) + " " + std::to_string(unique_object_id);
175 :
176 0 : auto rm_params = _factory.getValidParams(rm_name);
177 0 : rm_params.set<Moose::RelationshipManagerType>("rm_type") = rm_type;
178 :
179 0 : rm_params.set<std::string>("for_whom") = name();
180 :
181 : // If there is a callback for setting the RM parameters let's use it
182 0 : if (rm_input_parameter_func)
183 0 : rm_input_parameter_func(moose_object_pars, rm_params);
184 :
185 0 : rm_params.set<MooseMesh *>("mesh") = &_mesh;
186 :
187 0 : if (!rm_params.areAllRequiredParamsValid())
188 0 : mooseError("Missing required parameters for RelationshipManager " + rm_name + " for object " +
189 : name());
190 :
191 0 : auto rm_obj = _factory.create<RelationshipManager>(rm_name, new_name, rm_params);
192 :
193 0 : const bool added = _app.addRelationshipManager(rm_obj);
194 :
195 : // Delete the resources created on behalf of the RM if it ends up not being added to the App.
196 0 : if (!added)
197 0 : _factory.releaseSharedObjects(*rm_obj);
198 : else // we added it
199 0 : unique_object_id++;
200 0 : }
201 :
202 : Node *
203 297468 : Component::addNode(const Point & pt)
204 : {
205 297468 : auto node = mesh().addNode(pt);
206 297468 : _node_ids.push_back(node->id());
207 297468 : return node;
208 : }
209 :
210 : Elem *
211 587 : Component::addNodeElement(dof_id_type node)
212 : {
213 587 : auto elem = mesh().addNodeElement(node);
214 587 : _elem_ids.push_back(elem->id());
215 587 : return elem;
216 : }
217 :
218 : void
219 4272 : Component::setSubdomainInfo(SubdomainID subdomain_id,
220 : const std::string & subdomain_name,
221 : const Moose::CoordinateSystemType & coord_system)
222 : {
223 4272 : _subdomain_ids.push_back(subdomain_id);
224 4272 : _subdomain_names.push_back(subdomain_name);
225 4272 : _coord_sys.push_back(coord_system);
226 4272 : if (_parent)
227 : {
228 0 : _parent->_subdomain_ids.push_back(subdomain_id);
229 0 : _parent->_subdomain_names.push_back(subdomain_name);
230 0 : _parent->_coord_sys.push_back(coord_system);
231 : }
232 4272 : mesh().setSubdomainName(subdomain_id, subdomain_name);
233 4272 : }
234 :
235 : void
236 6830 : Component::addNonlinearStepFunctorMaterial(const std::string & functor_name,
237 : const std::string & property,
238 : bool functor_is_ad)
239 : {
240 : const std::string class_name =
241 12941 : functor_is_ad ? "ADFunctorChangeFunctorMaterial" : "FunctorChangeFunctorMaterial";
242 6830 : InputParameters params = _factory.getValidParams(class_name);
243 13660 : params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
244 13660 : params.set<MooseFunctorName>("functor") = functor_name;
245 13660 : params.set<MooseEnum>("change_over") = "nonlinear";
246 6830 : params.set<std::string>("prop_name") = property;
247 6830 : params.set<bool>("take_absolute_value") = true;
248 13660 : getTHMProblem().addFunctorMaterial(class_name, genName(name(), property + "_fmat"), params);
249 13660 : }
250 :
251 : void
252 7182 : Component::addMaximumFunctorPostprocessor(const std::string & functor_name,
253 : const std::string & pp_name,
254 : const Real normalization,
255 : const std::vector<SubdomainName> & subdomains)
256 : {
257 7182 : const std::string class_name = "ElementExtremeFunctorValue";
258 7182 : InputParameters params = _factory.getValidParams(class_name);
259 7182 : params.set<std::vector<SubdomainName>>("block") = subdomains;
260 14364 : params.set<MooseEnum>("value_type") = "max";
261 14364 : params.set<MooseFunctorName>("functor") = functor_name;
262 7182 : params.set<Real>("scale") = 1.0 / normalization;
263 14364 : params.set<ExecFlagEnum>("execute_on") = EXEC_NONLINEAR_CONVERGENCE;
264 21546 : params.set<std::vector<OutputName>>("outputs") = {"none"};
265 7182 : getTHMProblem().addPostprocessor(class_name, pp_name, params);
266 14364 : }
267 :
268 : void
269 2756 : Component::addMultiPostprocessorConvergence(const std::vector<PostprocessorName> & postprocessors,
270 : const std::vector<std::string> & descriptions,
271 : const std::vector<Real> & tolerances)
272 : {
273 2756 : const std::string class_name = "MultiPostprocessorConvergence";
274 2756 : InputParameters params = _factory.getValidParams(class_name);
275 2756 : params.set<std::vector<PostprocessorName>>("postprocessors") = postprocessors;
276 2756 : params.set<std::vector<std::string>>("descriptions") = descriptions;
277 2756 : params.set<std::vector<Real>>("tolerances") = tolerances;
278 2756 : params.set<unsigned int>("min_iterations") = 1;
279 2756 : params.set<unsigned int>("max_iterations") = std::numeric_limits<unsigned int>::max();
280 2756 : getTHMProblem().addConvergence(class_name, nonlinearConvergenceName(), params);
281 5512 : }
282 :
283 : void
284 161 : Component::checkMutuallyExclusiveParameters(const std::vector<std::string> & params,
285 : bool need_one_specified) const
286 : {
287 : unsigned int n_provided_params = 0;
288 483 : for (const auto & param : params)
289 322 : if (isParamValid(param))
290 161 : n_provided_params++;
291 :
292 161 : if (n_provided_params != 1)
293 : {
294 0 : std::string params_list_string = "{'" + params[0] + "'";
295 0 : for (unsigned int i = 1; i < params.size(); ++i)
296 0 : params_list_string += ", '" + params[i] + "'";
297 : params_list_string += "}";
298 :
299 0 : if (n_provided_params == 0 && need_one_specified)
300 0 : logError("One of the parameters ", params_list_string, " must be provided");
301 :
302 0 : if (n_provided_params != 0)
303 0 : logError("Only one of the parameters ", params_list_string, " can be provided");
304 : }
305 161 : }
306 :
307 : /// Return a string for the setup status
308 : std::string
309 4 : Component::stringify(EComponentSetupStatus status) const
310 : {
311 4 : switch (status)
312 : {
313 : case CREATED:
314 0 : return "component created";
315 : case MESH_PREPARED:
316 2 : return "component mesh set up";
317 : case INITIALIZED_PRIMARY:
318 2 : return "primary initialization completed";
319 : case INITIALIZED_SECONDARY:
320 0 : return "secondary initialization completed";
321 : case CHECKED:
322 0 : return "component fully set up and checked";
323 0 : default:
324 0 : mooseError("Should not reach here");
325 : }
326 : }
327 :
328 : const std::vector<dof_id_type> &
329 0 : Component::getNodeIDs() const
330 : {
331 0 : checkSetupStatus(MESH_PREPARED);
332 :
333 0 : return _node_ids;
334 : }
335 :
336 : const std::vector<dof_id_type> &
337 289 : Component::getElementIDs() const
338 : {
339 289 : checkSetupStatus(MESH_PREPARED);
340 :
341 289 : return _elem_ids;
342 : }
343 :
344 : const std::vector<SubdomainName> &
345 145580 : Component::getSubdomainNames() const
346 : {
347 145580 : checkSetupStatus(MESH_PREPARED);
348 :
349 145580 : return _subdomain_names;
350 : }
351 :
352 : const std::vector<Moose::CoordinateSystemType> &
353 8225 : Component::getCoordSysTypes() const
354 : {
355 8225 : checkSetupStatus(MESH_PREPARED);
356 :
357 8225 : return _coord_sys;
358 : }
359 :
360 : Convergence *
361 0 : Component::getNonlinearConvergence() const
362 : {
363 0 : mooseError("getNonlinearConvergence() not implemented.");
364 : }
|