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 "RestartableData.h"
15 :
16 : // Forward declarations
17 : class PostprocessorData;
18 : class SubProblem;
19 : class InputParameters;
20 : class MooseObject;
21 : class MooseApp;
22 : class MooseMesh;
23 :
24 : /**
25 : * A class for creating restricted objects
26 : * \see BlockRestartable BoundaryRestartable
27 : */
28 : class Restartable
29 : {
30 : public:
31 : /**
32 : * Wrapper class for restartable data that is "managed.'
33 : *
34 : * Managed here means that the destruction of the data
35 : * is managed by the reciever and not the app.
36 : *
37 : * When this wrapper is destructed, the underlying
38 : * restartable data is also destructed. This allows for
39 : * proper construction ordered destruction.
40 : */
41 : template <typename T>
42 : class ManagedValue
43 : {
44 : public:
45 57974 : ManagedValue<T>(RestartableData<T> & value) : _value(value) {}
46 :
47 : /**
48 : * Destructor.
49 : *
50 : * Destructs the managed restartable data.
51 : */
52 53701 : ~ManagedValue<T>() { _value.reset(); }
53 :
54 : /**
55 : * Get the restartable value.
56 : */
57 : ///@{
58 : const T & get() const { return _value.get(); }
59 1513602 : T & set() { return _value.set(); }
60 : ///@}
61 :
62 : private:
63 : /// The underlying data
64 : RestartableData<T> & _value;
65 : };
66 :
67 : /**
68 : * Class constructor
69 : *
70 : * @param moose_object The MooseObject that this interface is being implemented on.
71 : * @param system_name The name of the MOOSE system. ie "Kernel", "BCs", etc. Should roughly
72 : * correspond to the section in the input file so errors are easy to understand.
73 : *
74 : * This method will forward the thread id if it exists in the moose_object parameters. Delegates
75 : * to the "MooseApp &" constructor.
76 : */
77 : Restartable(const MooseObject * moose_object, const std::string & system_name);
78 :
79 : /**
80 : * Class constructor
81 : *
82 : * Similar to the other class constructor but also accepts an individual thread ID. If this
83 : * method is used, no thread ID in the parameters object is used. Delegates to the "MooseApp &"
84 : * constructor.
85 : */
86 : Restartable(const MooseObject * moose_object, const std::string & system_name, THREAD_ID tid);
87 :
88 : /**
89 : * This class constructor is used for non-Moose-based objects like interfaces. A name for the
90 : * storage as well as a system name must be passed in along with the thread ID explicitly.
91 : * @param moose_app Reference to the application
92 : * @param name The name which is used when constructing the full-names of the restartable data.
93 : * It is used with the following logic: `system_name/name/data_name`.
94 : * (e.g. UserObjects/diffusion_kernel/coefficient). In most of the cases this is the
95 : * name of the moose object.
96 : * @param system_name The name of the system where this object belongs to.
97 : * @param tid The thread ID.
98 : * @param read_only Switch to restrict the data for read-only.
99 : * @param metaname The name of the datamap where the restartable objects should be registered to.
100 : */
101 : Restartable(MooseApp & moose_app,
102 : const std::string & name,
103 : const std::string & system_name,
104 : THREAD_ID tid,
105 : const bool read_only = false,
106 : const RestartableDataMapName & metaname = "");
107 :
108 : protected:
109 : /**
110 : * Declare a piece of data as "restartable" and initialize it.
111 : * This means that in the event of a restart this piece of data
112 : * will be restored back to its previous value.
113 : *
114 : * NOTE: This returns a _reference_! Make sure you store it in a _reference_!
115 : *
116 : * @param data_name The name of the data (usually just use the same name as the member variable)
117 : * @param args Arguments to forward to the constructor of the data
118 : */
119 : template <typename T, typename... Args>
120 : T & declareRestartableData(const std::string & data_name, Args &&... args);
121 :
122 : /**
123 : * Declares a piece of "managed" restartable data and initialize it.
124 : *
125 : * Here, "managed" restartable data means that the caller can destruct this data
126 : * upon destruction of the return value of this method. Therefore, this
127 : * ManagedValue<T> wrapper should survive after the final calls to dataStore()
128 : * for it. That is... at the very end.
129 : *
130 : * This is needed for objects whose destruction ordering is important, and
131 : * enables natural c++ destruction in reverse construction order of the object
132 : * that declares it.
133 : *
134 : * See delcareRestartableData and declareRestartableDataWithContext for more information.
135 : */
136 : template <typename T, typename... Args>
137 : ManagedValue<T> declareManagedRestartableDataWithContext(const std::string & data_name,
138 : void * context,
139 : Args &&... args);
140 :
141 : /**
142 : * Declare a piece of data as "restartable" and initialize it
143 : * Similar to `declareRestartableData` but returns a const reference to the object.
144 : * Forwarded arguments are not allowed in this case because we assume that the
145 : * object is restarted and we won't need different constructors to initialize it.
146 : *
147 : * NOTE: This returns a _const reference_! Make sure you store it in a _const reference_!
148 : *
149 : * @param data_name The name of the data (usually just use the same name as the member variable)
150 : */
151 : template <typename T, typename... Args>
152 : const T & getRestartableData(const std::string & data_name) const;
153 :
154 : /**
155 : * Declare a piece of data as "restartable" and initialize it.
156 : * This means that in the event of a restart this piece of data
157 : * will be restored back to its previous value.
158 : *
159 : * NOTE: This returns a _reference_! Make sure you store it in a _reference_!
160 : *
161 : * @param data_name The name of the data (usually just use the same name as the member variable)
162 : * @param context Context pointer that will be passed to the load and store functions
163 : * @param args Arguments to forward to the constructor of the data
164 : */
165 : template <typename T, typename... Args>
166 : T &
167 : declareRestartableDataWithContext(const std::string & data_name, void * context, Args &&... args);
168 :
169 : /**
170 : * Declare a piece of data as "recoverable" and initialize it.
171 : * This means that in the event of a restart this piece of data
172 : * will be restored back to its previous value.
173 : *
174 : * Note - this data will NOT be restored on _Restart_!
175 : *
176 : * NOTE: This returns a _reference_! Make sure you store it in a _reference_!
177 : *
178 : * @param data_name The name of the data (usually just use the same name as the member variable)
179 : * @param args Arguments to forward to the constructor of the data
180 : */
181 : template <typename T, typename... Args>
182 : T & declareRecoverableData(const std::string & data_name, Args &&... args);
183 :
184 : /**
185 : * Declare a piece of data as "restartable".
186 : * This means that in the event of a restart this piece of data
187 : * will be restored back to its previous value.
188 : *
189 : * NOTE: This returns a _reference_! Make sure you store it in a _reference_!
190 : *
191 : * @param data_name The name of the data (usually just use the same name as the member variable)
192 : * @param object_name A supplied name for the object that is declaring this data.
193 : * @param args Arguments to forward to the constructor of the data
194 : */
195 : template <typename T, typename... Args>
196 : T & declareRestartableDataWithObjectName(const std::string & data_name,
197 : const std::string & object_name,
198 : Args &&... args);
199 :
200 : /**
201 : * Declare a piece of data as "restartable".
202 : * This means that in the event of a restart this piece of data
203 : * will be restored back to its previous value.
204 : *
205 : * NOTE: This returns a _reference_! Make sure you store it in a _reference_!
206 : *
207 : * @param data_name The name of the data (usually just use the same name as the member variable)
208 : * @param object_name A supplied name for the object that is declaring this data.
209 : * @param context Context pointer that will be passed to the load and store functions
210 : * @param args Arguments to forward to the constructor of the data
211 : */
212 : template <typename T, typename... Args>
213 : T & declareRestartableDataWithObjectNameWithContext(const std::string & data_name,
214 : const std::string & object_name,
215 : void * context,
216 : Args &&... args);
217 :
218 : /**
219 : * Gets the name of a piece of restartable data given a data name, adding
220 : * the system name and object name prefix.
221 : *
222 : * This should only be used in this interface and in testing.
223 : */
224 : std::string restartableName(const std::string & data_name) const;
225 :
226 : /// Reference to the application
227 : MooseApp & _restartable_app;
228 :
229 : /// The system name this object is in
230 : const std::string _restartable_system_name;
231 :
232 : /// The thread ID for this object
233 : const THREAD_ID _restartable_tid;
234 :
235 : /// Flag for toggling read only status (see ReporterData)
236 : const bool _restartable_read_only;
237 :
238 : private:
239 : /// Restartable metadata name
240 : const RestartableDataMapName _metaname;
241 :
242 : /// The name of the object
243 : std::string _restartable_name;
244 :
245 : /// Helper function for actually registering the restartable data.
246 : RestartableDataValue & registerRestartableDataOnApp(std::unique_ptr<RestartableDataValue> data,
247 : THREAD_ID tid) const;
248 :
249 : /// Helper function for actually registering the restartable data.
250 : void registerRestartableNameWithFilterOnApp(const std::string & name,
251 : Moose::RESTARTABLE_FILTER filter);
252 :
253 : /**
254 : * Helper function for declaring restartable data. We use this function to reduce code duplication
255 : * when returning const/nonconst references to the data.
256 : *
257 : * @param data_name The name of the data (usually just use the same name as the member variable)
258 : * @param context Context pointer that will be passed to the load and store functions
259 : * @param args Arguments to forward to the constructor of the data
260 : */
261 : template <typename T, typename... Args>
262 : RestartableData<T> & declareRestartableDataHelper(const std::string & data_name,
263 : void * context,
264 : Args &&... args) const;
265 : };
266 :
267 : template <typename T, typename... Args>
268 : T &
269 856916 : Restartable::declareRestartableData(const std::string & data_name, Args &&... args)
270 : {
271 856916 : return declareRestartableDataWithContext<T>(data_name, nullptr, std::forward<Args>(args)...);
272 : }
273 :
274 : template <typename T, typename... Args>
275 : Restartable::ManagedValue<T>
276 57974 : Restartable::declareManagedRestartableDataWithContext(const std::string & data_name,
277 : void * context,
278 : Args &&... args)
279 : {
280 : auto & data_ptr =
281 57974 : declareRestartableDataHelper<T>(data_name, context, std::forward<Args>(args)...);
282 57974 : return Restartable::ManagedValue<T>(data_ptr);
283 : }
284 :
285 : template <typename T, typename... Args>
286 : const T &
287 : Restartable::getRestartableData(const std::string & data_name) const
288 : {
289 : return declareRestartableDataHelper<T>(data_name, nullptr).get();
290 : }
291 :
292 : template <typename T, typename... Args>
293 : T &
294 1895959 : Restartable::declareRestartableDataWithContext(const std::string & data_name,
295 : void * context,
296 : Args &&... args)
297 : {
298 1895959 : return declareRestartableDataHelper<T>(data_name, context, std::forward<Args>(args)...).set();
299 : }
300 :
301 : template <typename T, typename... Args>
302 : RestartableData<T> &
303 1953933 : Restartable::declareRestartableDataHelper(const std::string & data_name,
304 : void * context,
305 : Args &&... args) const
306 : {
307 1953933 : const auto full_name = restartableName(data_name);
308 :
309 : // Here we will create the RestartableData even though we may not use this instance.
310 : // If it's already in use, the App will return a reference to the existing instance and we'll
311 : // return that one instead. We might refactor this to have the app create the RestartableData
312 : // at a later date.
313 1953933 : auto data_ptr =
314 : std::make_unique<RestartableData<T>>(full_name, context, std::forward<Args>(args)...);
315 : auto & restartable_data_ref = static_cast<RestartableData<T> &>(
316 1953933 : registerRestartableDataOnApp(std::move(data_ptr), _restartable_tid));
317 :
318 1953933 : return restartable_data_ref;
319 1953933 : }
320 :
321 : template <typename T, typename... Args>
322 : T &
323 : Restartable::declareRestartableDataWithObjectName(const std::string & data_name,
324 : const std::string & object_name,
325 : Args &&... args)
326 : {
327 : return declareRestartableDataWithObjectNameWithContext<T>(
328 : data_name, object_name, nullptr, std::forward<Args>(args)...);
329 : }
330 :
331 : template <typename T, typename... Args>
332 : T &
333 : Restartable::declareRestartableDataWithObjectNameWithContext(const std::string & data_name,
334 : const std::string & object_name,
335 : void * context,
336 : Args &&... args)
337 : {
338 : std::string old_name = _restartable_name;
339 :
340 : _restartable_name = object_name;
341 :
342 : T & value = declareRestartableDataWithContext<T>(data_name, context, std::forward<Args>(args)...);
343 :
344 : _restartable_name = old_name;
345 :
346 : return value;
347 : }
348 :
349 : template <typename T, typename... Args>
350 : T &
351 742265 : Restartable::declareRecoverableData(const std::string & data_name, Args &&... args)
352 : {
353 742265 : const auto full_name = restartableName(data_name);
354 :
355 742265 : registerRestartableNameWithFilterOnApp(full_name, Moose::RESTARTABLE_FILTER::RECOVERABLE);
356 :
357 1484530 : return declareRestartableDataWithContext<T>(data_name, nullptr, std::forward<Args>(args)...);
358 742265 : }
|