Version: SMASH-1.5
smash::Clock Class Reference

#include <clock.h>

Clock tracks the time in the simulation.

The basic unit is 1 fm/c = \(1 / 2.99798542 \cdot 10^{-23}\)s \(\approx 0.33 \cdot 10^{-24}\) s. The resolution of the clock is 0.000001 fm/c. I.e. only multiples of 0.000001 fm/c are representable internally.

Potential usage for adapting time steps:

Clock labtime(0., 0.1);
Clock endtime(10., 0.);
while (labtime < endtime) {
// do something
// adapt the timestep size to external circumstances:
if (system_is_very_dense()) {
labtime.set_timestep_duration(labtime.timestep_duration() / 2.);
}
if (system_is_very_dilute()) {
labtime.set_timestep_duration(labtime.timestep_duration() * 2.);
}
// let the clock tick
++labtime;
}

Possible actions for Clock are:

Clock stores a time step size \(\Delta t\) and a base time \(t_0\) as well as a counter \(n\). The current time is calculated from \(t = t_0 + n \cdot \Delta t\). When \(\Delta t\) is changed, \(t_0\) is reset.

Definition at line 75 of file clock.h.

Collaboration diagram for smash::Clock:
[legend]

Public Types

using Representation = std::int64_t
 The type used for counting ticks/time. More...
 

Public Member Functions

 Clock ()=default
 default initializer: Timestep size is set to 0! More...
 
 Clock (const double time, const double dt)
 Initialize with base time and time step size. More...
 
double current_time () const
 
double next_time () const
 
double timestep_duration () const
 
void set_timestep_duration (const double dt)
 Sets the time step size (and resets the counter). More...
 
bool multiple_is_in_next_tick (const double interval) const
 Checks if a multiple of a given interval is reached within the next tick. More...
 
double next_multiple (const double interval) const
 Returns the next multiple of a given interval. More...
 
void end_tick_on_multiple (const double interval)
 Set the time step such that it ends on the next multiple of the interval. More...
 
void reset (const double reset_time)
 Resets the time to a pre-defined value reset_time. More...
 
Clockoperator++ ()
 Advances the clock by one tick ( \(\Delta t\)). More...
 
template<typename T >
std::enable_if< std::is_floating_point< T >::value, Clock & >::type operator+= (T big_timestep)
 Advances the clock by an arbitrary timestep (multiple of 0.000001 fm/c). More...
 
Clockoperator+= (Representation advance_several_timesteps)
 advances the clock by an arbitrary number of ticks. More...
 
bool operator< (const Clock &rhs) const
 Compares the times between two clocks. More...
 
bool operator< (double time) const
 Compares the time of the clock against a fixed time. More...
 
bool operator> (double time) const
 Compares the time of the clock against a fixed time. More...
 

Static Private Member Functions

static Representation convert (double x)
 Convert a double x into the internal int representation. More...
 
static double convert (Representation x)
 Convert an internal int value x into the double representation. More...
 

Private Attributes

Representation counter_ = 0
 Clock tick. More...
 
Representation timestep_duration_ = 0u
 The time step size \(\Delta t\) in $10^{-3}$ fm. More...
 
Representation reset_time_ = 0
 The time of last reset (when counter_ was set to 0). More...
 

Static Private Attributes

static constexpr double resolution = 0.000001
 Defines the resolution of the clock (i.e. More...
 
static constexpr double to_double = resolution
 A multiplier transfering the internal integer to the real time. More...
 
static constexpr double from_double = 1. / resolution
 A multiplier transfering the real time to the internal integer. More...
 

Member Typedef Documentation

◆ Representation

using smash::Clock::Representation = std::int64_t

The type used for counting ticks/time.

Definition at line 92 of file clock.h.

Constructor & Destructor Documentation

◆ Clock() [1/2]

smash::Clock::Clock ( )
default

default initializer: Timestep size is set to 0!

◆ Clock() [2/2]

smash::Clock::Clock ( const double  time,
const double  dt 
)
inline

Initialize with base time and time step size.

Parameters
[in]timebase time
[in]dtstep size

Definition at line 103 of file clock.h.

105  if (dt < 0.) {
106  throw std::range_error("No negative time increment allowed");
107  }
108  }
Representation timestep_duration_
The time step size in $10^{-3}$ fm.
Definition: clock.h:313
static Representation convert(double x)
Convert a double x into the internal int representation.
Definition: clock.h:301
Representation reset_time_
The time of last reset (when counter_ was set to 0).
Definition: clock.h:315

