C++ API#
The core is header-only (include/spheropack/) and can be used without Python.
-
namespace spheropack#
Typedefs
Enums
-
enum class Status#
Reason why LSPacking::run() returned.
Values:
-
enumerator running#
run() has not finished (initial value)
-
enumerator target#
radii reached a_i * target_scale
-
enumerator pressure#
reduced pressure exceeded max_pressure (jammed or crystallised)
-
enumerator jammed#
jamming protocol reached jammed_pressure (median over spheres)
-
enumerator stall#
radii grew by less than stall_tol over stall_window collisions per particle
-
enumerator collisions#
max_collisions reached
-
enumerator time_limit#
max_time (simulation time) reached
-
enumerator timeout#
wall-clock timeout reached
-
enumerator interrupted#
the interrupt callback returned true (e.g. Ctrl-C)
-
enumerator no_events#
no future events (all particles at rest)
-
enumerator box_limit#
the largest sphere touches its own periodic image
-
enumerator running#
-
enum class CollisionRule#
Collision rule for growing spheres.
Here \(u_n\) is the normal relative velocity before contact (negative when approaching) and the growth speed is the rate at which the contact distance grows.
Values:
-
enumerator legacy#
Normal relative velocity after contact: max(-u_n, growth speed + margin).
Elastic when the approach is faster than the growth, perfectly inelastic in the frame of the growing surfaces otherwise (the legacy rule).
-
enumerator elastic_growing#
Elastic in the frame of the growing surfaces: u_n’ = 2 * growth speed - u_n (Donev, Torquato and Stillinger).
Heats the system; the thermostat removes it.
-
enumerator legacy#
Functions
-
inline double ball_measure(int m, double r) noexcept#
Measure of a ball of radius
rinmdimensions (m = 1, 2, 3).- Returns:
\(2r\), \(\pi r^2\) or \(\tfrac{4}{3}\pi r^3\)
-
template<int D>
constexpr double ball_volume(double r) noexcept# Volume (D=3) or area (D=2) of a ball of radius
r.- Template Parameters:
D – dimension (2 or 3)
- Parameters:
r – radius
- Returns:
\(\pi r^2\) for D=2, \(\tfrac{4}{3}\pi r^3\) for D=3
-
inline const char *to_string(Status s) noexcept#
Name of a status as used in the Python interface.
- Parameters:
s – status value
- Returns:
the enumerator name as a string, e.g.
"time_limit";"unknown"for invalid values
-
template<int D, class F>
void for_each_pair(const std::vector<Vec<D>> &x, const Box<D> &box, double cutoff, F &&f)# Calls
f(i, j, r)once for every pairi < jand every periodic image ofjwith|r| < cutoff, wherer = x_j + shift * L - x_i.Positions must lie inside the box. On periodic axes the cutoff may exceed half the box length but not the box length itself; every image within the cutoff is then reported separately. Images of a particle with itself are not reported.
- Template Parameters:
D – dimension (2 or 3)
- Parameters:
x – positions, inside the box
box – container
cutoff – largest distance of interest
f – callable
f(std::uint32_t i, std::uint32_t j, const Vec<D>& r)
-
inline double first_contact(double A, double B, double C) noexcept#
Earliest \(\tau \ge 0\) at which the quadratic \(f(\tau) = A\tau^2 + 2B\tau + C\) reaches zero while decreasing.
Here \(f\) is the squared distance of a pair minus its squared contact distance, so the root is the first contact. \(C \le 0\) means contact (or round-off overlap) now. The roots use the cancellation-free form \(q = -(B + \mathrm{sign}(B)\sqrt{B^2 - AC})\), with roots \(q/A\) and \(C/q\). With growing particles \(A < 0\) is legal.
- Parameters:
A – coefficient of \(\tau^2\)
B – half the coefficient of \(\tau\) ( \(B<0\): pair closing now)
C – value at \(\tau = 0\)
- Returns:
contact time, 0 if already in contact, or
neverif the pair does not meet
-
inline double first_contact_linear(double gap, double rate) noexcept#
Earliest \(\tau \ge 0\) at which \(\mathrm{gap} + \mathrm{rate}\,\tau\) reaches zero (flat wall, gap linear in time).
- Parameters:
gap – current distance to the wall
rate – rate of change of the gap
- Returns:
contact time (0 if the gap is already non-positive and closing), or
neverif the gap does not decrease
-
inline double reflection_time(double r2, double b, double u2, double du, const PairPotential &pot) noexcept#
Time \(\tau \ge 0\) along a straight relative path at which a pair reflects.
The pair separation is \(\mathbf r(\tau) = \mathbf r_0 + \mathbf u\,\tau\). Along the inward leg (up to the closest approach) the potential rises inside \(r_m\), along the outward leg it rises between \(r_m\) and \(r_c\). The reflection happens where the accumulated rise equals
du.- Parameters:
r2 – \(|\mathbf r_0|^2\)
b – \(\mathbf r_0 \cdot \mathbf u\)
u2 – \(|\mathbf u|^2\)
du – drawn energy, \(-kT \ln u\)
pot – the pair potential
- Returns:
\(\tau\), or
neverif the pair does not reflect before it separates beyond the cutoff
-
inline bool may_reflect(double r2, double b, double u2, const PairPotential &pot) noexcept#
Whether a straight relative path has any uphill part for
pot(a cheap necessary condition for reflection_time() to be finite).- Parameters:
r2 – \(|\mathbf r_0|^2\)
b – \(\mathbf r_0 \cdot \mathbf u\)
u2 – \(|\mathbf u|^2\)
pot – the pair potential
-
constexpr std::uint64_t splitmix64(std::uint64_t &state) noexcept#
One step of SplitMix64.
- Parameters:
state – generator state, advanced by the golden-ratio increment
- Returns:
a well-mixed 64-bit value
-
constexpr std::uint64_t mix64(std::uint64_t key) noexcept#
Stateless 64-bit mix of a key, used for counter-based random numbers.
- Parameters:
key – input value (for example a counter or an index)
- Returns:
one SplitMix64 output for the state
key
-
constexpr double to_unit_interval(std::uint64_t bits) noexcept#
Uniform double in \([0, 1)\) from the 53 high bits of a 64-bit integer.
- Parameters:
bits – raw 64-bit random value
- Returns:
(bits >> 11) * 2^-53, exactly representable
Variables
-
constexpr double never = std::numeric_limits<double>::infinity()#
Event time meaning “no contact” (positive infinity).
-
template<int D>
struct BallWall# - #include <box.hpp>
Curved wall: the region \(\sum_{k \in A} (x_k - c_k)^2 \le R^2\) over a set of axes \(A\).
Over two axes of a 3D box it is a cylinder, over all axes a spherical container (3D) or a disk (2D).
- Template Parameters:
D – dimension (2 or 3)
-
template<int D>
struct Box# - #include <box.hpp>
Axis-aligned box \([0, L_0) \times \dots \times [0, L_{D-1})\) with a boundary type per axis, and an optional curved wall inside it.
Along a periodic axis the box repeats. Along a non-periodic axis that the ball does not constrain, flat walls bound the box at 0 and \(L_k\). Along the axes of the ball, the ball wall bounds the spheres; it must lie inside the box.
- Template Parameters:
D – dimension (2 or 3)
Public Functions
-
inline bool flat_walls(int k) const noexcept#
- Returns:
true if axis
kis bounded by flat walls at 0 and \(L_k\)
-
inline void validate() const#
Check the geometry.
- Throws:
std::invalid_argument – if an edge length is not positive (or NaN), or if the ball wall is periodic along one of its axes or does not fit in the box
-
inline double volume() const noexcept#
- Returns:
volume (D=3) or area (D=2) available to the spheres: the box, or the ball over its axes times the box edges along the other axes
-
template<int D>
class CellGrid# - #include <cell_grid.hpp>
Cell list with O(1) insertion, removal and move of particles.
Particles are stored in one doubly linked list per cell. Particle indices and cell indices are 32-bit;
nonemarks the end of a list and a particle in no cell.- Template Parameters:
D – dimension (2 or 3)
Public Functions
-
inline void build(const Box<D> &box, double min_width, std::size_t max_cells, int stencil = 1)#
Choose the cell layout for a box and empty all cells.
Cells are at least
min_widthwide along every axis; the total number of cells is capped nearmax_cellsby widening cells (never by narrowing them). Callclear_particlesafterwards, before inserting.- Parameters:
box – container (copied; its periodicity is used by
for_each_neighbor)min_width – lower bound on the cell width along every axis, typically the largest interaction distance; a value <= 0 requests the finest grid allowed
max_cells – approximate upper bound on the total number of cells
stencil – stencil radius m in cells: neighbours are searched in offsets -m..m per axis, so cells may be as narrow as the interaction distance divided by m
-
inline void clear_particles(std::size_t n_particles)#
Remove all particles and size the per-particle arrays.
- Parameters:
n_particles – number of particles that will be inserted
-
inline double min_width() const noexcept#
- Returns:
smallest cell width over all axes
-
inline int n(int k) const noexcept#
- Returns:
number of cells along axis
k
-
inline int stencil() const noexcept#
- Returns:
the stencil radius m
-
inline double width(int k) const noexcept#
- Returns:
cell width along axis
k
-
inline std::size_t num_cells() const noexcept#
- Returns:
total number of cells
-
inline Index coords_of(const Vec<D> &x) const noexcept#
Cell coordinates containing a position.
- Parameters:
x – position; coordinates outside the box are clamped to the edge cells
- Returns:
integer cell coordinates
-
inline std::int32_t flat(const Index &c) const noexcept#
Flatten cell coordinates (axis 0 varies fastest).
- Parameters:
c – cell coordinates, within range
- Returns:
cell index
-
inline Index coords(std::int32_t f) const noexcept#
Inverse of
flat.- Parameters:
f – cell index
- Returns:
cell coordinates
-
inline std::int32_t cell_of(std::uint32_t i) const noexcept#
- Parameters:
i – particle index
- Returns:
cell holding particle
i, ornoneif it is not inserted
-
inline void insert(std::uint32_t i, std::int32_t cell) noexcept#
Put particle
iat the head of the list ofcell.- Parameters:
i – particle index; must not currently be in a cell
cell – destination cell index
-
inline void remove(std::uint32_t i) noexcept#
Take particle
iout of its cell; afterwardscell_of(i) == none.- Parameters:
i – particle index; must currently be in a cell
-
inline void move(std::uint32_t i, std::int32_t cell) noexcept#
Move particle
ito another cell (removefollowed byinsert).- Parameters:
i – particle index; must currently be in a cell
cell – destination cell index
-
template<class F>
inline void for_each_neighbor_layer(std::int32_t cell, int axis, int dir, F &&f) const# Like for_each_neighbor(), but only the layer of the stencil at offset
dir(+1 or -1) alongaxis: the cells that become adjacent when a particle moves intocellacross that face (offset m alongaxis).Callers fall back to a full scan when there are fewer than 2m + 1 cells along
axis.- Parameters:
cell – centre cell of the stencil
axis – axis of the move
dir – direction of the move along
axis(+1 or -1)f – callable
f(std::uint32_t j, const std::array<int, D>& shift)
-
template<class F>
inline void for_each_neighbor(std::int32_t cell, F &&f) const# Visit every particle in the \((2m+1)^D\) stencil of cells around
cell.Calls
f(j, shift)for each particlejfound, where the image ofjto use is \(x_j + \mathrm{shift}\cdot L\) (componentwise integers). Every stencil offset is a distinct periodic image. On periodic axes with fewer than 2m + 1 cells the stencil visits the same cell with different shifts, which is what makes small periodic boxes correct. On non-periodic axes stencil cells outside the grid are skipped. Includes the particle itself with shift 0.- Parameters:
cell – centre cell of the stencil
f – callable
f(std::uint32_t j, const std::array<int, D>& shift); the grid must not be modified from insidef
Public Static Attributes
-
static constexpr std::int32_t none = -1#
Sentinel for “no particle” / “no cell”.
-
template<int D>
class EventChainMC# - #include <rejection_free.hpp>
Straight event-chain variant of the rejection-free method (Peters and de With 2012, section “straight event-chain collision”; Bernard, Krauth and Wilson 2009 for hard spheres).
One particle moves at a time, along a coordinate axis. For every pair with the moving particle the uphill part of the pair potential along the path is accumulated; at a reflection the moving particle stops and the partner continues with the same displacement direction (a lift). A chain ends after a total displacement
chain_length; the next chain starts at a random particle. In the irreversible mode (the default) the direction cycles through +x, +y, +z; this breaks detailed balance but satisfies global balance, so the canonical distribution is sampled. In the reversible mode each chain gets a random axis and sign.- Template Parameters:
D – dimension (2 or 3)
Public Functions
-
inline EventChainMC(const Box<D> &box, const std::vector<Vec<D>> &positions, PairPotential potential, double kT, std::uint64_t seed, bool irreversible = true)#
Set up particles at the given positions.
- Parameters:
box – periodic box (all axes periodic), edges at least twice the cutoff
positions – initial positions
potential – pair potential (prepared here)
kT – temperature in energy units
seed – random seed
irreversible – cycle the directions +x, +y, +z (true) or draw random axes and signs
-
inline const EventChainStats &run(double displacement, double chain_length, const std::function<bool()> &interrupted = {})#
Run chains until the total displacement reaches
displacement.- Parameters:
displacement – total displacement of all chains together
chain_length – displacement per chain
interrupted – polled regularly; returning true stops the run early
- Returns:
the accumulated statistics
-
inline double potential_energy() const#
- Returns:
total potential energy
-
inline const EventChainStats &stats() const noexcept#
- Returns:
the accumulated statistics
-
struct EventChainStats#
- #include <rejection_free.hpp>
Run statistics of an event-chain simulation.
Public Members
-
double displacement = 0.0#
total displacement of all chains
-
std::uint64_t n_lifts = 0#
number of lifts (the motion passed to another particle)
-
std::uint64_t n_chains = 0#
number of chains
-
double wall_time = 0.0#
wall-clock seconds spent in run()
-
bool interrupted = false#
the last run() was stopped by the interrupt callback
-
double displacement = 0.0#
-
class EventHeap#
- #include <event_queue.hpp>
Indexed binary min-heap with one key per particle.
Particle
ialways owns sloti; its key can be changed in O(log n). The top is the particle with the smallest key (the next event). Keys equal to infinity mean “no event”.Public Functions
-
inline void reset(std::uint32_t n)#
Resize to
nparticles and set every key to infinity.- Parameters:
n – number of particles
-
inline void assign(const std::vector<double> &keys)#
Set all keys at once (O(n) heapify).
- Parameters:
keys – one key per particle; must have the size given to
reset
-
inline void update(std::uint32_t i, double t)#
Change the key of particle
iand restore the heap order, O(log n).- Parameters:
i – particle index
t – new key (event time)
-
inline std::uint32_t top() const noexcept#
- Returns:
particle with the smallest key; undefined if
empty()
-
inline double top_key() const noexcept#
- Returns:
smallest key; undefined if
empty()
-
inline double key(std::uint32_t i) const noexcept#
- Parameters:
i – particle index
- Returns:
current key of particle
i
-
inline bool empty() const noexcept#
- Returns:
true if the heap holds no particles
-
inline void reset(std::uint32_t n)#
-
struct HistoryRecord#
- #include <ls_packing.hpp>
One record per pressure window.
Public Members
-
double time#
simulation time at the end of the window
-
double scale#
s at the end of the window
-
double reduced_pressure#
mean over spheres
-
double median_pressure#
median over spheres
-
double kT#
time-averaged temperature over the window
-
std::uint64_t n_collisions#
collisions since the start of the run
-
int phase#
0 growing, 1 relaxing (fixed radii), 2 growth step
-
double time#
-
template<int D>
class LSPacking# - #include <ls_packing.hpp>
Event-driven Lubachevsky-Stillinger packing of polydisperse growing hard spheres.
The spheres move ballistically with unit mass at temperature kT = 1 and collide elastically while their radii \(a_i s(t)\) grow at a constant rate. The temperature is restored to 1 at every synchronisation while the spheres grow. Pressure is measured in windows of
sync_intervalcollisions per particle as the reduced pressure \(Z = PV/(NkT) = 1 + \sum \mathbf r\cdot\mathbf J / (2 \int KE\, dt)\), from the virial of the collision impulses \(\mathbf J\) and the time integral of the kinetic energy. The container may have periodic axes, flat walls and a spherical wall (see Box).- Template Parameters:
D – dimension (2 or 3)
Public Functions
-
inline LSPacking(const Box<D> &box, std::vector<double> radii, const PackingOptions &opt)#
Creates a packing with random positions at zero radius and random velocities.
The growth rate is set so that the mean diameter grows at
opt.growth_ratethermal speeds. The generator is seeded withopt.seed.- Parameters:
box – container; validated here
radii – relative radii a_i; the radii at scale s are a_i * s
opt – run parameters
- Throws:
std::invalid_argument – if the box is invalid,
radiiis empty or has too many entries, a radius is not positive and finite,growth_rate < 0ortarget_scale <= 0
-
inline void randomize_positions()#
Places the particles uniformly at random (inside the ball wall, if any) and sets the scale to s = 0, so that the radii are zero.
-
inline void randomize_velocities()#
Draws Maxwellian velocities with zero total momentum, scaled to kT = 1 exactly.
-
inline void set_positions(const std::vector<Vec<D>> &x, double scale)#
Starts from given positions at scale s (radii a_i * s); they must not overlap.
Resets the periodic image counters. The positions are not checked for overlaps.
- Parameters:
x – positions, inside the box
scale – initial scale s, at least 0
- Throws:
std::invalid_argument – if the number of positions differs from the number of particles or
scale < 0
-
inline void set_velocities(const std::vector<Vec<D>> &v)#
Sets the velocities, replacing the random ones.
The temperature is rescaled to kT = 1 at the first synchronisation of a growing run.
- Parameters:
v – velocities, one per particle
- Throws:
std::invalid_argument – if the number of velocities differs from the number of particles
-
inline const PackingStats &run(const std::function<bool()> &interrupted = {})#
Runs until a stopping criterion is met.
The criteria are the target scale, the pressure limits, the jamming protocol, stall detection, the collision, simulation time and wall-clock limits, the interrupt callback, the absence of events and the box limit; see Status. On return the radii are shrunk uniformly if round-off left overlaps (PackingStats::shrink_factor).
- Parameters:
interrupted – optional callback polled regularly; the run stops with Status::interrupted when it returns true
- Throws:
std::invalid_argument – if the growth rate is zero and the initial scale is zero
std::runtime_error – if the box is smaller than the largest particle diameter
- Returns:
the statistics of the run, valid until the next call of run()
-
inline std::size_t size() const noexcept#
- Returns:
the number of particles
-
inline const std::vector<HistoryRecord> &history() const noexcept#
- Returns:
one record per pressure window of the last run
-
inline std::vector<double> sphere_pressure() const#
Per-sphere reduced pressure of the last completed window: 1 + N w_i / (2 int KE dt).
Without walls its mean over spheres is the reduced pressure; wall contacts add to the spheres that touch a wall. Close to 1 for rattlers.
- Returns:
one value per sphere; empty before the first window has closed
-
inline void set_full_rescan(bool on) noexcept#
Testing aid: re-predict with a full neighbour scan after every cell crossing instead of scanning only the new cell layer.
The trajectory must be the same.
-
inline const PackingStats &stats() const noexcept#
- Returns:
the statistics of the last run (status Status::running before the first run)
-
inline std::vector<Vec<D>> positions() const#
Positions wrapped into the box; valid after run().
- Returns:
one position per particle
-
inline std::vector<double> radii() const#
Final radii a_i * stats().scale; valid after run().
- Returns:
one radius per particle
-
struct PackingOptions#
- #include <ls_packing.hpp>
Parameters of a run.
Every stopping criterion is off when set to its default.
Lengths are in the units of the box;
neveris positive infinity (see predict.hpp).Jamming protocol
Off when jammed_pressure is infinite: grow until the median reduced pressure reaches jam_start_pressure, then alternate relaxation at fixed radii (jam_relax_windows pressure windows) with growth steps of relative size jam_step / Z_median, until Z_median after relaxation reaches jammed_pressure.
-
double jam_start_pressure = 1e3#
median reduced pressure at which the protocol starts
-
int jam_relax_windows = 4#
pressure windows per relaxation at fixed radii
-
double jam_step = 0.2#
fraction of the remaining relative growth closed per step
Public Members
-
double target_scale = 1.0#
Final radii are a_i * target_scale; infinity: no target.
-
double growth_rate = 0.02#
Growth speed of the mean diameter in units of the thermal speed sqrt(kT/m).
-
double max_pressure = never#
Reduced pressure PV/(NkT) at which growth stops (mean over a measurement window).
-
double stall_tol = 0.0#
0: off. Stop when s grew by less than this (relative)
-
double stall_window = 100.0#
over this many collisions per particle
-
std::uint64_t max_collisions = 0#
total collisions at which to stop; 0: unlimited
-
CollisionRule rule = CollisionRule::legacy#
collision rule
-
double sync_interval = 10.0#
collisions per particle between synchronisations
-
double separation_margin = 1e-9#
After a collision the pair separates at least this much faster than the contact distance grows (thermal speed units); keeps the gap opening in floating point.
-
std::uint64_t seed = 0#
seed of the random number generator
-
double jam_start_pressure = 1e3#
-
struct PackingStats#
- #include <ls_packing.hpp>
Summary of a finished run, returned by LSPacking::run().
Public Members
-
double scale = 0.0#
final s: radii are a_i * scale
-
double density = 0.0#
volume (area) fraction
-
double reduced_pressure = 0.0#
last measured PV/(NkT) (mean over spheres); 0 if never measured
-
double median_pressure = 0.0#
median over spheres of the per-sphere reduced pressure
-
std::uint64_t n_collisions = 0#
number of collisions that changed velocities
-
std::uint64_t n_events = 0#
number of processed events, including cell crossings
-
double sim_time = 0.0#
simulation time
-
double wall_time = 0.0#
wall-clock seconds
-
double min_gap_ratio = 0.0#
min over contacts of distance / contact distance - 1, before shrink
-
double shrink_factor = 1.0#
uniform radius factor applied to remove round-off overlaps
-
double max_contact_error = 0.0#
max over collisions of |distance / contact distance - 1|
-
double scale = 0.0#
-
struct PairPotential#
- #include <rejection_free.hpp>
Isotropic pair potential with at most one minimum, zero at and beyond the cutoff.
U decreases on \((0, r_m]\) and increases on \([r_m, r_c]\) to \(U(r_c) = 0\). Purely repulsive potentials have \(r_m = r_c\). Hard spheres have an infinite step at \(\sigma\).
Public Types
-
enum class Kind#
Potential families.
Values:
-
enumerator soft#
\(U = \tfrac{\epsilon}{\alpha}(1 - r/\sigma)^\alpha\) for \(r < \sigma\) (DPD: \(\alpha = 2\))
-
enumerator lennard_jones#
\(4\epsilon[(\sigma/r)^{12} - (\sigma/r)^6] - U(r_c)\) for \(r < r_c\)
-
enumerator hard#
infinite for \(r < \sigma\), zero otherwise
-
enumerator soft#
Public Functions
-
inline void prepare()#
Check parameters and derive the shift and the minimum.
-
inline double r_min() const noexcept#
- Returns:
radius of the minimum \(r_m\)
-
inline double u_min() const noexcept#
- Returns:
\(U(r_m)\), the lowest value (0 for purely repulsive potentials)
-
inline double value(double r) const noexcept#
- Returns:
\(U(r)\)
-
inline double inner_radius(double u) const noexcept#
Radius on the repulsive branch \(r \le r_m\) where \(U(r) = u\), for \(u \ge U(r_m)\).
-
inline double outer_radius(double u) const noexcept#
Radius on the attractive branch \(r_m \le r \le r_c\) where \(U(r) = u\), for \(U(r_m) \le u \le 0\).
-
enum class Kind#
-
template<int D>
class RejectionFreeMC# - #include <rejection_free.hpp>
Rejection-free event-driven Monte Carlo in a periodic box.
- Template Parameters:
D – dimension (2 or 3)
Public Functions
-
inline RejectionFreeMC(const Box<D> &box, const std::vector<Vec<D>> &positions, PairPotential potential, double kT, std::uint64_t seed)#
Set up particles at the given positions with Gaussian move velocities.
- Parameters:
box – periodic box (all axes periodic)
positions – initial positions inside the box
potential – pair potential (prepared here)
kT – temperature in energy units
seed – random seed (velocities and reflection energies)
-
inline void set_velocities(const std::vector<Vec<D>> &v)#
Replace the move velocities (for example to redraw them).
-
inline void redraw_velocities()#
Redraw all move velocities from a standard normal distribution.
-
inline const RejectionFreeStats &run(double duration, const std::function<bool()> &interrupted = {})#
Advance the simulation by
duration(time = contour length along the moves).- Parameters:
duration – simulation time to advance
interrupted – polled regularly; returning true stops the run early
- Returns:
the accumulated statistics
-
inline double time() const noexcept#
- Returns:
simulation time since the start
-
inline std::vector<Vec<D>> positions()#
- Returns:
positions at the current time, wrapped into the box
-
inline double potential_energy()#
- Returns:
total potential energy at the current time
-
inline void set_full_rescan(bool on) noexcept#
Testing aid: re-predict with a full neighbour scan after every cell crossing instead of scanning only the new cell layer.
The trajectory must be the same.
-
inline const RejectionFreeStats &stats() const noexcept#
- Returns:
the accumulated run statistics
-
inline std::size_t size() const noexcept#
- Returns:
the number of particles
-
struct RejectionFreeStats#
- #include <rejection_free.hpp>
Run statistics of a rejection-free simulation.
Public Members
-
double time = 0.0#
simulation time (“contour length” of the moves)
-
std::uint64_t n_reflections = 0#
number of pair reflections
-
std::uint64_t n_events = 0#
processed events (reflections, cell crossings, stale predictions)
-
double wall_time = 0.0#
wall-clock seconds spent in run()
-
bool interrupted = false#
the last run() was stopped by the interrupt callback
-
double time = 0.0#
-
class Rng#
- #include <rng.hpp>
xoshiro256++ pseudo-random generator (Blackman and Vigna, 2019).
Satisfies the interface of a C++ uniform random bit generator (
result_type,min,max,operator()), and provides portable uniform, exponential and normal variates. The state is 256 bits, seeded through SplitMix64.Public Types
-
using result_type = std::uint64_t#
Type of the raw integer output.
Public Functions
-
inline explicit Rng(std::uint64_t seed = 0) noexcept#
Construct and seed the generator.
- Parameters:
seed – any 64-bit seed; the four state words are drawn from SplitMix64
-
inline void reseed(std::uint64_t seed) noexcept#
Reset the stream to the one defined by
seedand drop any cached normal variate.- Parameters:
seed – any 64-bit seed
-
inline result_type operator()() noexcept#
Next raw 64-bit value of the xoshiro256++ stream.
- Returns:
uniformly distributed 64-bit integer
-
inline double uniform() noexcept#
- Returns:
uniform variate in \([0, 1)\)
-
inline double uniform_open0() noexcept#
- Returns:
uniform variate in \((0, 1]\), safe as argument of
log
-
inline double exponential() noexcept#
- Returns:
standard exponential variate (rate 1), \(-\ln u\) with \(u \in (0,1]\)
-
inline double normal() noexcept#
Standard normal variate by the Box-Muller transform.
Each transform yields two independent values; the second is cached and returned by the next call.
- Returns:
normal variate with zero mean and unit variance
-
inline std::array<std::uint64_t, 4> state() const noexcept#
- Returns:
copy of the four 64-bit state words (the cached normal is not included)
Public Static Functions
-
static inline constexpr result_type min() noexcept#
Smallest raw output (0).
-
static inline constexpr result_type max() noexcept#
Largest raw output (all bits set).
-
using result_type = std::uint64_t#
-
enum class Status#