Packer¶
Molpack drives the GENCAN-based three-phase optimizer. All tuning
is through with_* builder methods — the constructor takes no
arguments.
Constructor¶
All defaults match Packmol's reference behaviour. Override any of them via the builders below.
Builder methods¶
Every builder returns a new Molpack:
packer = (
Molpack()
.with_tolerance(2.0) # minimum allowed pairwise distance (Å)
.with_precision(0.01) # convergence threshold on fdist and frest
.with_inner_iterations(20) # GENCAN inner-loop cap (Packmol `maxit`)
.with_init_passes(0) # initial compaction passes (Packmol `nloop0`; 0 = auto)
.with_init_box_half_size(1000) # hard bound on init placement (Packmol `sidemax`)
.with_perturb_fraction(0.05) # fraction of atoms re-sampled per stall
.with_random_perturb(False) # randomize perturbation target selection
.with_perturb(True) # enable the stall-perturbation heuristic
.with_seed(42) # deterministic RNG
.with_parallel_eval(False) # rayon-backed pair-kernel eval (opt-in)
.with_lammps_output(True) # attach LAMMPS-style screen output
.with_log_level("progress") # quiet | summary | progress | verbose
.with_log_frequency(1) # print every N outer steps
)
Use .with_lammps_output(False) or .with_log_level("quiet") to run
silently (the default). .with_progress() is kept as a compatibility
alias for enabling/disabling progress output.
A few more builders cover specific needs:
packer = (
packer
.with_periodic_box([0, 0, 0], [30, 30, 30]) # fully-periodic cell (Packmol `pbc`)
.with_avoid_overlap(True) # reject init placements onto a fixed molecule
.with_xyz_output("traj.xyz", every=5) # record the packing trajectory
)
Global restraints¶
Attach a single restraint to every target in a pack:
Semantically equivalent to calling .with_restraint(r) on every
target.
Handlers¶
Attach any object implementing some subset of on_start(ntotat, ntotmol),
on_step(info) -> bool | None, on_finish():
class MyHandler:
def on_step(self, info):
print(f"phase={info.phase} loop={info.loop_idx} fdist={info.fdist:.3f}")
return None # or True to request early stop
packer = packer.with_handler(MyHandler())
Returning True from on_step halts the run at the next check. See
the Handler Protocol in molpack.
Periodic boundaries¶
PBC can be declared per-axis on an InsideBoxRestraint, or as a
fully-periodic cell directly on the packer via
.with_periodic_box(min, max). See
Periodic boundaries.
Running¶
targets— list ofTargetobjects (must be non-empty).max_loops— per-phase outer-iteration budget.
Raises one of the typed PackError subclasses on failure
(NoTargetsError, InvalidPBCBoxError,
ConflictingPeriodicBoxesError, …).
pack() returns a molrs.Frame. To retrieve structured diagnostics,
use pack_with_report():
PackResult¶
result.positions # (N, 3) float64 ndarray — packed coordinates
result.frame # molrs.Frame — topology-complete packed frame
result.elements # list[str] — one entry per atom
result.natoms # int
result.converged # bool — True iff both fdist and frest < precision
result.fdist # float — final distance-violation sum
result.frest # float — final restraint-violation sum
Inspect convergence:
PackResult.frame is the same Frame returned by pack(). Pass it to a
writer of your choice (e.g. molrs.write_pdb). molpack does not
provide writers.
Reproducibility¶
Packing is deterministic for a given (targets, tolerance, precision,
seed) tuple. Capture the builder chain and max_loops to reproduce
a result later.