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 : #pragma once
11 :
12 : #include "ThermalHydraulicsApp.h"
13 : #include "FlowModel.h"
14 : #include "Logger.h"
15 : #include "ControlData.h"
16 : #include "LoggingInterface.h"
17 : #include "NamingInterface.h"
18 : #include "libmesh/parallel_object.h"
19 :
20 : class ActionWarehouse;
21 : class Component;
22 : class ClosuresBase;
23 : class THMMesh;
24 : class THMProblem;
25 :
26 : /**
27 : * Main class for simulation (the driver of the simulation)
28 : */
29 : class Simulation : public libMesh::ParallelObject, public LoggingInterface, public NamingInterface
30 : {
31 : public:
32 : /**
33 : * Sets a component variable order index.
34 : *
35 : * See Component system documentation for more information.
36 : *
37 : * @param[in] var Variable to order
38 : * @param[in] index Order index
39 : */
40 : static void setComponentVariableOrder(const VariableName & var, int index);
41 :
42 : Simulation(FEProblemBase & fe_problem, const InputParameters & params);
43 : virtual ~Simulation();
44 :
45 : /**
46 : * Gets the FE type for the flow in this simulation
47 : */
48 5147 : const libMesh::FEType & getFlowFEType() const { return _flow_fe_type; }
49 :
50 : /**
51 : * Sets up quadrature rules
52 : */
53 : virtual void setupQuadrature();
54 :
55 : /**
56 : * Initialize this simulation
57 : */
58 : virtual void initSimulation();
59 :
60 : /**
61 : * Initialize this simulation's components
62 : */
63 : virtual void initComponents();
64 :
65 : /**
66 : * Identifies the component loops
67 : */
68 : void identifyLoops();
69 :
70 : /**
71 : * Prints the component loops
72 : */
73 : void printComponentLoops() const;
74 :
75 : /**
76 : * Run the simulation
77 : */
78 : virtual void run();
79 :
80 : /**
81 : * Add a component into this simulation
82 : * @param type Type (the registered class name) of the component
83 : * @param name Name of the component
84 : * @param params Input parameters
85 : */
86 : virtual void
87 : addComponent(const std::string & type, const std::string & name, InputParameters params);
88 :
89 : /**
90 : * Find out if simulation has a component with the given name
91 : * @param name The name of the component
92 : * @return true if the components exists, otherwise false
93 : */
94 : bool hasComponent(const std::string & name) const;
95 :
96 : /**
97 : * Find out if simulation has a component with the given name and specified type
98 : * @tparam T the type of the component we are requesting
99 : * @param name The name of the component
100 : * @return true if the component exists and has specified type, otherwise false
101 : */
102 : template <typename T>
103 : bool hasComponentOfType(const std::string & name) const;
104 :
105 : /**
106 : * Get component by its name
107 : * @tparam T the type of the component we are requesting
108 : * @param name The name of the component
109 : * @return Pointer to the component if found, otherwise throws and error
110 : */
111 : template <typename T>
112 : const T & getComponentByName(const std::string & name) const;
113 :
114 : /**
115 : * Return list of components available in the simulation
116 : */
117 : const std::vector<std::shared_ptr<Component>> & getComponents() { return _components; }
118 :
119 : /**
120 : * Add a closures object into this simulation
121 : *
122 : * @param[in] type Closures class name
123 : * @param[in] name Closures object name
124 : * @param[in] params Input parameters
125 : */
126 : virtual void
127 : addClosures(const std::string & type, const std::string & name, InputParameters params);
128 :
129 : /**
130 : * Return whether the simulation has a closures object
131 : *
132 : * @param[in] name Closures object name
133 : */
134 : bool hasClosures(const std::string & name) const;
135 :
136 : /**
137 : * Get a pointer to a closures object
138 : *
139 : * @param[in] name Closures object name
140 : */
141 : std::shared_ptr<ClosuresBase> getClosures(const std::string & name) const;
142 :
143 : /**
144 : * Queues a variable of type MooseVariableScalar to be added to the nonlinear or aux system.
145 : *
146 : * @param[in] nl True if this is a nonlinear (solution) variable
147 : * @param[in] name Name of the variable
148 : * @param[in] fe_type FEType of the variable
149 : * @param[in] scaling_factor Scaling factor for the variable
150 : */
151 : void addSimVariable(bool nl,
152 : const VariableName & name,
153 : libMesh::FEType fe_type,
154 : Real scaling_factor = 1.0);
155 :
156 : /**
157 : * Queues a variable of type MooseVariable to be added to the nonlinear or aux system.
158 : *
159 : * @param[in] nl True if this is a nonlinear (solution) variable
160 : * @param[in] name Name of the variable
161 : * @param[in] fe_type FEType of the variable
162 : * @param[in] subdomain_names List of subdomain names to add the variable to
163 : * @param[in] scaling_factor Scaling factor for the variable
164 : */
165 : void addSimVariable(bool nl,
166 : const VariableName & name,
167 : libMesh::FEType fe_type,
168 : const std::vector<SubdomainName> & subdomain_names,
169 : Real scaling_factor = 1.0);
170 :
171 : /**
172 : * Queues a generic variable to be added to the nonlinear or aux system.
173 : *
174 : * @param[in] nl True if this is a nonlinear (solution) variable
175 : * @param[in] var_type Type (class) of the variable
176 : * @param[in] name Name of the variable
177 : * @param[in] params Input parameters for the variable
178 : */
179 : void addSimVariable(bool nl,
180 : const std::string & var_type,
181 : const VariableName & name,
182 : const InputParameters & params);
183 :
184 : /**
185 : * Reports an error if the variable name is too long
186 : */
187 : void checkVariableNameLength(const std::string & name) const;
188 :
189 : void addConstantIC(const VariableName & var_name,
190 : Real value,
191 : const std::vector<SubdomainName> & block_names);
192 : void addFunctionIC(const VariableName & var_name,
193 : const std::string & func_name,
194 : const std::vector<SubdomainName> & block_names);
195 : void addConstantScalarIC(const VariableName & var_name, Real value);
196 : void addComponentScalarIC(const VariableName & var_name, const std::vector<Real> & value);
197 :
198 : void addSimInitialCondition(const std::string & type,
199 : const std::string & name,
200 : InputParameters params);
201 :
202 : /**
203 : * Add a control
204 : * @param type Type (registered name) of the control
205 : * @param name Name of the control
206 : * @param params Input parameters
207 : */
208 : void addControl(const std::string & type, const std::string & name, InputParameters params);
209 :
210 : void addFileOutputter(const std::string & name);
211 : void addScreenOutputter(const std::string & name);
212 :
213 : /**
214 : * Gets the vector of output names corresponding to a 1-word key string
215 : *
216 : * @param[in] key string key that corresponds to an output names vector
217 : * @returns output names vector corresponding to key
218 : */
219 : std::vector<OutputName> getOutputsVector(const std::string & key) const;
220 :
221 : /**
222 : * Create mesh for this simulation
223 : */
224 : virtual void buildMesh();
225 :
226 : /**
227 : * Add variables involved in this simulation
228 : */
229 : virtual void addVariables();
230 :
231 : /**
232 : * Add component MOOSE objects
233 : */
234 : virtual void addMooseObjects();
235 :
236 : /**
237 : * Perform mesh setup actions such as setting up the coordinate system(s) and
238 : * creating ghosted elements.
239 : */
240 : virtual void setupMesh();
241 :
242 : /**
243 : * Get the ThermalHydraulicsApp
244 : */
245 3735 : ThermalHydraulicsApp & getApp() { return _thm_app; }
246 :
247 : /**
248 : * Check the integrity of the simulation
249 : */
250 : virtual void integrityCheck() const;
251 :
252 : /**
253 : * Advance all of the state holding vectors / datastructures so that we can move to the next
254 : * timestep.
255 : */
256 : virtual void advanceState();
257 :
258 : /**
259 : * Check the integrity of the control data
260 : */
261 : virtual void controlDataIntegrityCheck();
262 :
263 : /**
264 : * Check integrity of coupling matrix used by the preconditioner
265 : */
266 : virtual void couplingMatrixIntegrityCheck() const;
267 :
268 : /**
269 : * Query if control data with name 'name' exists
270 : *
271 : * @param name The unique name of the control data
272 : * @return true if control data 'name' exists, false otherwise
273 : */
274 : template <typename T>
275 268 : bool hasControlData(const std::string & name)
276 : {
277 268 : if (_control_data.find(name) == _control_data.end())
278 : return false;
279 : else
280 156 : return dynamic_cast<ControlData<T> *>(_control_data[name]) != NULL;
281 : }
282 :
283 : /**
284 : * Get control data of type T and name 'name', if it does not exist it will be created
285 : *
286 : * @param name The unique name of the control data
287 : * @return Pointer to the control data of type T
288 : */
289 : template <typename T>
290 11264 : ControlData<T> * getControlData(const std::string & name)
291 : {
292 : ControlData<T> * data = nullptr;
293 11264 : if (_control_data.find(name) == _control_data.end())
294 : {
295 10470 : data = new ControlData<T>(_thm_app, name);
296 10470 : _control_data[name] = data;
297 : }
298 : else
299 794 : data = dynamic_cast<ControlData<T> *>(_control_data[name]);
300 :
301 11264 : return data;
302 : }
303 :
304 : /**
305 : * Declare control data of type T and name 'name', if it does not exist it will be created
306 : *
307 : * @param name The unique name of the control data
308 : * @return Pointer to the control data of type T
309 : */
310 : template <typename T>
311 10466 : ControlData<T> * declareControlData(const std::string & name, THMControl * ctrl)
312 : {
313 10466 : ControlData<T> * data = getControlData<T>(name);
314 10466 : if (!data->getDeclared())
315 : {
316 : // Mark the data for error checking
317 : data->setDeclared();
318 : data->setControl(ctrl);
319 : }
320 : else
321 : logError("Trying to declare '", name, "', but it was already declared.");
322 :
323 10466 : return data;
324 : }
325 :
326 : /**
327 : * Gets the flag indicating whether an implicit time integration scheme is being used
328 : */
329 : const bool & getImplicitTimeIntegrationFlag() { return _implicit_time_integration; }
330 :
331 : /**
332 : * Are initial conditions specified from a file
333 : *
334 : * @return true if initial conditions are specified from a file
335 : */
336 : bool hasInitialConditionsFromFile() const;
337 :
338 18268 : Logger & log() { return _log; }
339 :
340 : /**
341 : * Enable Jacobian checking
342 : *
343 : * @param state True for Jacobian checking, otherwise false
344 : */
345 130 : void setCheckJacobian(bool state) { _check_jacobian = state; }
346 :
347 : /**
348 : * Hint how to augment sparsity pattern between two elements.
349 : *
350 : * The augmentation will be symmetric
351 : */
352 : virtual void augmentSparsity(const dof_id_type & elem_id1, const dof_id_type & elem_id2);
353 :
354 : /**
355 : * Is velocity output as vector-valued field
356 : *
357 : * @return true for vector-valued field, false for scalar
358 : */
359 4160 : bool getVectorValuedVelocity() { return _output_vector_velocity; }
360 :
361 : /**
362 : * Set if velocity is being output as a vector-valued field
363 : */
364 3891 : void setVectorValuedVelocity(bool vector_velocity) { _output_vector_velocity = vector_velocity; }
365 :
366 : /**
367 : * Add additional relationship managers to run the simulation
368 : */
369 : void addRelationshipManagers();
370 :
371 : protected:
372 : /**
373 : * Variable information
374 : */
375 89290 : struct VariableInfo
376 : {
377 : /// True if the variable is a nonlinear (solution) variable; otherwise, aux
378 : bool _nl;
379 : /// Type (class) of the variable
380 : std::string _var_type;
381 : /// Input parameters
382 : InputParameters _params;
383 :
384 89290 : VariableInfo() : _params(emptyInputParameters()) {}
385 : };
386 :
387 : /// THM mesh
388 : THMMesh & _thm_mesh;
389 :
390 : /// Pointer to FEProblem representing this simulation
391 : FEProblemBase & _fe_problem;
392 :
393 : /// The application this is associated with
394 : ThermalHydraulicsApp & _thm_app;
395 :
396 : /// The Factory associated with the MooseApp
397 : Factory & _thm_factory;
398 :
399 : /// List of components in this simulation
400 : std::vector<std::shared_ptr<Component>> _components;
401 : /// Map of components by their names
402 : std::map<std::string, std::shared_ptr<Component>> _comp_by_name;
403 : /// Map of component name to component loop name
404 : std::map<std::string, std::string> _component_name_to_loop_name;
405 : /// Map of loop name to model type
406 : std::map<std::string, THM::FlowModelID> _loop_name_to_model_id;
407 :
408 : /// Map of closures by their names
409 : std::map<std::string, std::shared_ptr<ClosuresBase>> _closures_by_name;
410 :
411 : /// variables for this simulation (name and info about the var)
412 : std::map<VariableName, VariableInfo> _vars;
413 :
414 134562 : struct ICInfo
415 : {
416 : std::string _type;
417 : InputParameters _params;
418 :
419 67281 : ICInfo() : _params(emptyInputParameters()) {}
420 67281 : ICInfo(const std::string & type, const InputParameters & params) : _type(type), _params(params)
421 : {
422 67281 : }
423 : };
424 : std::map<std::string, ICInfo> _ics;
425 :
426 : /// "Global" of this simulation
427 : const InputParameters & _thm_pars;
428 :
429 : /// finite element type for the flow in the simulation
430 : libMesh::FEType _flow_fe_type;
431 :
432 : /**
433 : * Setup equations to be solved in this simulation
434 : */
435 : void setupEquations();
436 :
437 : /**
438 : * Setup reading initial conditions from a specified file, see 'initial_from_file' and
439 : * 'initial_from_file_timestep' parameters
440 : */
441 : void setupInitialConditionsFromFile();
442 :
443 : void setupInitialConditionObjects();
444 :
445 : /**
446 : * Sets the coordinate system for each subdomain
447 : */
448 : void setupCoordinateSystem();
449 :
450 : /**
451 : * Setup ctirical heat flux table user object
452 : */
453 : void setupCriticalHeatFluxTable();
454 :
455 : std::vector<OutputName> _outputters_all;
456 : std::vector<OutputName> _outputters_file;
457 : std::vector<OutputName> _outputters_screen;
458 :
459 : /// Control data created in the control logic system
460 : std::map<std::string, ControlDataValue *> _control_data;
461 :
462 : /// true if using implicit time integration scheme
463 : bool _implicit_time_integration;
464 :
465 : Logger _log;
466 :
467 : /// True if checking jacobian
468 : bool _check_jacobian;
469 :
470 : /// Additional sparsity pattern that needs to be added into the Jacobian matrix
471 : std::map<dof_id_type, std::vector<dof_id_type>> _sparsity_elem_augmentation;
472 :
473 : /// Flag indicating if velocity is output as vector-valued field
474 : bool _output_vector_velocity;
475 :
476 : public:
477 : Real _zero;
478 :
479 : private:
480 : /**
481 : * Returns a sorted list of the variables added by components
482 : *
483 : * See Component system documentation for more information.
484 : */
485 : std::vector<VariableName> sortAddedComponentVariables() const;
486 :
487 : /// Component variable order map; see setComponentVariableOrder for more info
488 : static std::map<VariableName, int> _component_variable_order_map;
489 : };
490 :
491 : template <typename T>
492 : bool
493 76202 : Simulation::hasComponentOfType(const std::string & name) const
494 : {
495 : auto it = _comp_by_name.find(name);
496 76202 : if (it != _comp_by_name.end())
497 76154 : return dynamic_cast<T *>((it->second).get()) != nullptr;
498 : else
499 : return false;
500 : }
501 :
502 : template <typename T>
503 : const T &
504 56341 : Simulation::getComponentByName(const std::string & name) const
505 : {
506 : auto it = _comp_by_name.find(name);
507 56341 : if (it != _comp_by_name.end())
508 56341 : return *dynamic_cast<T *>((it->second).get());
509 : else
510 0 : mooseError("Component '",
511 : name,
512 : "' does not exist in the simulation. Use hasComponent or "
513 : "checkComponnetByName before calling getComponent.");
514 : }
|