Member Function Documentation

◆ current_time()

double smash::Clock::current_time ( ) const
inline
Returns
the current time.

Definition at line 110 of file clock.h.

110  {
112  }
Representation counter_
Clock tick.
Definition: clock.h:311
Representation timestep_duration_
The time step size in $10^{-3}$ fm.
Definition: clock.h:313
static Representation convert(double x)
Convert a double x into the internal int representation.
Definition: clock.h:301
Representation reset_time_
The time of last reset (when counter_ was set to 0).
Definition: clock.h:315
Here is the call graph for this function:
Here is the caller graph for this function:

◆ next_time()

double smash::Clock::next_time ( ) const
inline
Returns
the time in the next tick.

This function is needed, because current_time() + timestep_duration() is not the same as the next tick (numerically; this is due to floating point arithmetic).

Definition at line 120 of file clock.h.

120  {
122  std::numeric_limits<Representation>::max() - timestep_duration_) {
123  throw std::overflow_error("Too many timesteps, clock overflow imminent");
124  }
126  }
Representation counter_
Clock tick.
Definition: clock.h:311
Representation timestep_duration_
The time step size in $10^{-3}$ fm.
Definition: clock.h:313
static Representation convert(double x)
Convert a double x into the internal int representation.
Definition: clock.h:301
Representation reset_time_
The time of last reset (when counter_ was set to 0).
Definition: clock.h:315
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timestep_duration()

double smash::Clock::timestep_duration ( ) const
inline
Returns
the time step size.

Definition at line 128 of file clock.h.

128 { return convert(timestep_duration_); }
Representation timestep_duration_
The time step size in $10^{-3}$ fm.
Definition: clock.h:313
static Representation convert(double x)
Convert a double x into the internal int representation.
Definition: clock.h:301
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_timestep_duration()

void smash::Clock::set_timestep_duration ( const double  dt)
inline

Sets the time step size (and resets the counter).

Parameters
[in]dtnew time step size

Definition at line 134 of file clock.h.

134  {
135  if (dt < 0.) {
136  throw std::range_error("No negative time increment allowed");
137  }
139  counter_ = 0;
141  }
Representation counter_
Clock tick.
Definition: clock.h:311
Representation timestep_duration_
The time step size in $10^{-3}$ fm.
Definition: clock.h:313
static Representation convert(double x)
Convert a double x into the internal int representation.
Definition: clock.h:301
Representation reset_time_
The time of last reset (when counter_ was set to 0).
Definition: clock.h:315
Here is the call graph for this function:

◆ multiple_is_in_next_tick()

bool smash::Clock::multiple_is_in_next_tick ( const double  interval) const
inline

Checks if a multiple of a given interval is reached within the next tick.

Parameters
[in]intervalThe interval \(t_i\) at which, for instance, output is expected to happen
Returns
is there a natural number n so that \(n \cdot t_i\) is between the current time and the next time: \(\exists n \in \mathbb{N}: t \le n \cdot t_i < t + \Delta t\).

Internally, it checks if \(n\) is the same for this time step as for the next time step. If so, the next multiple is outside the current time step, if not, then the multiple must be within.

Definition at line 158 of file clock.h.

158  {
159  if (interval < 0.) {
160  throw std::range_error("Negative interval makes no sense for clock");
161  }
162  const Representation int_interval = convert(interval);
163  // if the interval is less than or equal to the time step size, one
164  // multiple will surely be within the next tick!
165  if (int_interval <= timestep_duration_) {
166  return true;
167  }
168  const auto next = reset_time_ + timestep_duration_ * counter_;
169  if (unlikely(next < 0)) {
170  return -next % int_interval < timestep_duration_;
171  }
172  return (timestep_duration_ - 1 + next) % int_interval < timestep_duration_;
173  }
Representation counter_
Clock tick.
Definition: clock.h:311
Representation timestep_duration_
The time step size in $10^{-3}$ fm.
Definition: clock.h:313
static Representation convert(double x)
Convert a double x into the internal int representation.
Definition: clock.h:301
Representation reset_time_
The time of last reset (when counter_ was set to 0).
Definition: clock.h:315
std::int64_t Representation
The type used for counting ticks/time.
Definition: clock.h:92
#define unlikely(x)
Tell the branch predictor that this expression is likely false.
Definition: macros.h:16
Here is the call graph for this function:

◆ next_multiple()

