Exporting data

An Aggregate lives in memory; five exporters (see the I/O API reference) write it to disk in formats suited to different downstream uses. All snippets below assume:

import pyFracAggregate as pfa

agg = pfa.generate(64, df=1.8, kf=1.9)
results = pfa.analyze(agg)

YAML snapshot

export_yaml bundles everything about one aggregate in a single human-readable file: particle data, the aggregate’s units and density, and — optionally — the generation parameters and analysis results you pass in:

pfa.export_yaml(
    agg, "aggregate.yaml",
    generation_params={"method": "pca", "n_particles": 64,
                       "df": 1.8, "kf": 1.9, "seed": 42},
    analysis_results=results,
)

The written file has three top-level keys — generation (only if generation_params is given), aggregate (n_particles, length_unit, mass_unit, density, positions, radii, masses), and analysis (only if analysis_results is given). Recording the seed you used (see Reproducibility) makes the snapshot traceable back to an identical aggregate.

VTK point cloud

export_vtk writes a lightweight VTK PolyData point cloud: one point per primary, with radius and mass as point attributes:

pfa.export_vtk(agg, "aggregate.vtk")

VTM MultiBlock

export_vtm writes each primary as an explicit sphere mesh, grouped in a pyvista MultiBlock. Heavier on disk than the point cloud, but ready to render with no extra filters:

pfa.export_vtm(agg, "aggregate.vtm")

Rendered image

save_screenshot renders an off-screen 3D screenshot of the sphere mesh and saves it as PNG. Sphere color, opacity, background, camera position, and window_size are configurable:

pfa.save_screenshot(agg, "render.png", color="dimgray", window_size=(512, 384))

Polydisperse clusters can be colored by monomer size instead of a solid color — color_by="radius" maps each monomer’s radius onto a colormap (cmap, default "viridis"); the color argument is ignored in that mode:

pfa.save_screenshot(agg, "render_radius.png", color_by="radius", cmap="plasma")

Rotation video

save_rotation_video animates a full 360° turn and writes an MP4 (n_frames frames at fps, camera at elevation degrees). Keep n_frames modest while prototyping — rendering time scales with it:

pfa.save_rotation_video(agg, "rotation.mp4", n_frames=72, fps=24)

MP4 writing goes through imageio’s ffmpeg backend. The imageio[ffmpeg] dependency installed with pyFracAggregate provides a bundled ffmpeg; if you replaced it with plain imageio, install ffmpeg yourself or re-add the extra (pip install "imageio[ffmpeg]").

Viewing VTK/VTM in ParaView

Both aggregate.vtk and aggregate.vtm open directly in ParaView. The .vtk point cloud needs one extra step to look like soot: select the source, apply the Glyph filter with glyph type Sphere, scale by the radius array (scale factor 2 with the default 0.5-radius sphere source), and set the number of theta/phi resolution to taste. The .vtm MultiBlock already contains explicit sphere meshes, so it displays as-is after loading — at the cost of a larger file.

Warning

Rendering and video on headless servers. save_screenshot and save_rotation_video need a working OpenGL context even though they render off-screen. On a machine without a GPU or display, pyvista/VTK may fall back to software EGL successfully — or crash with EGL/segfault errors, depending on the VTK build. The reliable fixes are a virtual display or software GL:

$ xvfb-run -a python make_renders.py

or set PYVISTA_OFF_SCREEN=true with an OSMesa-built VTK (libosmesa6-dev on Debian/Ubuntu, or vtk-osmesa from conda-forge). This is the same workaround this project’s CI needed; do not debug your physics first — check the GL backend first.