spack: a package for spherical packing analysis

class spack.Packing(rs, diameters, shear=0.0, L=1.0)[source]

A class representing a packing of spheres in a periodic box.

class Backbone(indices, adjacency)

Return self as a plain tuple. Used by copy and pickle.


Exclude the OrderedDict from pickling


Return a nicely formatted representation string


Alias for field number 1


Alias for field number 0

class Packing.Contacts(Nc, stable, floaters)

Alias for field number 0


Return self as a plain tuple. Used by copy and pickle.


Exclude the OrderedDict from pickling


Return a nicely formatted representation string


Alias for field number 2


Alias for field number 1


Dynamical matrix for array rs, size ds. Assumes epsilon is the same for all.

Parameters:masses (an array of length N of the masses of the particles.) –

Find the frequencies corresponding to the eigenvalues of the dynamical matrix.

This is just a short wrapper around DM().

class Packing.Neighbors(adjacency, diffs)

Return self as a plain tuple. Used by copy and pickle.


Exclude the OrderedDict from pickling


Return a nicely formatted representation string


Alias for field number 0


Alias for field number 1


Returns (backbone indices, neighbor matrix)

Packing.cages(M=10000, R=None, Rfactor=1.2, padding=0.1, Mfactor=0.1)[source]

Find all cages in the current “packing”.

The algorithm uses Monte Carlo: it finds M random points within a sphere of radius R from each particle, and sees if that particle could sit there without conflicting with other particles. Then (number of accepted points) / (number of test points) * (volume of sphere) is the volume of the cage.

The algorithm is adaptive: if not enough test points are accepted (n < M * Mfactor), it tries more test points. If any test points are within padding of the edge, R is (temporarily) expanded.

  • M (Number of points in the sphere to test) –
  • R (Size of sphere to test (will be expanded if necessary)) –
  • Rfactor (How much to increase R by when the cage doesn't fit) –
  • padding (How much larger the sphere should be than the cage (if it isn't, the sphere is) – expanded)
  • Mfactor (Mfactor * M is the minimum number of points to find per cage. If they aren't) – found, more points are tested.

  • points (a list of (A x 3) lists, A indeterminate (but larger than M * Mfactor), with each) – list corresponding to the points within one cage.
  • Vs (The approximate volumes of each cage.)


Returns (number of backbone contacts, stable number, number of floaters)

Packing.dist(other, tol=1e-08, maxt=1000000)[source]

Returns the distance between two packings, with the particles paired up in the most efficient way, and also with center-of-mass accounted for.

Packing.dist_tree(other, tol=1e-08)[source]

Find the distance between two packings.

Requires pyparm.


Find Fij on each particle, assuming a harmonic potential, U = 1/2 (1 - r/σ)^2

Returns a dxNxN matrix.


For a set of particles at xs,ys with diameters diameters, finds the distance vector matrix (d x N x N) and the adjacency matrix.

Assumes box size 1, returns (adjacency matrix, diffs)

Packing.paired_dists(other, match_com=True)[source]

Returns the distance between two packings, assuming particle 1 of packing 1 goes with particle 2 of packing 2.

Distance is calculated as :math:`d = sqrt{sum_i left(

ec r_i ominus_ ec{L} ec s_i

ight)^2`, where
ec r_i` are the particles from one packing,
ec s_i` are the particles from the other packing,
and :math:`ominus_
ec{L}` means “shortest distance given periodic
boundary conditions in a box of shape :math:`


other : Another Packing. match_com : Subtract off center-of-mass motion as well.

For match_com = True, this yields

:math:`d = sqrt{sum_i left(

ec{r}_{i} ominus_ ec{L} ec{s}_{i} -

ec{delta} ight)^2}`

Minimized over `

ec delta`. It does this by actually evaluating

:math:`d = sqrt{

rac{1}{N}sum_{leftlangle i,j ight angle


ec{r}_{ij} ominus_ ec{L} ec{s}_{ij} ight)^2}`,

which turns out to be equivalent.

Volume of the spheres in the box.

Packing.plot_contacts(ax=None, tol=0, reshape=True, **kw)[source]

Designed for use with plot_disks, this will plot a line between neighboring particles.

Packing.plot_disks(ax=None, color=None, alpha=0.4, reshape=True)[source]

Plot the packing as a set of disks.

Color can be None (uses the standard sets), ‘diameter’ (colors by diameter), or a list of colors.

‘reshape’ means set axis scaled, etc.

Packing.scene(pack, cmap=None, rot=0, camera_height=0.7, camera_dist=1.5, angle=None, lightstrength=1.1, orthographic=False, pad=None, floater_color=(0.6, 0.6, 0.6), bgcolor=(1, 1, 1), box_color=(0.5, 0.5, 0.5), group_indexes=None, clip=False)[source]

Render a 3D scene.

Requires vapory package, which requires the povray binary.

  • cmap (a colormap) –
  • box_color (Color to draw the box. 'None' => don't draw box.) –
  • floater_color (Color for floaters. 'None' => same color as non-floaters (use cmap).) –
  • group_indexes (a list of indexes for each "group" that should remain) – together on the same side of the box.
  • clip (clip the spheres at the edge of the box.) –


Return type:

vapory.Scene, which can be rendered using its .render() method.


Returns [idx of sigma1, idx of sigma2, ...]


Get a tess.Container instance of this.

Requires tess.