ryujin 2.5.0 revision c64172211cf21344cb9b9b0f3a1266aa6400d392
Loading...
Searching...
No Matches
task.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// Copyright (C) 2026 by the ryujin authors
4//
5
6#pragma once
7
8#include <ryujin/base/compile_time_options.h>
11
12#include <deal.II/base/parameter_acceptor.h>
13
14#include <boost/archive/binary_iarchive.hpp>
15#include <boost/archive/binary_oarchive.hpp>
16
17#include <algorithm>
18#include <cstddef>
19#include <cstdint>
20#include <functional>
21#include <limits>
22#include <span>
23#include <string>
24#include <vector>
25
26namespace ryujin
27{
33 enum class TaskPhase : std::uint8_t {
39
45 adapt,
46
52 step,
53
58 };
59
60
66 enum class TriggerMode : std::uint8_t {
71
77
83
90 };
91} // namespace ryujin
92
93#ifndef DOXYGEN
94DECLARE_ENUM(ryujin::TriggerMode,
95 LIST({ryujin::TriggerMode::every_cycle, "every cycle"},
96 {ryujin::TriggerMode::timer_tick, "timer tick"},
97 {ryujin::TriggerMode::wall_clock, "wall clock"},
98 {ryujin::TriggerMode::time_points, "time points"}, ));
99#endif
100
101namespace ryujin
102{
103 namespace Interface
104 {
105 template <typename Number>
106 class Task;
107 } // namespace Interface
108
109
118 template <typename Number = double>
119 struct TaskContext {
124 bool tick_reached() const
125 {
126 constexpr Number relax =
127 Number(1.) - Number(10.) * std::numeric_limits<Number>::epsilon();
128 return t >= relax * timer_cycle * timer_granularity;
129 }
130
134 Number t = Number(0.);
135
140 Number tau = Number(0.);
141
146 Number t_max = std::numeric_limits<Number>::max();
147
151 unsigned int cycle = 0;
152
156 unsigned int timer_cycle = 0;
157
163 bool timer_tick = false;
164
169 Number wall_time = Number(0.);
170
174 Number t_final = Number(0.);
175
179 Number timer_granularity = Number(0.);
180
184 std::string base_name;
185
191 bool prepare_required = false;
192
196 std::span<Interface::Task<Number> *const> tasks;
197
201 std::function<void(const std::string &)> info;
202 };
203
204
215 template <typename Number = double>
217 {
218 public:
223 unsigned int multiplier = 1,
224 Number interval = Number(0.))
225 : mode_(mode)
226 , multiplier_(multiplier)
227 , interval_(interval)
228 , last_fired_(Number(0.))
229 {
230 }
231
232 Trigger(const Trigger &) = delete;
233 Trigger &operator=(const Trigger &) = delete;
234
240 void add_parameters(dealii::ParameterAcceptor &acceptor,
241 const std::string &prefix = "trigger")
242 {
243 acceptor.add_parameter(
244 prefix,
245 mode_,
246 "The condition under which the task is executed: every cycle, timer "
247 "tick, wall clock, time points");
248
249 acceptor.add_parameter(prefix + " multiplier",
250 multiplier_,
251 "Execute only in every n-th cycle (every cycle), "
252 "or at every n-th timer tick (timer tick)");
253
254 acceptor.add_parameter(prefix + " interval",
255 interval_,
256 "Execute after the given number of seconds of "
257 "wall time have passed (wall clock)");
258
259 acceptor.add_parameter(prefix + " time points",
260 time_points_,
261 "Execute once whenever the time has reached one "
262 "of the given time points (time points)");
263
264 acceptor.parse_parameters_call_back.connect([this] {
265 std::ranges::sort(time_points_);
266 next_time_point_ = std::numeric_limits<std::size_t>::max();
267 });
268 }
269
273 bool fire(const TaskContext<Number> &context)
274 {
275 switch (mode_) {
277 return context.cycle % multiplier_ == 0;
278
280 return context.timer_tick && context.timer_cycle % multiplier_ == 0;
281
283 if (context.wall_time < last_fired_ + interval_)
284 return false;
285 last_fired_ = context.wall_time;
286 return true;
287
289 /* Skip all time points before the first evaluation: */
290 if (next_time_point_ == std::numeric_limits<std::size_t>::max()) {
291 next_time_point_ = 0;
292 while (next_time_point_ < time_points_.size() &&
293 time_points_[next_time_point_] < context.t)
294 ++next_time_point_;
295 }
296
297 bool fire = false;
298 while (next_time_point_ < time_points_.size() &&
299 time_points_[next_time_point_] <= context.t) {
300 ++next_time_point_;
301 fire = true;
302 }
303 return fire;
304 }
305 }
306
307 __builtin_unreachable();
308 }
309
310 private:
311 TriggerMode mode_;
312 unsigned int multiplier_;
313 Number interval_;
314 std::vector<Number> time_points_;
315
316 Number last_fired_;
317 std::size_t next_time_point_ = std::numeric_limits<std::size_t>::max();
318 };
319
320
321 namespace Interface
322 {
341 template <typename Number = double>
342 class Task
343 {
344 public:
348 virtual ~Task() = default;
349
354
360 virtual void initialize(TaskContext<Number> & /*context*/) {}
361
368 virtual void start(TaskContext<Number> & /*context*/) {}
369
378 virtual void prepare(TaskContext<Number> & /*context*/) {}
379
381
385
390 virtual void execute(TaskContext<Number> &context) = 0;
391
395 virtual void finalize(TaskContext<Number> & /*context*/) {}
396
398
402
407 virtual void save(boost::archive::binary_oarchive & /*archive*/) const {}
408
413 virtual void load(boost::archive::binary_iarchive & /*archive*/) {}
414
416
420
426
427
430 ACCESSOR_READ_ONLY(phase)
431
432 //@}
433
434 protected:
439 Task(const std::string &name, TaskPhase phase)
440 : name_(name)
441 , phase_(phase)
442 {
443 }
444
445 private:
446 std::string name_;
447 TaskPhase phase_;
448 };
449 } // namespace Interface
450} // namespace ryujin
virtual void prepare(TaskContext< Number > &)
Definition task.h:378
virtual ~Task()=default
virtual void load(boost::archive::binary_iarchive &)
Definition task.h:413
Task(const std::string &name, TaskPhase phase)
Definition task.h:439
virtual void save(boost::archive::binary_oarchive &) const
Definition task.h:407
virtual void execute(TaskContext< Number > &context)=0
virtual void finalize(TaskContext< Number > &)
Definition task.h:395
virtual void start(TaskContext< Number > &)
Definition task.h:368
virtual void initialize(TaskContext< Number > &)
Definition task.h:360
bool fire(const TaskContext< Number > &context)
Definition task.h:273
Trigger & operator=(const Trigger &)=delete
Trigger(TriggerMode mode=TriggerMode::timer_tick, unsigned int multiplier=1, Number interval=Number(0.))
Definition task.h:222
Trigger(const Trigger &)=delete
void add_parameters(dealii::ParameterAcceptor &acceptor, const std::string &prefix="trigger")
Definition task.h:240
TriggerMode
Definition task.h:66
TaskPhase
Definition task.h:33
#define ACCESSOR_READ_ONLY(member)
std::span< Interface::Task< Number > *const > tasks
Definition task.h:196
unsigned int timer_cycle
Definition task.h:156
Number wall_time
Definition task.h:169
unsigned int cycle
Definition task.h:151
bool tick_reached() const
Definition task.h:124
std::function< void(const std::string &)> info
Definition task.h:201
bool prepare_required
Definition task.h:191
std::string base_name
Definition task.h:184
Number timer_granularity
Definition task.h:179