Output formats#

A Packing can be written in the formats of common visualisation and simulation tools. All writers are in spheropack.io and available as methods of the packing:

method

format

for

to_xyz(path)

extended XYZ (with cell, periodic flags and radii)

OVITO, ASE, VMD

to_lammps_dump(path)

LAMMPS text dump with a radius column

OVITO, LAMMPS read_dump

to_lammps_data(path, density=...)

LAMMPS data file, atom_style sphere

DEM in LAMMPS or LIGGGHTS

to_vtp(path)

VTK XML PolyData with radius and diameter

ParaView

spheropack.io.write_container_vtp(p, path)

outline of the container as VTK lines

ParaView

to_stl(path)

binary STL surface mesh of all spheres

CFD meshing, CAD, 3D printing

to_pov(path)

POV-Ray scene

ray-traced images

to_csv(path)

CSV x,y,z,r

spreadsheets, the legacy tools

save(path) / spheropack.load(path)

NumPy .npz, exact round trip

Python

2D packings are written with \(z = 0\). With periodic_images=True the writers add the images of spheres that cut periodic faces, which completes the spheres at the box boundary; this is the default for STL.

import spheropack as sp

p = sp.pack(n=2000, density="max", container=sp.Cylinder(8.0, 12.0), radii=0.5, seed=1)
p.to_xyz("packing.xyz")  # OVITO
p.to_vtp("packing.vtp")  # ParaView
sp.io.write_container_vtp(p, "tube.vtp")
p.to_stl("packing.stl")  # CFD meshing
p.save("packing.npz")  # exact round trip: sp.load("packing.npz")

The command line writes the same formats: spheropack pack ... --format xyz -o packing.xyz (also lammps, lammps-data, vtp, stl, pov, npz).

OVITO#

Open the .xyz (or the LAMMPS .dump) file. OVITO takes the simulation cell and the periodic flags from the file and the particle radii from the radius column, so the spheres appear with their true sizes. Per-sphere values written as species (for example small and large spheres of a mixture) become particle types for colouring. In OVITO’s Python module:

from ovito.io import import_file

pipeline = import_file("packing.xyz")

ParaView#

Open the .vtp file and apply a Glyph filter: glyph type Sphere, Scale Array diameter, scale factor 1, glyph mode All Points. The default sphere glyph has radius 0.5, so scaling by the diameter gives the true sizes. For very large packings the Point Gaussian representation with the Sphere shader preset, scaled by the radius array, renders faster than glyphs. Open the container outline written by write_container_vtp alongside. Further per-sphere arrays can be added with to_vtp(path, point_data={"contacts": analysis.contact_numbers(p)}); the per-sphere pressure is included automatically.

LAMMPS and LIGGGHTS#

to_lammps_data writes id type diameter density x y z for atom_style sphere; read it with read_data. The boundary conditions are not part of a data file: use boundary p p p for a periodic box, p p f for a slab, and add the walls of a tube or a spherical container in the input script (for example fix wall/gran with a zcylinder).

CFD meshing#

to_stl triangulates every sphere as an icosphere (320 triangles by default; subdivisions=3 gives 1280). For the pore space of a packed bed, use the STL file as the geometry in a mesher such as OpenFOAM’s snappyHexMesh. Touching spheres share single contact points, which meshers cannot resolve; the usual remedies are to shrink the spheres by a small factor before export (sp.Packing radii can be scaled, e.g. dataclasses.replace(p, radii=0.99 * p.radii)) or to bridge the contacts.