Stopping criteria#
A run ends when the spheres reach the target density, or when the first of the
stopping criteria passed as stop= fires. The result reports what happened in
status ("target" or the name of the criterion), the criterion object in
stopped_by, and whether the run did what was asked in success.
import spheropack as sp
p = sp.pack(n=1000, density=0.6) # target density
q = sp.pack(n=1000, density="max") # until jammed
r = sp.pack(n=1000, density="max", stop=[sp.stop.Jammed(pressure=1e10), sp.stop.Timeout(120)])
Targets#
density sets the goal of the run:
|
the run succeeds when |
default |
|---|---|---|
|
the spheres have the |
|
a number |
the volume (area) fraction reaches it |
|
|
an arrest criterion fires |
|
With a target, the default Pressure(1e6) stops a run whose target lies beyond the
jamming density instead of letting it run forever. Without success pack warns
(PackingWarning), or raises PackingError
with strict=True; the partial packing is available in both cases.
Arrest criteria#
Arrest criteria detect that the spheres can no longer grow.
Jammed
: Compresses quasi-statically to a jammed packing. The spheres grow at the requested
growth rate until the median per-sphere reduced pressure reaches start_pressure
(\(10^3\)). Then the radii alternate between relaxation at fixed size and short
growth steps. Near jamming the reduced pressure diverges as
\(Z \approx D/(1 - \phi/\phi_J)\), so the remaining relative growth is about \(1/Z\); each
step closes the fraction step of it. The run stops when the median pressure after
relaxation exceeds pressure (\(10^9\)). The median ignores rattlers and the few
spheres that may collide at very high rates.
: Slower protocols (more relaxation windows, smaller steps) come closer to an
isostatic contact network at a higher cost. For 1000 equal spheres at growth rate
0.02, the contacts between force-bearing spheres reach about 94% of the isostatic
number with relax_windows=2, step=0.5, 97% with the defaults
(relax_windows=4, step=0.2, 1.75 times the run time) and 98% with
relax_windows=4, step=0.1 (3 times). The density changes only in the fourth
decimal. Pressures above about \(10^{11}\) bring the gaps between touching spheres
close to floating-point round-off.
Pressure
: Stops when the mean reduced pressure over a measurement window exceeds value,
while the spheres keep growing at the requested rate. Cheaper than Jammed, but the
final approach is not quasi-static, so the contact network is not yet fully formed.
Suitable when only the density and the overall structure matter.
Stall
: Stops when the radii grew by less than the relative amount tol during the last
window collisions per sphere. It measures progress directly and needs no pressure.
Limit criteria#
Limit criteria bound the cost of a run. When one fires before the target or an arrest, the run counts as failed.
Collisions
: A budget of total collisions or per_particle collisions per sphere, exact.
Timeout
: Wall-clock seconds. Unlike all other criteria it makes the result depend on the
speed of the machine.
Pressing Ctrl-C in Python stops a run within a fraction of a second and raises
KeyboardInterrupt.
How pressure is measured#
The reduced pressure \(Z = PV/(Nk_BT)\) is computed from the collision virial over windows of 10 collisions per sphere,
with \(J_{ij}\) the impulse of a collision and the kinetic energy integrated over the
window. Each sphere receives half of the virial of its collisions, which gives a
per-sphere pressure (Packing.sphere_pressure); its mean is \(Z\) and its median is
Packing.median_pressure. In a jammed packing the per-sphere pressure is the
time-averaged contact force on the sphere, so spheres with a value near 1 carry no
force: they are rattlers (spheropack.analysis.rattlers()). Packing.history
holds the pressures, temperature and radius scale of every window, which shows the
course of the compression.
Combining criteria#
Criteria of different types combine: the first that fires ends the run. Of several
criteria of the same type the strictest applies (the lowest pressure, the smallest
budget, the shortest timeout). At most one Jammed and one Stall may be given.
Reproducibility#
With the same seed, the same version and the same platform a run is reproducible
exactly, except when it is ended by Timeout or Ctrl-C. Between platforms results
agree statistically but not sphere by sphere: event-driven dynamics is chaotic and
amplifies round-off differences of the mathematical library.