33#include "libmesh/string_to_enum.h"
49 _fe_problem(fe_problem),
51 _thm_factory(_thm_app.getFactory()),
54 _implicit_time_integration(true),
55 _check_jacobian(false),
56 _output_vector_velocity(true),
59 bool second_order_mesh = pars.
get<
bool>(
"2nd_order_mesh");
76 {elem_id1, std::vector<dof_id_type>()});
77 it->second.push_back(elem_id2);
82 {elem_id2, std::vector<dof_id_type>()});
83 it->second.push_back(elem_id1);
94 comp->executeSetupMesh();
104 unsigned int n_flow_channels = 0;
105 unsigned int n_heat_structures = 0;
110 if (flow_channel !=
nullptr)
118 if (n_flow_channels > 0)
124 if (n_heat_structures > 0)
141 dependency_resolver.
addNode(comp);
142 for (
const auto & dep : comp->getDependencies())
160 comp->executeInitSecondary();
169 const auto flow_connection =
170 MooseSharedNamespace::dynamic_pointer_cast<Component1DConnection>(component);
175 std::vector<std::string> names = flow_connection->getConnectedComponentNames();
176 names.push_back(component->name());
177 std::sort(names.begin(), names.end());
180 std::string proposed_loop_name = names[0];
182 for (
const std::string &
name : names)
196 if (proposed_loop_name > current_loop_name)
199 if (entry.second == proposed_loop_name)
200 entry.second = current_loop_name;
201 proposed_loop_name = current_loop_name;
205 else if (proposed_loop_name < current_loop_name)
208 if (entry.second == current_loop_name)
209 entry.second = proposed_loop_name;
217 std::vector<std::string> loops;
219 if (std::find(loops.begin(), loops.end(), entry.second) == loops.end())
220 loops.push_back(entry.second);
223 for (
const auto & loop : loops)
227 bool found_model_id =
false;
230 const auto flow_chan_base_component =
231 MooseSharedNamespace::dynamic_pointer_cast<FlowChannelBase>(component);
234 model_id = flow_chan_base_component->getFlowModelID();
235 found_model_id =
true;
243 logError(
"No FlowChannelBase-derived components were found in loop '", loop,
"'");
251 std::vector<std::string> loops;
253 if (std::find(loops.begin(), loops.end(), entry.second) == loops.end())
254 loops.push_back(entry.second);
257 Moose::out <<
"\nListing of component loops:" << std::endl;
258 for (
unsigned int i = 0; i < loops.size(); i++)
260 Moose::out <<
"\n Loop " << i + 1 <<
":" << std::endl;
264 if (entry.second == loops[i])
265 Moose::out <<
" " << entry.first << std::endl;
267 Moose::out << std::endl;
276 mooseError(
"This method should only be used for scalar variables.");
292 order = Utility::enum_to_string<Order>(fe_type.
order);
296 params.
set<std::vector<Real>>(
"scaling") = {scaling_factor};
297 else if (!MooseUtils::absoluteFuzzyEqual(scaling_factor, 1.0))
298 mooseError(
"Aux variables cannot be provided a residual scaling factor.");
315 const VariableName &
name,
317 const std::vector<SubdomainName> & subdomain_names,
324 "The version of Simulation::addSimVariable() with subdomain names can no longer be used "
325 "with scalar variables since scalar variables cannot be block-restricted. Use the version "
326 "of Simulation::addSimVariable() without subdomain names instead.");
329 for (
const auto & subdomain_name : subdomain_names)
330 mooseAssert(subdomain_name !=
"ANY_BLOCK_ID",
331 "'ANY_BLOCK_ID' cannot be used for adding field variables in components.");
342 params.
set<std::vector<SubdomainName>>(
"block") = subdomain_names;
349 order = Utility::enum_to_string<Order>(fe_type.
order);
353 params.
set<std::vector<Real>>(
"scaling") = {scaling_factor};
354 else if (!MooseUtils::absoluteFuzzyEqual(scaling_factor, 1.0))
355 mooseError(
"Aux variables cannot be provided a residual scaling factor.");
367 "' has already been added in a different system (nonlinear or aux).");
372 "' has already been added with a different type than 'MooseVariable'.");
377 mooseError(
"The variable '",
name,
"' has already been added with a different FE family.");
380 order = Utility::enum_to_string<Order>(fe_type.
order);
382 mooseError(
"The variable '",
name,
"' has already been added with a different FE order.");
387 auto blocks = params.
get<std::vector<SubdomainName>>(
"block");
388 for (
const auto & subdomain_name : subdomain_names)
390 blocks.push_back(subdomain_name);
391 params.
set<std::vector<SubdomainName>>(
"block") =
blocks;
394 params.
set<std::vector<SubdomainName>>(
"block") = subdomain_names;
397 if (!MooseUtils::absoluteFuzzyEqual(params.
get<std::vector<Real>>(
"scaling")[0],
400 "The variable '",
name,
"' has already been added with a different scaling factor.");
406 const std::string & var_type,
407 const VariableName &
name,
429 "' has already been added in a different system (nonlinear or aux).");
434 "' has already been added with a different type than '",
439 for (
auto it = params.
begin(); it != params.
end(); it++)
441 const std::string param_name = it->first;
442 if (param_name ==
"block")
446 auto blocks = vi_params.
get<std::vector<SubdomainName>>(
"block");
447 const auto new_blocks = params.
get<std::vector<SubdomainName>>(
"block");
448 for (
const auto & subdomain_name : new_blocks)
450 blocks.push_back(subdomain_name);
451 vi_params.
set<std::vector<SubdomainName>>(
"block") =
blocks;
454 mooseError(
"The variable '",
name,
"' was added previously without block restriction.");
463 "' was added previously with a different value for the parameter '",
470 "' was added previously without the parameter '",
496 const std::string &
name,
508 mooseError(
"Initial condition with name '",
name,
"' already exists.");
514 const std::vector<SubdomainName> & block_names)
519 std::string blk_str = block_names[0];
520 for (
unsigned int i = 1; i < block_names.size(); i++)
521 blk_str +=
":" + block_names[i];
523 std::string class_name =
"ConstantIC";
525 params.
set<VariableName>(
"variable") = var_name;
526 params.
set<
Real>(
"value") = value;
527 params.
set<std::vector<SubdomainName>>(
"block") = block_names;
533 const std::string & func_name,
534 const std::vector<SubdomainName> & block_names)
539 std::string blk_str = block_names[0];
540 for (
unsigned int i = 1; i < block_names.size(); i++)
541 blk_str +=
":" + block_names[i];
543 std::string class_name =
"FunctionIC";
545 params.
set<VariableName>(
"variable") = var_name;
546 params.
set<std::vector<SubdomainName>>(
"block") = block_names;
547 params.
set<FunctionName>(
"function") = func_name;
557 std::string class_name =
"ScalarConstantIC";
559 params.
set<VariableName>(
"variable") = var_name;
560 params.
set<
Real>(
"value") = value;
570 std::string class_name =
"ScalarComponentIC";
572 params.
set<VariableName>(
"variable") = var_name;
573 params.
set<std::vector<Real>>(
"values") = value;
577std::vector<VariableName>
582 std::set<int> indices;
583 std::vector<std::pair<VariableName, int>> registered_var_index_pairs;
586 registered_var_index_pairs.push_back(var_and_index);
588 const auto ind = var_and_index.second;
589 auto insert_return = indices.insert(ind);
590 if (!insert_return.second)
591 mooseError(
"The index ", ind,
" was used for multiple component variables.");
595 std::vector<VariableName> vars_unsorted;
596 for (
const auto & var_and_data :
_vars)
597 vars_unsorted.push_back(var_and_data.first);
605 std::sort(registered_var_index_pairs.begin(),
606 registered_var_index_pairs.end(),
607 [](
const std::pair<VariableName, int> &
a,
const std::pair<VariableName, int> &
b)
608 { return a.second < b.second; });
613 std::vector<VariableName> vars_sorted;
614 for (
const auto & var_index_pair : registered_var_index_pairs)
616 const auto & var = var_index_pair.first;
617 if (std::find(vars_unsorted.begin(), vars_unsorted.end(), var) != vars_unsorted.end())
619 vars_sorted.push_back(var);
620 vars_unsorted.erase(std::remove(vars_unsorted.begin(), vars_unsorted.end(), var),
621 vars_unsorted.end());
627 std::sort(vars_unsorted.begin(), vars_unsorted.end());
628 vars_sorted.insert(vars_sorted.end(), vars_unsorted.begin(), vars_unsorted.end());
653 comp->addVariables();
661 std::stringstream ss;
662 ss <<
"The system ordering of variables added by Components is as follows:\n";
663 for (
const auto & var : var_names)
664 ss <<
" " << var <<
"\n";
669 for (
const auto &
name : var_names)
688 const UserObjectName suo_name =
genName(
"thm",
"suo");
690 const std::string class_name =
"SolutionUserObject";
692 params.
set<MeshFileName>(
"mesh") =
_thm_pars.
get<FileName>(
"initial_from_file");
693 params.
set<std::string>(
"timestep") =
_thm_pars.
get<std::string>(
"initial_from_file_timestep");
699 const VariableName & var_name =
v.first;
702 if (vi.
_var_type ==
"MooseVariableScalar")
704 std::string class_name =
"ScalarSolutionIC";
706 params.
set<VariableName>(
"variable") = var_name;
707 params.
set<VariableName>(
"from_variable") = var_name;
708 params.
set<UserObjectName>(
"solution_uo") = suo_name;
713 std::string class_name =
"SolutionIC";
715 params.
set<VariableName>(
"variable") = var_name;
716 params.
set<VariableName>(
"from_variable") = var_name;
717 params.
set<UserObjectName>(
"solution_uo") = suo_name;
719 params.
set<std::vector<SubdomainName>>(
"block") =
720 vi.
_params.
get<std::vector<SubdomainName>>(
"block");
729 for (
auto && i :
_ics)
731 const std::string &
name = i.first;
741 comp->addMooseObjects();
748 const std::string class_name =
"AugmentSparsityBetweenElements";
751 Moose::RelationshipManagerType::COUPLING | Moose::RelationshipManagerType::ALGEBRAIC |
752 Moose::RelationshipManagerType::GEOMETRIC;
755 params.set<std::map<dof_id_type, std::vector<dof_id_type>> *>(
"_elem_map") =
764 comp->addRelationshipManagers(Moose::RelationshipManagerType::COUPLING |
765 Moose::RelationshipManagerType::ALGEBRAIC |
766 Moose::RelationshipManagerType::GEOMETRIC);
773 std::vector<SubdomainName>
blocks;
777 if (comp->parent() ==
nullptr)
779 const auto & subdomains = comp->getSubdomainNames();
780 const auto & coord_sys = comp->getCoordSysTypes();
782 for (
unsigned int i = 0; i < subdomains.size(); i++)
784 blocks.push_back(subdomains[i]);
813 const auto & time_integrators =
815 if (!time_integrators.empty())
816 ti = time_integrators.front().get();
820 (
dynamic_cast<const ExplicitRK2 *
>(ti) !=
nullptr) ||
826 mooseError(
"Coupling matrix does not exists. Something really bad happened.");
829 for (
unsigned int i = 0; i < cm->
size(); i++)
830 for (
unsigned int j = 0; j < cm->
size(); j++)
835 "Single matrix preconditioning with full coupling is required to run. Please, check that "
836 "your input file has the following preconditioning block:\n\n"
837 "[Preconditioning]\n"
855 std::vector<Component *> flow_channels;
859 if (flow_channel !=
nullptr)
860 flow_channels.push_back(flow_channel);
864 std::map<std::string, unsigned int> flow_channel_inlets;
865 std::map<std::string, unsigned int> flow_channel_outlets;
866 for (
auto && comp : flow_channels)
868 flow_channel_inlets[comp->name()] = 0;
869 flow_channel_outlets[comp->name()] = 0;
876 if (pc_comp !=
nullptr)
878 for (
const auto & connection : pc_comp->getConnections())
881 flow_channel_inlets[connection._component_name]++;
883 flow_channel_outlets[connection._component_name]++;
889 for (
auto && comp : flow_channels)
891 if (flow_channel_inlets[comp->name()] == 0)
892 logError(
"Component '", comp->name(),
"' does not have connected inlet.");
893 else if (flow_channel_inlets[comp->name()] > 1)
894 logError(
"Multiple inlets specified for component '", comp->name(),
"'.");
896 if (flow_channel_outlets[comp->name()] == 0)
897 logError(
"Component '", comp->name(),
"' does not have connected outlet.");
898 else if (flow_channel_outlets[comp->name()] > 1)
899 logError(
"Multiple outlets specified for component '", comp->name(),
"'.");
919 if (!i.second->getDeclared())
922 "' was requested, but was not declared by any active control object.");
930 for (
auto && i : ctrl_wh.getObjects())
937 for (
auto && i : ctrl_wh.getObjects())
945 for (
auto && cd_name : cd_deps)
952 auto it = std::find(deps.begin(), deps.end(), dep_name);
953 if (it == deps.end())
954 deps.push_back(dep_name);
963 for (
auto && i : ctrl_wh.getObjects())
967 std::list<const THMControl *> l;
973 for (
auto && cd_name : cd_deps)
997 logError(
"Component with name '",
name,
"' already exists");
1015 logError(
"A closures object with the name '",
name,
"' already exists.");
1024std::shared_ptr<ClosuresBase>
1031 mooseError(
"The requested closures object '",
name,
"' does not exist.");
1048std::vector<OutputName>
1051 std::string key_lowercase = key;
1052 std::transform(key_lowercase.begin(), key_lowercase.end(), key_lowercase.begin(), ::tolower);
1054 std::vector<OutputName> outputs;
1055 if (key_lowercase ==
"none")
1056 outputs.push_back(
"none");
1057 else if (key_lowercase ==
"screen")
1059 else if (key_lowercase ==
"file")
1061 else if (key_lowercase ==
"both")
1064 mooseError(
"The outputs vector key '" + key_lowercase +
"' is invalid");
1079 i.second->copyValuesBack();
void mooseInfo(Args &&... args)
void mooseError(Args &&... args)
void mooseDeprecated(Args &&... args)
const ExecFlagType EXEC_TIMESTEP_END
const ExecFlagType EXEC_TIMESTEP_BEGIN
static MooseEnum getNonlinearVariableFamilies()
static MooseEnum getNonlinearVariableOrders()
Base class for closures implementations.
Base class for 1D component junctions and boundaries.
Base class for THM components.
void executeCheck() const
Wrapper function for check() that marks the function as being called.
Abstract definition of a ControlData value.
const THMControl * getControl() const
Get the pointer to the control object that declared this control data.
std::vector< std::string > & getDependencies()
const std::vector< T > & dfs()
void addEdge(const T &a, const T &b)
void addObject(std::shared_ptr< T > object, THREAD_ID tid=0, bool recurse=true) override
virtual std::vector< std::shared_ptr< UserObject > > addUserObject(const std::string &user_object_name, const std::string &name, InputParameters ¶meters)
void setAxisymmetricCoordAxis(const MooseEnum &rz_coord_axis)
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters ¶ms)
void setCoordSystem(const std::vector< SubdomainName > &blocks, const MultiMooseEnum &coord_sys)
virtual void addInitialCondition(const std::string &ic_name, const std::string &name, InputParameters ¶meters)
ExecuteMooseObjectWarehouse< Control > & getControlWarehouse()
const libMesh::CouplingMatrix * couplingMatrix(const unsigned int nl_sys_num) const override
virtual void createQRules(libMesh::QuadratureType type, libMesh::Order order, libMesh::Order volume_order=libMesh::INVALID_ORDER, libMesh::Order face_order=libMesh::INVALID_ORDER, SubdomainID block=Moose::ANY_BLOCK_ID, bool allow_negative_qweights=true)
virtual void addAuxVariable(const std::string &var_type, const std::string &var_name, InputParameters ¶ms)
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
A base class for flow channels.
static const libMesh::FEType & feType()
Get the FE type used for heat conduction.
static libMesh::FEType _fe_type
Interface class for heat structure components.
void emitLoggedErrors() const
Calls mooseError if there are any logged errors.
void emitLoggedWarnings() const
Calls mooseWarning if there are any logged warnings.
Interface class for logging errors and warnings.
void logError(Args &&... args) const
Logs an error.
bool addRelationshipManager(std::shared_ptr< RelationshipManager > relationship_manager)
Executioner * getExecutioner() const
const std::string & name() const
const T & getParam(const std::string &name) const
bool compareCurrent(const MooseEnum &other, CompareMode mode=CompareMode::COMPARE_NAME) const
virtual void addObject(std::shared_ptr< T > object, THREAD_ID tid=0, bool recurse=true) override
void setAdditionalValue(const std::string &names)
std::string genName(const std::string &prefix, unsigned int id, const std::string &suffix="") const
Build a name from a prefix, number and possible suffix.
void printComponentLoops() const
Prints the component loops.
Simulation(FEProblemBase &fe_problem, const InputParameters ¶ms)
void addComponentScalarIC(const VariableName &var_name, const std::vector< Real > &value)
void addControl(const std::string &type, const std::string &name, InputParameters params)
Add a control.
THMMesh & _thm_mesh
THM mesh.
std::map< std::string, std::shared_ptr< Component > > _comp_by_name
Map of components by their names.
bool hasInitialConditionsFromFile() const
Are initial conditions specified from a file.
std::map< VariableName, VariableInfo > _vars
variables for this simulation (name and info about the var)
std::map< std::string, ControlDataValue * > _control_data
Control data created in the control logic system.
void addConstantScalarIC(const VariableName &var_name, Real value)
FEProblemBase & _fe_problem
Pointer to FEProblem representing this simulation.
ThermalHydraulicsApp & _thm_app
The application this is associated with.
static std::map< VariableName, int > _component_variable_order_map
Component variable order map; see setComponentVariableOrder for more info.
ThermalHydraulicsApp & getApp()
Get the ThermalHydraulicsApp.
std::vector< OutputName > _outputters_file
void addConstantIC(const VariableName &var_name, Real value, const std::vector< SubdomainName > &block_names)
virtual void integrityCheck() const
Check the integrity of the simulation.
virtual void advanceState()
Advance all of the state holding vectors / datastructures so that we can move to the next timestep.
virtual void addVariables()
Add variables involved in this simulation.
virtual void augmentSparsity(const dof_id_type &elem_id1, const dof_id_type &elem_id2)
Hint how to augment sparsity pattern between two elements.
const InputParameters & _thm_pars
"Global" of this simulation
void addFunctionIC(const VariableName &var_name, const std::string &func_name, const std::vector< SubdomainName > &block_names)
virtual void initComponents()
Initialize this simulation's components.
std::vector< OutputName > _outputters_all
std::map< std::string, std::string > _component_name_to_loop_name
Map of component name to component loop name.
virtual void couplingMatrixIntegrityCheck() const
Check integrity of coupling matrix used by the preconditioner.
virtual void addClosures(const std::string &type, const std::string &name, InputParameters params)
Add a closures object into this simulation.
void addRelationshipManagers()
Add additional relationship managers to run the simulation.
virtual void setupMesh()
Perform mesh setup actions such as setting up the coordinate system(s) and creating ghosted elements.
std::vector< OutputName > _outputters_screen
void checkVariableNameLength(const std::string &name) const
Reports an error if the variable name is too long.
const libMesh::FEType & getFlowFEType() const
Gets the FE type for the flow in this simulation.
bool hasComponent(const std::string &name) const
Find out if simulation has a component with the given name.
virtual void controlDataIntegrityCheck()
Check the integrity of the control data.
std::map< std::string, ICInfo > _ics
std::shared_ptr< ClosuresBase > getClosures(const std::string &name) const
Get a pointer to a closures object.
void identifyLoops()
Identifies the component loops.
virtual void initSimulation()
Initialize this simulation.
void addSimVariable(bool nl, const VariableName &name, libMesh::FEType fe_type, Real scaling_factor=1.0)
Queues a variable of type MooseVariableScalar to be added to the nonlinear or aux system.
static void setComponentVariableOrder(const VariableName &var, int index)
Sets a component variable order index.
virtual void addComponent(const std::string &type, const std::string &name, InputParameters params)
Add a component into this simulation.
bool hasClosures(const std::string &name) const
Return whether the simulation has a closures object.
std::map< std::string, std::shared_ptr< ClosuresBase > > _closures_by_name
Map of closures by their names.
virtual void addMooseObjects()
Add component MOOSE objects.
bool _implicit_time_integration
true if using implicit time integration scheme
virtual void buildMesh()
Create mesh for this simulation.
virtual void setupQuadrature()
Sets up quadrature rules.
Factory & _thm_factory
The Factory associated with the MooseApp.
std::vector< std::shared_ptr< Component > > _components
List of components in this simulation.
std::vector< VariableName > sortAddedComponentVariables() const
Returns a sorted list of the variables added by components.
void setupInitialConditionObjects()
void addFileOutputter(const std::string &name)
std::vector< OutputName > getOutputsVector(const std::string &key) const
Gets the vector of output names corresponding to a 1-word key string.
void setupCoordinateSystem()
Sets the coordinate system for each subdomain.
virtual void run()
Run the simulation.
void setupInitialConditionsFromFile()
Setup reading initial conditions from a specified file, see 'initial_from_file' and 'initial_from_fil...
std::map< std::string, THM::FlowModelID > _loop_name_to_model_id
Map of loop name to model type.
bool _check_jacobian
True if checking jacobian.
void addSimInitialCondition(const std::string &type, const std::string &name, InputParameters params)
std::map< dof_id_type, std::vector< dof_id_type > > _sparsity_elem_augmentation
Additional sparsity pattern that needs to be added into the Jacobian matrix.
void addScreenOutputter(const std::string &name)
const std::vector< std::shared_ptr< TimeIntegrator > > & getTimeIntegrators()
const std::vector< std::string > & getControlDataDependencies() const
Return the Controls that must run before this Control.
This control block will terminate a run if its input indicates so.
Moose::TimeIntegratorType getTimeScheme() const
Order default_quadrature_order() const
virtual std::unique_ptr< Base > create()=0
static const size_t MAX_VARIABLE_LENGTH
std::string enum_to_string(const T e)
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool _nl
True if the variable is a nonlinear (solution) variable; otherwise, aux.
InputParameters _params
Input parameters.
std::string _var_type
Type (class) of the variable.