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 64512 : ManagedValue(RestartableData<T> & value) : _value(value) {}
46 :
47 : /**
48 : * Destructor.
49 : *
50 : * Destructs the managed restartable data.
51 : */
52 60096 : ~ManagedValue() { _value.reset(); }
53 :
54 : /**
55 : * Get the restartable value.
56 : */
57 : ///@{
58 0 : const T & get() const { return _value.get(); }
59 1645851 : 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 : #ifdef MOOSE_KOKKOS_ENABLED
109 : /**
110 : * Special constructor used for Kokkos functor copy during parallel dispatch
111 : */
112 : Restartable(const Restartable & object, const Moose::Kokkos::FunctorCopy & key);
113 : #endif
114 :
115 : protected:
116 : /**
117 : * Declare a piece of data as "restartable" and initialize it.
118 : * This means that in the event of a restart this piece of data
119 : * will be restored back to its previous value.
120 : *
121 : * NOTE: This returns a _reference_! Make sure you store it in a _reference_!
122 : *
123 : * @param data_name The name of the data (usually just use the same name as the member variable)
124 : * @param args Arguments to forward to the constructor of the data
125 : */
126 : template <typename T, typename... Args>
127 : T & declareRestartableData(const std::string & data_name, Args &&... args);
128 :
129 : /**
130 : * Declares a piece of "managed" restartable data and initialize it.
131 : *
132 : * Here, "managed" restartable data means that the caller can destruct this data
133 : * upon destruction of the return value of this method. Therefore, this
134 : * ManagedValue<T> wrapper should survive after the final calls to dataStore()
135 : * for it. That is... at the very end.
136 : *
137 : * This is needed for objects whose destruction ordering is important, and
138 : * enables natural c++ destruction in reverse construction order of the object
139 : * that declares it.
140 : *
141 : * See delcareRestartableData and declareRestartableDataWithContext for more information.
142 : */
143 : template <typename T, typename... Args>
144 : ManagedValue<T> declareManagedRestartableDataWithContext(const std::string & data_name,
145 : void * context,
146 : Args &&... args);
147 :
148 : /**
149 : * Declare a piece of data as "restartable" and initialize it
150 : * Similar to `declareRestartableData` but returns a const reference to the object.
151 : * Forwarded arguments are not allowed in this case because we assume that the
152 : * object is restarted and we won't need different constructors to initialize it.
153 : *
154 : * NOTE: This returns a _const reference_! Make sure you store it in a _const reference_!
155 : *
156 : * @param data_name The name of the data (usually just use the same name as the member variable)
157 : */
158 : template <typename T, typename... Args>
159 : const T & getRestartableData(const std::string & data_name) const;
160 :
161 : /**
162 : * Declare a piece of data as "restartable" and initialize it.
163 : * This means that in the event of a restart this piece of data
164 : * will be restored back to its previous value.
165 : *
166 : * NOTE: This returns a _reference_! Make sure you store it in a _reference_!
167 : *
168 : * @param data_name The name of the data (usually just use the same name as the member variable)
169 : * @param context Context pointer that will be passed to the load and store functions
170 : * @param args Arguments to forward to the constructor of the data
171 : */
172 : template <typename T, typename... Args>
173 : T &
174 : declareRestartableDataWithContext(const std::string & data_name, void * context, Args &&... args);
175 :
176 : /**
177 : * Declare a piece of data as "recoverable" and initialize it.
178 : * This means that in the event of a restart this piece of data
179 : * will be restored back to its previous value.
180 : *
181 : * Note - this data will NOT be restored on _Restart_!
182 : *
183 : * NOTE: This returns a _reference_! Make sure you store it in a _reference_!
184 : *
185 : * @param data_name The name of the data (usually just use the same name as the member variable)
186 : * @param args Arguments to forward to the constructor of the data
187 : */
188 : template <typename T, typename... Args>
189 : T & declareRecoverableData(const std::string & data_name, Args &&... args);
190 :
191 : /**
192 : * Declare a piece of data as "restartable".
193 : * This means that in the event of a restart this piece of data
194 : * will be restored back to its previous value.
195 : *
196 : * NOTE: This returns a _reference_! Make sure you store it in a _reference_!
197 : *
198 : * @param data_name The name of the data (usually just use the same name as the member variable)
199 : * @param object_name A supplied name for the object that is declaring this data.
200 : * @param args Arguments to forward to the constructor of the data
201 : */
202 : template <typename T, typename... Args>
203 : T & declareRestartableDataWithObjectName(const std::string & data_name,
204 : const std::string & object_name,
205 : Args &&... args);
206 :
207 : /**
208 : * Declare a piece of data as "restartable".
209 : * This means that in the event of a restart this piece of data
210 : * will be restored back to its previous value.
211 : *
212 : * NOTE: This returns a _reference_! Make sure you store it in a _reference_!
213 : *
214 : * @param data_name The name of the data (usually just use the same name as the member variable)
215 : * @param object_name A supplied name for the object that is declaring this data.
216 : * @param context Context pointer that will be passed to the load and store functions
217 : * @param args Arguments to forward to the constructor of the data
218 : */
219 : template <typename T, typename... Args>
220 : T & declareRestartableDataWithObjectNameWithContext(const std::string & data_name,
221 : const std::string & object_name,
222 : void * context,
223 : Args &&... args);
224 :
225 : /**
226 : * Gets the name of a piece of restartable data given a data name, adding
227 : * the system name and object name prefix.
228 : *
229 : * This should only be used in this interface and in testing.
230 : */
231 : std::string restartableName(const std::string & data_name) const;
232 :
233 : /// Reference to the application
234 : MooseApp & _restartable_app;
235 :
236 : /// The system name this object is in
237 : const std::string _restartable_system_name;
238 :
239 : /// The thread ID for this object
240 : const THREAD_ID _restartable_tid;
241 :
242 : /// Flag for toggling read only status (see ReporterData)
243 : const bool _restartable_read_only;
244 :
245 : private:
246 : /// Restartable metadata name
247 : const RestartableDataMapName _metaname;
248 :
249 : /// The name of the object
250 : std::string _restartable_name;
251 :
252 : /// Helper function for actually registering the restartable data.
253 : RestartableDataValue & registerRestartableDataOnApp(std::unique_ptr<RestartableDataValue> data,
254 : THREAD_ID tid) const;
255 :
256 : /// Helper function for actually registering the restartable data.
257 : void registerRestartableNameWithFilterOnApp(const std::string & name,
258 : Moose::RESTARTABLE_FILTER filter);
259 :
260 : /**
261 : * Helper function for declaring restartable data. We use this function to reduce code duplication
262 : * when returning const/nonconst references to the data.
263 : *
264 : * @param data_name The name of the data (usually just use the same name as the member variable)
265 : * @param context Context pointer that will be passed to the load and store functions
266 : * @param args Arguments to forward to the constructor of the data
267 : */
268 : template <typename T, typename... Args>
269 : RestartableData<T> & declareRestartableDataHelper(const std::string & data_name,
270 : void * context,
271 : Args &&... args) const;
272 : };
273 :
274 : template <typename T, typename... Args>
275 : T &
276 956695 : Restartable::declareRestartableData(const std::string & data_name, Args &&... args)
277 : {
278 956695 : return declareRestartableDataWithContext<T>(data_name, nullptr, std::forward<Args>(args)...);
279 : }
280 :
281 : template <typename T, typename... Args>
282 : Restartable::ManagedValue<T>
283 64512 : Restartable::declareManagedRestartableDataWithContext(const std::string & data_name,
284 : void * context,
285 : Args &&... args)
286 : {
287 : auto & data_ptr =
288 64512 : declareRestartableDataHelper<T>(data_name, context, std::forward<Args>(args)...);
289 64512 : return Restartable::ManagedValue<T>(data_ptr);
290 : }
291 :
292 : template <typename T, typename... Args>
293 : const T &
294 : Restartable::getRestartableData(const std::string & data_name) const
295 : {
296 : return declareRestartableDataHelper<T>(data_name, nullptr).get();
297 : }
298 :
299 : template <typename T, typename... Args>
300 : T &
301 2332554 : Restartable::declareRestartableDataWithContext(const std::string & data_name,
302 : void * context,
303 : Args &&... args)
304 : {
305 2332554 : return declareRestartableDataHelper<T>(data_name, context, std::forward<Args>(args)...).set();
306 : }
307 :
308 : template <typename T, typename... Args>
309 : RestartableData<T> &
310 2397066 : Restartable::declareRestartableDataHelper(const std::string & data_name,
311 : void * context,
312 : Args &&... args) const
313 : {
314 2397066 : const auto full_name = restartableName(data_name);
315 :
316 : // Here we will create the RestartableData even though we may not use this instance.
317 : // If it's already in use, the App will return a reference to the existing instance and we'll
318 : // return that one instead. We might refactor this to have the app create the RestartableData
319 : // at a later date.
320 2397066 : auto data_ptr =
321 : std::make_unique<RestartableData<T>>(full_name, context, std::forward<Args>(args)...);
322 1102 : auto & restartable_data_ref = static_cast<RestartableData<T> &>(
323 2395964 : registerRestartableDataOnApp(std::move(data_ptr), _restartable_tid));
324 :
325 2397066 : return restartable_data_ref;
326 2397066 : }
327 :
328 : template <typename T, typename... Args>
329 : T &
330 : Restartable::declareRestartableDataWithObjectName(const std::string & data_name,
331 : const std::string & object_name,
332 : Args &&... args)
333 : {
334 : return declareRestartableDataWithObjectNameWithContext<T>(
335 : data_name, object_name, nullptr, std::forward<Args>(args)...);
336 : }
337 :
338 : template <typename T, typename... Args>
339 : T &
340 : Restartable::declareRestartableDataWithObjectNameWithContext(const std::string & data_name,
341 : const std::string & object_name,
342 : void * context,
343 : Args &&... args)
344 : {
345 : std::string old_name = _restartable_name;
346 :
347 : _restartable_name = object_name;
348 :
349 : T & value = declareRestartableDataWithContext<T>(data_name, context, std::forward<Args>(args)...);
350 :
351 : _restartable_name = old_name;
352 :
353 : return value;
354 : }
355 :
356 : template <typename T, typename... Args>
357 : T &
358 916010 : Restartable::declareRecoverableData(const std::string & data_name, Args &&... args)
359 : {
360 916010 : const auto full_name = restartableName(data_name);
361 :
362 916010 : registerRestartableNameWithFilterOnApp(full_name, Moose::RESTARTABLE_FILTER::RECOVERABLE);
363 :
364 1832020 : return declareRestartableDataWithContext<T>(data_name, nullptr, std::forward<Args>(args)...);
365 916010 : }
|