33 #include "libmesh/string_to_enum.h" 42 _component_variable_order_map[var] = index;
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 =
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 =
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.");
288 family = Utility::enum_to_string(fe_type.
family);
292 order = Utility::enum_to_string<Order>(fe_type.
order);
296 params.
set<std::vector<Real>>(
"scaling") = {scaling_factor};
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;
345 family = Utility::enum_to_string(fe_type.
family);
349 order = Utility::enum_to_string<Order>(fe_type.
order);
353 params.
set<std::vector<Real>>(
"scaling") = {scaling_factor};
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'.");
375 family = Utility::enum_to_string(fe_type.
family);
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;
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;
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;
570 std::string class_name =
"ScalarComponentIC";
572 params.
set<VariableName>(
"variable") = var_name;
573 params.
set<std::vector<Real>>(
"values") =
value;
577 std::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";
755 params.set<std::map<dof_id_type, std::vector<dof_id_type>> *>(
"_elem_map") =
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();
818 if ((dynamic_cast<const ExplicitTimeIntegrator *>(ti) !=
nullptr) ||
819 (dynamic_cast<const ExplicitEuler *>(ti) !=
nullptr) ||
820 (dynamic_cast<const ExplicitRK2 *>(ti) !=
nullptr) ||
821 (dynamic_cast<const ExplicitTVDRK2 *>(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(),
"'.");
904 comp->executeCheck();
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.");
1024 std::shared_ptr<ClosuresBase>
1031 mooseError(
"The requested closures object '",
name,
"' does not exist.");
1048 std::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 addObject(std::shared_ptr< Control > object, THREAD_ID tid=0, bool recurse=true) override
Abstract definition of a ControlData value.
virtual void run()
Run the simulation.
bool _implicit_time_integration
true if using implicit time integration scheme
std::shared_ptr< ClosuresBase > getClosures(const std::string &name) const
Get a pointer to a closures object.
virtual void setupMesh()
Perform mesh setup actions such as setting up the coordinate system(s) and creating ghosted elements...
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.
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
void setupInitialConditionObjects()
void mooseError(Args &&... args)
void setAdditionalValue(const std::string &names)
void identifyLoops()
Identifies the component loops.
static const std::string component
void emitLoggedErrors() const
Calls mooseError if there are any logged errors.
Base class for 1D component junctions and boundaries.
static const size_t MAX_VARIABLE_LENGTH
std::map< std::string, ICInfo > _ics
virtual void controlDataIntegrityCheck()
Check the integrity of the control data.
bool _check_jacobian
True if checking jacobian.
FEProblemBase & _fe_problem
Pointer to FEProblem representing this simulation.
THMMesh & _thm_mesh
THM mesh.
void addFileOutputter(const std::string &name)
Order default_quadrature_order() const
A base class for flow channels.
const ExecFlagType EXEC_TIMESTEP_END
virtual void addClosures(const std::string &type, const std::string &name, InputParameters params)
Add a closures object into this simulation.
void printComponentLoops() const
Prints the component loops.
const std::vector< std::string > & getControlDataDependencies() const
Return the Controls that must run before this Control.
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
virtual void addAuxVariable(const std::string &var_type, const std::string &var_name, InputParameters ¶ms)
Interface class for logging errors and warnings.
void addEdge(const T &a, const T &b)
virtual const std::string & name() const
virtual void couplingMatrixIntegrityCheck() const
Check integrity of coupling matrix used by the preconditioner.
static MooseEnum getNonlinearVariableFamilies()
void addFunctionIC(const VariableName &var_name, const std::string &func_name, const std::vector< SubdomainName > &block_names)
const libMesh::CouplingMatrix * couplingMatrix(const unsigned int nl_sys_num) const override
void addRelationshipManagers()
Add additional relationship managers to run the simulation.
virtual void initSimulation()
Initialize this simulation.
Base class for closures implementations.
std::map< std::string, ControlDataValue * > _control_data
Control data created in the control logic system.
virtual void addInitialCondition(const std::string &ic_name, const std::string &name, InputParameters ¶meters)
static std::map< VariableName, int > _component_variable_order_map
Component variable order map; see setComponentVariableOrder for more info.
void mooseInfo(Args &&... args)
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...
void checkVariableNameLength(const std::string &name) const
Reports an error if the variable name is too long.
bool hasComponent(const std::string &name) const
Find out if simulation has a component with the given name.
bool addRelationshipManager(std::shared_ptr< RelationshipManager > relationship_manager)
static MooseEnum getNonlinearVariableOrders()
virtual std::unique_ptr< Base > create()=0
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
virtual void initComponents()
Initialize this simulation's components.
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)
const THMControl * getControl() const
Get the pointer to the control object that declared this control data.
std::map< VariableName, VariableInfo > _vars
variables for this simulation (name and info about the var)
const ExecFlagType EXEC_TIMESTEP_BEGIN
ThermalHydraulicsApp & getApp()
Get the ThermalHydraulicsApp.
void emitLoggedWarnings() const
Calls mooseWarning if there are any logged warnings.
void logError(Args &&... args) const
Logs an error.
std::vector< OutputName > _outputters_file
Factory & _thm_factory
The Factory associated with the MooseApp.
void setupInitialConditionsFromFile()
Setup reading initial conditions from a specified file, see 'initial_from_file' and 'initial_from_fil...
virtual void integrityCheck() const
Check the integrity of the simulation.
std::vector< OutputName > getOutputsVector(const std::string &key) const
Gets the vector of output names corresponding to a 1-word key string.
void setAxisymmetricCoordAxis(const MooseEnum &rz_coord_axis)
const T & getParam(const std::string &name) const
InputParameters _params
Input parameters.
const std::vector< std::string > & getConnectedComponentNames() const
Returns a list of names of components that are connected to this component.
Interface class for heat structure components.
Base class for THM components.
void mooseDeprecated(Args &&... args)
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
virtual void addMooseObjects()
Add component MOOSE objects.
const std::vector< std::shared_ptr< TimeIntegrator > > & getTimeIntegrators()
std::vector< std::shared_ptr< Component > > _components
List of components in this simulation.
Executioner * getExecutioner() const
std::map< std::string, std::string > _component_name_to_loop_name
Map of component name to component loop name.
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters ¶ms)
std::map< std::string, std::shared_ptr< Component > > _comp_by_name
Map of components by their names.
void addConstantScalarIC(const VariableName &var_name, Real value)
void setCoordSystem(const std::vector< SubdomainName > &blocks, const MultiMooseEnum &coord_sys)
static const libMesh::FEType & feType()
Get the FE type used for heat conduction.
const InputParameters & _thm_pars
"Global" of this simulation
void addScreenOutputter(const std::string &name)
virtual void setupQuadrature()
Sets up quadrature rules.
std::map< std::string, std::shared_ptr< ClosuresBase > > _closures_by_name
Map of closures by their names.
bool hasClosures(const std::string &name) const
Return whether the simulation has a closures object.
std::string _var_type
Type (class) of the variable.
void addSimInitialCondition(const std::string &type, const std::string &name, InputParameters params)
const libMesh::FEType & getFlowFEType() const
Gets the FE type for the flow in this simulation.
void addComponentScalarIC(const VariableName &var_name, const std::vector< Real > &value)
virtual void buildMesh()
Create mesh for this simulation.
std::vector< VariableName > sortAddedComponentVariables() const
Returns a sorted list of the variables added by components.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string v
virtual void addComponent(const std::string &type, const std::string &name, InputParameters params)
Add a component into this simulation.
Simulation(FEProblemBase &fe_problem, const InputParameters ¶ms)
bool compareCurrent(const MooseEnum &other, CompareMode mode=CompareMode::COMPARE_NAME) const
bool _nl
True if the variable is a nonlinear (solution) variable; otherwise, aux.
virtual std::vector< std::shared_ptr< UserObject > > addUserObject(const std::string &user_object_name, const std::string &name, InputParameters ¶meters)
static void setComponentVariableOrder(const VariableName &var, int index)
Sets a component variable order index.
std::map< std::string, THM::FlowModelID > _loop_name_to_model_id
Map of loop name to model type.
const std::vector< T > & dfs()
virtual void addVariables()
Add variables involved in this simulation.
Moose::TimeIntegratorType getTimeScheme() const
std::vector< OutputName > _outputters_screen
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
void setupCoordinateSystem()
Sets the coordinate system for each subdomain.
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.
static libMesh::FEType _fe_type
ExecuteMooseObjectWarehouse< Control > & getControlWarehouse()
ThermalHydraulicsApp & _thm_app
The application this is associated with.
This control block will terminate a run if its input indicates so.
void addConstantIC(const VariableName &var_name, Real value, const std::vector< SubdomainName > &block_names)
virtual void addObject(std::shared_ptr< Control > object, THREAD_ID tid=0, bool recurse=true) override
static const std::string k
std::vector< OutputName > _outputters_all
virtual const THM::FlowModelID & getFlowModelID() const =0
Gets the flow model ID.
const Elem & get(const ElemType type_in)
bool hasInitialConditionsFromFile() const
Are initial conditions specified from a file.
virtual void augmentSparsity(const dof_id_type &elem_id1, const dof_id_type &elem_id2)
Hint how to augment sparsity pattern between two elements.
void addControl(const std::string &type, const std::string &name, InputParameters params)
Add a control.
virtual void advanceState()
Advance all of the state holding vectors / datastructures so that we can move to the next timestep...
std::vector< std::string > & getDependencies()