Packmol parity¶
molpack tracks the original Packmol's behavior (L. Martínez et al.,
J. Comput. Chem. 2009). Coordinates are not byte-identical with the
same seed, but functional equivalence is enforced on five canonical
workloads.
What is matched¶
Objective structure
- Geometric restraint penalties — equivalent of
comprest/gwalls. - Minimum-distance overlap penalty — equivalent of
computef/fparc.
Optimization workflow
- Initialization with constraint-only fitting (
initial/restmol/swaptype). avoid_overlap(on by default, faithful toinitial.f90): initial placements that land inside a fixed molecule are rejected. This matters for dense solvation around a large fixed solute — without it a sizeable fraction of solvent seeds inside the solute, roughly doubling the initial overlap and slowing convergence by about an order of magnitude.- Phased main optimization — per-type pre-compaction, then all-types.
movebadheuristic for stalled molecules.- Radius-scaling (
radscale) decay across each phase. - GENCAN / SPG / CG inner solver chain.
- Precision gate on
fdist(overlap) andfrest(restraint violation).
Restraint vocabulary
inside/outside box,cube,sphere,ellipsoid,cylinderover plane(above) /below plane- fixed molecule placement
All twelve box/cube/sphere/ellipsoid/cylinder/plane kinds lower through a single
restraint_from_spec table in script::build, so each is reachable from both
whole-molecule and atoms … end atoms blocks. The two Gaussian-surface kinds
(14/15) exist in the Rust/Python API but have no .inp keyword yet — Packmol's
Gaussian grammar is not pinned down here, and emitting a wrong parameter mapping
would silently mis-pack, so the parser rejects them rather than guessing.
Periodicity
pbc X Y Zandpbc X0 Y0 Z0 X1 Y1 Z1, mirroring Packmol'sgetinp.f90. The packer's cell grid is built directly from the declared box.
Script parser strictness
- Unknown top-level keywords are rejected via
ScriptError::UnknownKeyword. A silently droppedpbcpreviously triggered a 42 GB cell-grid allocation — strict parsing prevents that class of failure.
Determinism
- Explicit seeds; identical seed values are used for paired Packmol vs molpack runs in the regression suite.
Verification¶
Batch example validation¶
tests/examples_batch.rs runs all five canonical workloads. Marked
#[ignore] because the run is expensive — invoke explicitly:
The test asserts:
- atom and molecule counts match the expanded target specs;
- XYZ output is structurally sound;
- quantified violation metrics stay within tolerance / precision.
Violation metrics¶
Each side reports max_distance_violation, max_constraint_penalty,
violating_pairs, and violating_atoms. Both packers must satisfy the
same thresholds.
Accepted differences¶
- Packed coordinates are not bit-identical with Packmol, even at the same seed — the inner solver and RNG are independent implementations.
- The two Gaussian-surface restraint kinds have no
.inpkeyword; they are reachable only from the Rust/Python API. - Acceptance is therefore functional rather than numerical: the same restraints, the same conflict criteria, the same order of magnitude of tolerance / precision, and comparable violation metrics.