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