double smash::Clock::next_multiple ( const double  interval) const
inline

Returns the next multiple of a given interval.

Parameters
[in]intervalthe given interval
Returns
The smallest multiple of interval that is larger than the current time.

Definition at line 182 of file clock.h.

182  {
183  const Representation int_interval = convert(interval);
184  const auto current = reset_time_ + timestep_duration_ * counter_;
185  if (unlikely(current < 0)) {
186  return convert(current / int_interval * int_interval);
187  }
188  return convert((current / int_interval + 1) * int_interval);
189  }
Representation counter_
Clock tick.
Definition: clock.h:311
Representation timestep_duration_
The time step size in $10^{-3}$ fm.
Definition: clock.h:313
static Representation convert(double x)
Convert a double x into the internal int representation.
Definition: clock.h:301
Representation reset_time_
The time of last reset (when counter_ was set to 0).
Definition: clock.h:315
std::int64_t Representation
The type used for counting ticks/time.
Definition: clock.h:92
#define unlikely(x)
Tell the branch predictor that this expression is likely false.
Definition: macros.h:16
Here is the call graph for this function:

◆ end_tick_on_multiple()

void smash::Clock::end_tick_on_multiple ( const double  interval)
inline

Set the time step such that it ends on the next multiple of the interval.

Parameters
intervalThe given interval

Definition at line 195 of file clock.h.

195  {
196  const Representation int_interval = convert(interval);
197  const auto current = reset_time_ + timestep_duration_ * counter_;
198  reset_time_ = current;
199  counter_ = 0;
200  if (unlikely(current < 0)) {
201  timestep_duration_ = current / int_interval * int_interval - current;
202  } else {
204  (current / int_interval + 1) * int_interval - current;
205  }
206  }
Representation counter_
Clock tick.
Definition: clock.h:311
Representation timestep_duration_
The time step size in $10^{-3}$ fm.
Definition: clock.h:313
static Representation convert(double x)
Convert a double x into the internal int representation.
Definition: clock.h:301
Representation reset_time_
The time of last reset (when counter_ was set to 0).
Definition: clock.h:315
std::int64_t Representation
The type used for counting ticks/time.
Definition: clock.h:92
#define unlikely(x)
Tell the branch predictor that this expression is likely false.
Definition: macros.h:16
Here is the call graph for this function:

◆ reset()

void smash::Clock::reset ( const double  reset_time)
inline

Resets the time to a pre-defined value reset_time.

This is the only way of turning the clock back. It is needed so that the time can be adjusted after initialization (different initial conditions may require different starting times).

Parameters
[in]reset_timeNew time

Definition at line 216 of file clock.h.

216  {
217  if (reset_time < current_time()) {
218  logger<LogArea::Clock>().debug("Resetting clock from", current_time(),
219  " fm/c to ", reset_time, " fm/c");
220  }
221  reset_time_ = convert(reset_time);
222  counter_ = 0;
223  }
Representation counter_
Clock tick.
Definition: clock.h:311
static Representation convert(double x)
Convert a double x into the internal int representation.
Definition: clock.h:301
Representation reset_time_
The time of last reset (when counter_ was set to 0).
Definition: clock.h:315
double current_time() const
Definition: clock.h:110
Here is the call graph for this function:

◆ operator++()

Clock& smash::Clock::operator++ ( )
inline

Advances the clock by one tick ( \(\Delta t\)).

This operator is used as ++clock. The operator clock++ is not implemented deliberately, because that requires a copy of the clock being created.

Definition at line 231 of file clock.h.

231  {
232  // guard against overflow:
233  if (counter_ >= std::numeric_limits<Representation>::max() - 1) {
234  throw std::overflow_error("Too many timesteps, clock overflow imminent");
235  }
236  ++counter_;
237  return *this;
238  }
Representation counter_
Clock tick.
Definition: clock.h:311

◆ operator+=() [1/2]

template<typename T >
std::enable_if<std::is_floating_point<T>::value, Clock&>::type smash::Clock::operator+= ( big_timestep)
inline

Advances the clock by an arbitrary timestep (multiple of 0.000001 fm/c).

Template Parameters
Ttype of the timestep
Parameters
[in]big_timestepTimestep by which the clock is advanced.
Note
It uses a template parameter only for disambiguation with the overload below.

Definition at line 249 of file clock.h.

