Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <optional>
7 :
8 : /// \cond
9 : namespace PUP {
10 : class er;
11 : } // namespace PUP
12 : /// \endcond
13 :
14 : /// Information on a requested time-step size returned by `StepChooser`s.
15 : ///
16 : /// Requests made using this struct control most of the changing of
17 : /// slab and local-time-stepping step sizes. Slab-size changing is
18 : /// more complex, as it is controlled using the `ChangeSlabSize`
19 : /// event, which may run zero or more times per slab, and may have the
20 : /// application of its result delayed. The step size for LTS is
21 : /// adjusted using a constant list of `StepChoosers` on every step.
22 : ///
23 : /// For slab-size adjustment (including the global time step when not
24 : /// using LTS), a "goal" step size is maintained from step to step.
25 : /// It is initially the initial slab size from the input file, and can
26 : /// be adjusted by any request setting the `size_goal` field of this
27 : /// struct. If multiple requests set new goals at the same time, the
28 : /// smallest value is used. At the start of each slab, the size is
29 : /// chosen to be the smallest of the current goal and the temporary
30 : /// limits imposed by any requests processed at that time. For the
31 : /// LTS step size, the current step size is used as the goal if no
32 : /// request sets a new one.
33 : ///
34 : /// Any request with either the `size` or `end` fields set introduces
35 : /// a temporary step size limit. If only one of the two is set, the
36 : /// chosen step size will be limited to be not larger than `*size`, or
37 : /// not go beyond the time `*end`. If both are set, the tighter limit
38 : /// may be ignored if the looser limit is chosen as the actual step,
39 : /// but the step will not be chosen to be intermediate between two
40 : /// temporary limits from the same request object.
41 : ///
42 : /// The hard limits are not used in setting the step size, but if the
43 : /// actual step does not satisfy all hard limits from all requests the
44 : /// evolution will be terminated with an error.
45 : ///
46 : /// \note All step sizes are subject to roundoff error in either
47 : /// direction except for two cases:
48 : /// * Slab sizes imposed by the `end` limit of a request will always
49 : /// end precisely at the requested time.
50 : /// * LTS step sizes within a single slab will always be considered to
51 : /// have size ratios that are exactly powers of two for the purposes
52 : /// of the `size_goal` and `size` limits.
53 1 : struct TimeStepRequest {
54 0 : std::optional<double> size_goal{};
55 :
56 0 : std::optional<double> size{};
57 0 : std::optional<double> end{};
58 :
59 0 : std::optional<double> size_hard_limit{};
60 0 : std::optional<double> end_hard_limit{};
61 :
62 0 : void pup(PUP::er& p);
63 : };
64 :
65 0 : bool operator==(const TimeStepRequest& a, const TimeStepRequest& b);
66 0 : bool operator!=(const TimeStepRequest& a, const TimeStepRequest& b);
|