Packmol-grade molecular packing in pure Rust, with Python bindings. Part of the molrs toolkit.
CLI
cargo install molcrafts-molpack --features cliRust library
cargo add molcrafts-molpackPython
pip install molcrafts-molpackThe molpack binary accepts Packmol-style .inp scripts. Use the official
Packmol user guide as the
script-language reference; molpack documents only invocation behavior and
extensions here. Relative file paths in the script are resolved against the
script's own directory (file-arg mode) or the current directory (stdin mode).
# File argument (paths resolved relative to the .inp file's directory)
molpack mixture.inp
# Stdin — compatible with Packmol usage
molpack < mixture.inp
cat mixture.inp | molpackmolpack script additions
| Addition | Description |
|---|---|
avoid_overlap <no|false|0> |
Disable the default fixed-solute initial-placement guard. Leave it on unless you need to reproduce a less guarded initialization. |
filetype <format> |
Any format in Formats (sdf, mol2, gro, cif, lammps_data, lammps_dump, …), named or by extension. |
Unknown top-level keywords are rejected instead of ignored. Files are read and
written through the molrs reader and writer of their format
(molpack::script::StructureFormat); the output format is inferred from the
output file name.
Rust
use std::sync::Arc;
use molpack::{GencanPack, PackEngine, RegionRestraint, Target};
use molrs::core::Cuboid;
use ndarray::array;
let positions = [[0.0, 0.0, 0.0], [0.96, 0.0, 0.0], [-0.24, 0.93, 0.0]];
let radii = [1.52, 1.20, 1.20];
let target = Target::from_coords(&positions, &radii, 100)
.with_name("water")
.with_restraint(RegionRestraint(Arc::new(Cuboid::new(array![0.0, 0.0, 0.0], array![40.0, 40.0, 40.0]))));
// You pick the algorithm by picking the engine: `GencanPack` for rigid-body
// packing, `CbmcGrow` for chain growth. Both share the `PackEngine` builders
// and the single terminal verb `run`, which consumes the engine — one engine,
// one run. Every tuning knob has a Packmol-matching default, so
// `GencanPack::new().run(...)` is a complete call; `200` is the outer-loop
// budget.
//
// `run` returns a `State`: the packed, topology-complete `molrs::core::Frame`
// in `.frame`, plus `fdist`, `frest`, `converged`, `degraded`.
let result = GencanPack::new().run(&[target], 200)?;
let frame = result.frame;Python
import molrs
from molpack import GencanPack, Target
frame = molrs.io.read_pdb("water.pdb")
water = (
Target(frame, count=100)
.with_name("water")
.with_restraint(molrs.core.Cuboid([0, 0, 0], [40, 40, 40]))
)
result = GencanPack().run([water], max_loops=200)
frame = result.frameFive canonical workloads ship in examples/ (they need the io feature
to read the bundled structure files):
cargo run --release --example pack_mixture --features io # 1000 water + 400 urea in a cube
cargo run --release --example pack_bilayer --features io # membrane leaflets via per-atom plane restraints
cargo run --release --example pack_interface --features io # water + chloroform around a fixed molecule
cargo run --release --example pack_spherical --features io # concentric lipid/water shells (largest case)
cargo run --release --example pack_solvprotein --features io # fixed protein solvated in a sphere (avoid_overlap)The same workloads run through the CLI from their bundled .inp scripts,
e.g. cargo run --release --features cli --bin molpack -- examples/pack_mixture/mixture.inp.
Python equivalents are in python/examples/.
examples/pack_peo compares the chain-growth solver against the
rigid-body path on a PEO melt (needs --features io).
Behaviour is tested in #[cfg(test)] modules next to the code it belongs
to — molpack has no tests/ directory and no benchmark suite.
cargo test --lib --features cli # the gate: in-module unit tests
cargo test --doc --features cli # rustdoc examples
cd python && maturin develop --release && pytest # Python wheel- Guide —
docs/, built withzensical build. Chapters: install, getting started, concepts, examples, Packmol parity, architecture, and extending. - Rust API —
cargo doc --open, or docs.rs. The four long-form chapters (getting started, concepts, architecture, extending) are also embedded in the rustdoc asmolpack::getting_started,molpack::concepts,molpack::architecture, andmolpack::extending. - Python — binding docs live under
docs/python/, published as the Python section of the site.
See CONTRIBUTING.md. Bugs and feature requests via GitHub Issues.
BSD-3-Clause
- Martínez, L.; Andrade, R.; Birgin, E. G.; Martínez, J. M. PACKMOL: A package for building initial configurations for molecular dynamics simulations. J. Comput. Chem. 2009, 30 (13), 2157–2164. https://doi.org/10.1002/jcc.21224