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 : // MOOSE includes 13 : #include "MooseTypes.h" 14 : #include "MooseUtils.h" 15 : 16 : // Forward declarations 17 : class UserObject; 18 : class FEProblemBase; 19 : class MooseObject; 20 : 21 : /** 22 : * Interface for objects that need to use UserObjects. 23 : */ 24 : class UserObjectInterface 25 : { 26 : public: 27 : static InputParameters validParams(); 28 : 29 : /** 30 : * @param params The parameters used by the object being instantiated. This 31 : * class needs them so it can get the user object named in the input file, 32 : * but the object calling getUserObject only needs to use the name on the 33 : * left hand side of the statement "user_object = user_object_name" 34 : */ 35 : UserObjectInterface(const MooseObject * moose_object); 36 : 37 : /** 38 : * @return The name of the user object associated with the parameter \p param_name 39 : */ 40 : UserObjectName getUserObjectName(const std::string & param_name) const; 41 : 42 : /** 43 : * @return Whether or not a UserObject exists with the name given by the parameter \p param_name. 44 : */ 45 : ///@{ 46 : bool hasUserObject(const std::string & param_name) const; 47 : template <class T> 48 : bool hasUserObject(const std::string & param_name) const; 49 : ///@} 50 : 51 : /* 52 : * @return Whether or not a UserObject exists with the name \p object_name. 53 : */ 54 : ///@{ 55 : bool hasUserObjectByName(const UserObjectName & object_name) const; 56 : template <class T> 57 : bool hasUserObjectByName(const UserObjectName & object_name) const; 58 : ///@} 59 : 60 : /** 61 : * Get an user object with a given parameter \p param_name 62 : * @param param_name The name of the parameter key of the user object to retrieve 63 : * @param is_dependency Whether the user object we are retrieving should be viewed as a 64 : * dependency, e.g. whether the retrieved user object should be sorted and executed before this 65 : * object (if we are a user object) 66 : * @return The user object with name associated with the parameter \p param_name 67 : */ 68 : template <class T> 69 : const T & getUserObject(const std::string & param_name, bool is_dependency = true) const; 70 : 71 : /** 72 : * Get an user object with the name \p object_name 73 : * @param object_name The name of the user object to retrieve 74 : * @param is_dependency Whether the user object we are retrieving should be viewed as a 75 : * dependency, e.g. whether the retrieved user object should be sorted and executed before this 76 : * object (if we are a user object) 77 : * @return The user object with the name \p object_name 78 : */ 79 : template <class T> 80 : const T & getUserObjectByName(const UserObjectName & object_name, 81 : bool is_dependency = true) const; 82 : 83 : /** 84 : * Get an user object with a given parameter \p param_name 85 : * @param param_name The name of the parameter key of the user object to retrieve 86 : * @param is_dependency Whether the user object we are retrieving should be viewed as a 87 : * dependency, e.g. whether the retrieved user object should be sorted and executed before this 88 : * object (if we are a user object) 89 : * @return The user object with name associated with the parameter \p param_name 90 : */ 91 : const UserObject & getUserObjectBase(const std::string & param_name, 92 : bool is_dependency = true) const; 93 : 94 : /** 95 : * Get an user object with the name \p object_name 96 : * @param object_name The name of the user object to retrieve 97 : * @param is_dependency Whether the user object we are retrieving should be viewed as a 98 : * dependency, e.g. whether the retrieved user object should be sorted and executed before this 99 : * object (if we are a user object) 100 : * @return The user object with the name \p object_name 101 : */ 102 : const UserObject & getUserObjectBaseByName(const UserObjectName & object_name, 103 : bool is_dependency = true) const; 104 : 105 : protected: 106 : /** 107 : * Helper for deriving classes to override to add dependencies when a UserObject 108 : * is requested. 109 : */ 110 967 : virtual void addUserObjectDependencyHelper(const UserObject & /* uo */) const {} 111 : 112 : private: 113 : /** 114 : * Go directly to the FEProblem for the requested \p UserObject 115 : */ 116 : const UserObject & getUserObjectFromFEProblem(const UserObjectName & object_name) const; 117 : 118 : /** 119 : * Internal helper that casts the UserObject \p uo_base to the requested type. Exits with 120 : * a useful error if the casting failed. If the parameter \p param_name is provided and 121 : * is valid, a paramError() will be used instead. 122 : */ 123 : template <class T> 124 : const T & castUserObject(const UserObject & uo_base, const std::string & param_name = "") const; 125 : 126 : /** 127 : * emit an error for the given parameter 128 : */ 129 : void mooseObjectError(const std::string & param_name, std::stringstream & oss) const; 130 : 131 : /// Gets a UserObject's type; avoids including UserObject.h in the UserObjectInterface 132 : const std::string & userObjectType(const UserObject & uo) const; 133 : /// Gets a UserObject's name; avoids including UserObject.h in the UserObjectInterface 134 : const std::string & userObjectName(const UserObject & uo) const; 135 : 136 : /// Moose object using the interface 137 : const MooseObject & _uoi_moose_object; 138 : 139 : /// Reference to the FEProblemBase instance 140 : const FEProblemBase & _uoi_feproblem; 141 : 142 : /// Thread ID 143 : const THREAD_ID _uoi_tid; 144 : }; 145 : 146 : template <class T> 147 : const T & 148 5806 : UserObjectInterface::castUserObject(const UserObject & uo_base, 149 : const std::string & param_name /* = "" */) const 150 : { 151 5806 : const T * uo = dynamic_cast<const T *>(&uo_base); 152 : 153 5806 : if (!uo) 154 : { 155 8 : std::stringstream oss; 156 16 : oss << "The provided UserObject \"" << userObjectName(uo_base) << "\" of type " 157 16 : << userObjectType(uo_base) 158 : << " is not derived from the required type.\n\nThe UserObject must derive from " 159 8 : << MooseUtils::prettyCppType<T>() << "."; 160 : 161 8 : mooseObjectError(param_name, oss); 162 0 : } 163 : 164 5798 : return *uo; 165 : } 166 : 167 : template <class T> 168 : const T & 169 5741 : UserObjectInterface::getUserObject(const std::string & param_name, const bool is_dependency) const 170 : { 171 5741 : return castUserObject<T>(getUserObjectBase(param_name, is_dependency), param_name); 172 : } 173 : 174 : template <class T> 175 : const T & 176 65 : UserObjectInterface::getUserObjectByName(const UserObjectName & object_name, 177 : const bool is_dependency) const 178 : { 179 65 : return castUserObject<T>(getUserObjectBaseByName(object_name, is_dependency)); 180 : } 181 : 182 : template <class T> 183 : bool 184 30 : UserObjectInterface::hasUserObject(const std::string & param_name) const 185 : { 186 30 : return hasUserObjectByName<T>(getUserObjectName(param_name)); 187 : } 188 : 189 : template <class T> 190 : bool 191 74 : UserObjectInterface::hasUserObjectByName(const UserObjectName & object_name) const 192 : { 193 74 : if (!hasUserObjectByName(object_name)) 194 0 : return false; 195 74 : return dynamic_cast<const T *>(&getUserObjectFromFEProblem(object_name)); 196 : }