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 "DataIO.h" 14 : #include "MooseUtils.h" 15 : 16 : // C++ includes 17 : #include <memory> 18 : #include <vector> 19 : #include <unordered_set> 20 : #include <unordered_map> 21 : 22 : #include "nlohmann/json.h" 23 : 24 : class RestartableDataReader; 25 : class RestartableDataWriter; 26 : class MooseApp; 27 : 28 : /** 29 : * Abstract definition of a RestartableData value. 30 : */ 31 : class RestartableDataValue 32 : { 33 : public: 34 : /** 35 : * Constructor 36 : * @param name The full (unique) name for this piece of data. 37 : * @param context 'typeless' pointer to user-specific data. 38 : */ 39 : RestartableDataValue(const std::string & name, void * const context); 40 : 41 : /** 42 : * Destructor. 43 : */ 44 3375351 : virtual ~RestartableDataValue() = default; 45 : 46 : /** 47 : * String identifying the type of parameter stored. 48 : * Must be reimplemented in derived classes. 49 : */ 50 : virtual std::string type() const = 0; 51 : 52 : /** 53 : * The type ID of the underlying data. 54 : */ 55 : virtual const std::type_info & typeId() const = 0; 56 : 57 : /** 58 : * The full (unique) name of this particular piece of data. 59 : */ 60 8206842 : const std::string & name() const { return _name; } 61 : 62 : /** 63 : * A context pointer for helping with load / store. 64 : */ 65 : void * context() { return _context; } 66 : 67 : /** 68 : * @return Whether or not the data has context set. 69 : */ 70 1809264 : bool hasContext() const { return _context != nullptr; } 71 : 72 : /** 73 : * Helper that protects access to setDeclared() to only MooseApp 74 : */ 75 : class SetDeclaredKey 76 : { 77 : friend class MooseApp; 78 2329574 : SetDeclaredKey() {} 79 : SetDeclaredKey(const SetDeclaredKey &) {} 80 : }; 81 : 82 : /** 83 : * Whether or not this data has been declared 84 : */ 85 173240 : bool declared() const { return _declared; } 86 : 87 : /** 88 : * Sets that this restartable value has been declared 89 : */ 90 : void setDeclared(const SetDeclaredKey); 91 : 92 : /** 93 : * Whether or not this data has been loaded 94 : * 95 : * This is typically reset on a call to 96 : * RestartableDataReader::restore() 97 : */ 98 76 : bool loaded() const { return _loaded; } 99 : 100 : /** 101 : * Helper that protects access to setNotLoaded() to only RestartableDataReader 102 : */ 103 : class SetNotLoadedKey 104 : { 105 : friend class RestartableDataReader; 106 533079 : SetNotLoadedKey() {} 107 : SetNotLoadedKey(const SetNotLoadedKey &) {} 108 : }; 109 : 110 : /** 111 : * Sets that this restartable value has been loaded 112 : */ 113 533079 : void setNotLoaded(const SetNotLoadedKey) { _loaded = false; } 114 : 115 : /** 116 : * Whether or not this data has been loaded 117 : * 118 : * This is typically reset on a call to 119 : * RestartableDataWriter::write() 120 : */ 121 74 : bool stored() const { return _stored; } 122 : 123 : /** 124 : * Helper that protects access to setNotStored() to only RestartableDataWriter 125 : */ 126 : class SetNotStoredKey 127 : { 128 : friend class RestartableDataWriter; 129 1809270 : SetNotStoredKey() {} 130 : SetNotStoredKey(const SetNotStoredKey &) {} 131 : }; 132 : 133 : /** 134 : * Sets that this restartable value has been loaded 135 : */ 136 1809270 : void setNotStored(const SetNotStoredKey) { _stored = false; } 137 : 138 : /** 139 : * Stores the value into the stream \p stream and sets it as stored 140 : */ 141 : void store(std::ostream & stream); 142 : /** 143 : * Loads the value from the stream \p stream and sets it as loaded 144 : */ 145 : void load(std::istream & stream); 146 : 147 : /** 148 : * Internal method that stores the value into the stream \p stream 149 : * in the specialized class. 150 : */ 151 : virtual void storeInternal(std::ostream & stream) = 0; 152 : /** 153 : * Internal method that loads the value from the stream \p stream 154 : * in the specialized class. 155 : */ 156 : virtual void loadInternal(std::istream & stream) = 0; 157 : 158 : /** 159 : * @return Whether or not this value supports storing JSON via \p store 160 : */ 161 : virtual bool hasStoreJSON() const = 0; 162 : 163 : /** 164 : * Struct that represents parameters for how to store the JSON value via \p store 165 : */ 166 : struct StoreJSONParams 167 : { 168 540 : StoreJSONParams() {} // fixes a compiler bug with default constructors 169 : bool value = true; 170 : bool type = true; 171 : bool name = false; 172 : bool declared = false; 173 : bool loaded = false; 174 : bool stored = false; 175 : bool has_context = false; 176 : }; 177 : 178 : /** 179 : * Stores this restartable data in the JSON entry \p json, with the options 180 : * set by \p params (optional; defaults to just the type and underlying value) 181 : * 182 : * If the underlying type is not supported for JSON output (if hasStoreJSON() == false), 183 : * and the parameters have the value output as enabled, this will error. 184 : */ 185 : void store(nlohmann::json & json, const StoreJSONParams & params = StoreJSONParams{}) const; 186 : 187 : protected: 188 : /** 189 : * Internal method for storing the underlying JSON value 190 : */ 191 : virtual void storeJSONValue(nlohmann::json & json) const = 0; 192 : 193 : /// The full (unique) name of this particular piece of data. 194 : const std::string _name; 195 : 196 : /// A context pointer for helping with load and store 197 : void * const _context; 198 : 199 : private: 200 : /// Whether or not this data has been declared (true) or only retreived (false) 201 : bool _declared; 202 : 203 : /// Whether or not this has value has been loaded 204 : bool _loaded; 205 : 206 : /// Whether or not this has value has been stored 207 : bool _stored; 208 : }; 209 : 210 : /** 211 : * Concrete definition of a parameter value 212 : * for a specified type. 213 : */ 214 : template <typename T> 215 : class RestartableData : public RestartableDataValue 216 : { 217 : public: 218 : /// Whether or not this type has a JSON store method implemented 219 : static constexpr bool has_store_json = std::is_constructible_v<nlohmann::json, T>; 220 : 221 : /** 222 : * Constructor 223 : * @param name The full (unique) name for this piece of data. 224 : * @param context 'typeless' pointer to user-specific data. 225 : * @param arg Forwarded arguments that are passed to the constructor of the data. 226 : */ 227 : template <typename... Params> 228 3527824 : RestartableData(const std::string & name, void * const context, Params &&... args) 229 : : RestartableDataValue(name, context), 230 3527824 : _value(std::make_unique<T>(std::forward<Params>(args)...)) 231 : { 232 3527824 : } 233 : 234 : /** 235 : * @returns a read-only reference to the parameter value. 236 : */ 237 : const T & get() const; 238 : 239 : /** 240 : * @returns a writable reference to the parameter value. 241 : */ 242 : T & set(); 243 : 244 : /** 245 : * Resets (destructs) the underlying data. 246 : */ 247 : void reset(); 248 : 249 : /** 250 : * String identifying the type of parameter stored. 251 : */ 252 : virtual std::string type() const override final; 253 : 254 6542712 : virtual const std::type_info & typeId() const override final { return typeid(T); } 255 : 256 774 : virtual bool hasStoreJSON() const override final { return has_store_json; } 257 : 258 : protected: 259 : /** 260 : * Store the RestartableData into a binary stream 261 : */ 262 : virtual void storeInternal(std::ostream & stream) override; 263 : 264 : /** 265 : * Load the RestartableData from a binary stream 266 : */ 267 : virtual void loadInternal(std::istream & stream) override; 268 : 269 : virtual void storeJSONValue(nlohmann::json & json) const override final; 270 : 271 : private: 272 : /// Stored value. 273 : std::unique_ptr<T> _value; 274 : }; 275 : 276 : // ------------------------------------------------------------ 277 : // RestartableData<> class inline methods 278 : template <typename T> 279 : inline const T & 280 2796525 : RestartableData<T>::get() const 281 : { 282 : mooseAssert(_value, "Not valid"); 283 2796525 : return *_value; 284 : } 285 : 286 : template <typename T> 287 : inline T & 288 6570381 : RestartableData<T>::set() 289 : { 290 : mooseAssert(_value, "Not valid"); 291 6570381 : return *_value; 292 : } 293 : 294 : template <typename T> 295 : inline void 296 53503 : RestartableData<T>::reset() 297 : { 298 : mooseAssert(_value, "Not valid"); // shouldn't really call this twice 299 53503 : _value.reset(); 300 53503 : } 301 : 302 : template <typename T> 303 : inline std::string 304 371 : RestartableData<T>::type() const 305 : { 306 371 : return MooseUtils::prettyCppType<T>(); 307 : } 308 : 309 : template <typename T> 310 : inline void 311 1767780 : RestartableData<T>::storeInternal(std::ostream & stream) 312 : { 313 1767780 : storeHelper(stream, set(), _context); 314 1767776 : } 315 : 316 : template <typename T> 317 : inline void 318 512934 : RestartableData<T>::loadInternal(std::istream & stream) 319 : { 320 512934 : loadHelper(stream, set(), _context); 321 512907 : } 322 : 323 : template <typename T> 324 : inline void 325 331 : RestartableData<T>::storeJSONValue(nlohmann::json & json) const 326 : { 327 : if constexpr (RestartableData<T>::has_store_json) 328 331 : nlohmann::to_json(json, get()); 329 : else 330 : mooseAssert(false, "Should not be called"); 331 331 : } 332 : 333 : using DataNames = std::unordered_set<std::string>;