249  {
250  if (big_timestep < 0.) {
251  throw std::range_error("The clock cannot be turned back.");
252  }
253  reset_time_ += convert(big_timestep);
254  return *this;
255  }
static Representation convert(double x)
Convert a double x into the internal int representation.
Definition: clock.h:301
Representation reset_time_
The time of last reset (when counter_ was set to 0).
Definition: clock.h:315
Here is the call graph for this function:

◆ operator+=() [2/2]

Clock& smash::Clock::operator+= ( Representation  advance_several_timesteps)
inline

advances the clock by an arbitrary number of ticks.

Parameters
[in]advance_several_timestepsNumber of the timesteps added to the clock
Exceptions
OverflowErrorif the number of the added timesteps exceeds the maximum value.

Definition at line 264 of file clock.h.

264  {
265  if (counter_ >= std::numeric_limits<Representation>::max() -
266  advance_several_timesteps) {
267  throw std::overflow_error("Too many timesteps, clock overflow imminent");
268  }
269  counter_ += advance_several_timesteps;
270  return *this;
271  }
Representation counter_
Clock tick.
Definition: clock.h:311

◆ operator<() [1/2]

bool smash::Clock::operator< ( const Clock rhs) const
inline

Compares the times between two clocks.

Parameters
[in]rhsThe other clock.

Definition at line 277 of file clock.h.

277  {
279  (rhs.reset_time_ + rhs.timestep_duration_ * rhs.counter_);
280  }
Representation counter_
Clock tick.
Definition: clock.h:311
Representation timestep_duration_
The time step size in $10^{-3}$ fm.
Definition: clock.h:313
Representation reset_time_
The time of last reset (when counter_ was set to 0).
Definition: clock.h:315

◆ operator<() [2/2]

bool smash::Clock::operator< ( double  time) const
inline

Compares the time of the clock against a fixed time.

Parameters
[in]timeThe other time.

Definition at line 286 of file clock.h.

286 { return current_time() < time; }
double current_time() const
Definition: clock.h:110
Here is the call graph for this function:

◆ operator>()

bool smash::Clock::operator> ( double  time) const
inline

Compares the time of the clock against a fixed time.

Parameters
[in]timeThe other time.

Definition at line 292 of file clock.h.

292 { return current_time() > time; }
double current_time() const
Definition: clock.h:110
Here is the call graph for this function:

◆ convert() [1/2]

static Representation smash::Clock::convert ( double  x)
inlinestaticprivate

Convert a double x into the internal int representation.

Definition at line 301 of file clock.h.

301  {
302  return std::round(x * from_double);
303  }
static constexpr double from_double
A multiplier transfering the real time to the internal integer.
Definition: clock.h:298
Here is the caller graph for this function:

◆ convert() [2/2]

static double smash::Clock::convert ( Representation  x)
inlinestaticprivate

Convert an internal int value x into the double representation.

Definition at line 305 of file clock.h.

305 { return x * to_double; }
static constexpr double to_double
A multiplier transfering the internal integer to the real time.
Definition: clock.h:296

Member Data Documentation

◆ resolution

constexpr double smash::Clock::resolution = 0.000001
staticprivate

Defines the resolution of the clock (i.e.

the smallest representable time difference).

The value 0.000001 is very well suited because

  • It should be \(10^{-n},\;n\in\mathbb{N}\). That's because we want to use it to convert user input/output and that's in decimal representation.
  • The floating-point representation of the constant should have a small error. 0.000001 has the smallest error (i.e. 0.022 ulp) in the range \(1\leq n \leq 10\). The small error helps to convert the internal integer representation as precise as possible to floating-point.

Definition at line 88 of file clock.h.

◆ to_double

constexpr double smash::Clock::to_double = resolution
staticprivate

A multiplier transfering the internal integer to the real time.

Definition at line 296 of file clock.h.

◆ from_double

constexpr double smash::Clock::from_double = 1. / resolution
staticprivate

A multiplier transfering the real time to the internal integer.

Definition at line 298 of file clock.h.

◆ counter_

Representation smash::Clock::counter_ = 0
private

Clock tick.

This is purely internal and will be reset when the timestep size is changed.

Definition at line 311 of file clock.h.

◆ timestep_duration_

Representation smash::Clock::timestep_duration_ = 0u
private

The time step size \(\Delta t\) in $10^{-3}$ fm.

Definition at line 313 of file clock.h.

◆ reset_time_

Representation smash::Clock::reset_time_ = 0
private

The time of last reset (when counter_ was set to 0).

Definition at line 315 of file clock.h.


The documentation for this class was generated from the following file: