diff --git a/modules/thermal_hydraulics/include/components/Component.h b/modules/thermal_hydraulics/include/components/Component.h index 9f384a1b3a8d..13bc5e4d69e7 100644 --- a/modules/thermal_hydraulics/include/components/Component.h +++ b/modules/thermal_hydraulics/include/components/Component.h @@ -103,6 +103,11 @@ class Component : public THMObject, public LoggingInterface, public NamingInterf */ void executeSetupMesh(); + /** + * Adds relationship managers for the component + */ + virtual void addRelationshipManagers(Moose::RelationshipManagerType /*input_rm_type*/) {} + virtual void addVariables() {} virtual void addMooseObjects() {} @@ -275,6 +280,18 @@ class Component : public THMObject, public LoggingInterface, public NamingInterf */ virtual void setupMesh() {} + /** + * Method to add a relationship manager for the objects being added to the system. Relationship + * managers have to be added relatively early. In many cases before the Action::act() method + * is called. + * + * This method was copied from Action. + * + * @param moose_object_pars The MooseObject to inspect for RelationshipManagers to add + * @return Whether any relationship manager was added + */ + bool addRelationshipManagersFromParameters(const InputParameters & moose_object_pars); + /** * Runtime check to make sure that a parameter of specified type exists in the component's input * parameters @@ -396,6 +413,27 @@ class Component : public THMObject, public LoggingInterface, public NamingInterf THMMesh & _mesh; private: + /** + * Method for adding a single relationship manager + * + * This method was copied from Action. + * + * @param moose_object_pars The parameters of the MooseObject that requested the RM + * @param rm_name The class type of the RM, e.g. ElementSideNeighborLayers + * @param rm_type The RelationshipManagerType, e.g. geometric, algebraic, coupling + * @param rm_input_parameter_func The RM callback function, typically a lambda defined in the + * requesting MooseObject's validParams function + * @param sys_type A RMSystemType that can be used to limit the systems and consequent dof_maps + * that the RM can be attached to + * @return Whether a relationship manager was added + */ + bool + addRelationshipManager(const InputParameters & moose_object_pars, + std::string rm_name, + Moose::RelationshipManagerType rm_type, + Moose::RelationshipManagerInputParameterCallback rm_input_parameter_func, + Moose::RMSystemType sys_type = Moose::RMSystemType::NONE); + /// Component setup status mutable EComponentSetupStatus _component_setup_status; diff --git a/modules/thermal_hydraulics/include/components/FlowComponentNS.h b/modules/thermal_hydraulics/include/components/FlowComponentNS.h index a1d4f1aa6362..77a8e533cae2 100644 --- a/modules/thermal_hydraulics/include/components/FlowComponentNS.h +++ b/modules/thermal_hydraulics/include/components/FlowComponentNS.h @@ -23,6 +23,7 @@ class FlowComponentNS : public NSFVBase FlowComponentNS(const InputParameters & parameters); + virtual void addRelationshipManagers(Moose::RelationshipManagerType input_rm_type) override; virtual void addVariables() override; virtual void addMooseObjects() override; diff --git a/modules/thermal_hydraulics/src/base/Simulation.C b/modules/thermal_hydraulics/src/base/Simulation.C index a073c33733ec..65ec5a38f783 100644 --- a/modules/thermal_hydraulics/src/base/Simulation.C +++ b/modules/thermal_hydraulics/src/base/Simulation.C @@ -684,6 +684,11 @@ Simulation::addRelationshipManagers() if (!_thm_app.addRelationshipManager(rm)) _thm_factory.releaseSharedObjects(*rm); } + + for (auto && comp : _components) + comp->addRelationshipManagers(Moose::RelationshipManagerType::COUPLING | + Moose::RelationshipManagerType::ALGEBRAIC | + Moose::RelationshipManagerType::GEOMETRIC); } void diff --git a/modules/thermal_hydraulics/src/components/Component.C b/modules/thermal_hydraulics/src/components/Component.C index 5d0a9549fcf6..2265b39a06e4 100644 --- a/modules/thermal_hydraulics/src/components/Component.C +++ b/modules/thermal_hydraulics/src/components/Component.C @@ -12,6 +12,7 @@ #include "ThermalHydraulicsApp.h" #include "ConstantFunction.h" #include "Numerics.h" +#include "RelationshipManager.h" InputParameters Component::validParams() @@ -158,6 +159,68 @@ Component::checkComponentExistsByName(const std::string & comp_name) const logError("The component '", comp_name, "' does not exist"); } +bool +Component::addRelationshipManagersFromParameters(const InputParameters & moose_object_pars) +{ + const auto & buildable_types = moose_object_pars.getBuildableRelationshipManagerTypes(); + + bool added = false; + + for (const auto & buildable_type : buildable_types) + { + auto & rm_name = std::get<0>(buildable_type); + auto & rm_type = std::get<1>(buildable_type); + auto rm_input_parameter_func = std::get<2>(buildable_type); + + added = addRelationshipManager(moose_object_pars, rm_name, rm_type, rm_input_parameter_func) || + added; + } + + return added; +} + +bool +Component::addRelationshipManager( + const InputParameters & moose_object_pars, + std::string rm_name, + Moose::RelationshipManagerType rm_type, + Moose::RelationshipManagerInputParameterCallback rm_input_parameter_func, + Moose::RMSystemType) +{ + // These need unique names + static unsigned int unique_object_id = 0; + + auto new_name = moose_object_pars.get("_moose_base") + '_' + name() + '_' + rm_name + + "_" + Moose::stringify(rm_type) + " " + std::to_string(unique_object_id); + + auto rm_params = _factory.getValidParams(rm_name); + rm_params.set("rm_type") = rm_type; + + rm_params.set("for_whom") = name(); + + // If there is a callback for setting the RM parameters let's use it + if (rm_input_parameter_func) + rm_input_parameter_func(moose_object_pars, rm_params); + + rm_params.set("mesh") = &mesh(); + + if (!rm_params.areAllRequiredParamsValid()) + mooseError("Missing required parameters for RelationshipManager " + rm_name + " for object " + + name()); + + auto rm_obj = _factory.create(rm_name, new_name, rm_params); + + const bool added = _app.addRelationshipManager(rm_obj); + + // Delete the resources created on behalf of the RM if it ends up not being added to the App. + if (!added) + _factory.releaseSharedObjects(*rm_obj); + else // we added it + unique_object_id++; + + return added; +} + void Component::checkMutuallyExclusiveParameters(const std::vector & params, bool need_one_specified) const diff --git a/modules/thermal_hydraulics/src/components/FlowComponentNS.C b/modules/thermal_hydraulics/src/components/FlowComponentNS.C index f12bf6b1e424..c7ddd2dedd28 100644 --- a/modules/thermal_hydraulics/src/components/FlowComponentNS.C +++ b/modules/thermal_hydraulics/src/components/FlowComponentNS.C @@ -27,6 +27,11 @@ FlowComponentNS::FlowComponentNS(const InputParameters & parameters) checkCopyNSNodalVariables(); } +void FlowComponentNS::addRelationshipManagers(Moose::RelationshipManagerType /*input_rm_type*/) +{ + addRelationshipManagersFromParameters(getGhostParametersForRM()); +} + void FlowComponentNS::addVariables() {