pub struct PackContext {Show 60 fields
pub constraints: Constraints,
pub xcart: Vec<[F; 3]>,
pub elements: Vec<Option<Element>>,
pub coor: Vec<[F; 3]>,
pub radius: Vec<F>,
pub radius_ini: Vec<F>,
pub fscale: Vec<F>,
pub use_short_radius: Vec<bool>,
pub short_radius: Vec<F>,
pub short_radius_scale: Vec<F>,
pub any_short_radius: bool,
pub any_fixed_atoms: bool,
pub atom_props: Vec<AtomProps>,
pub fdist: F,
pub frest: F,
pub fdist_atom: Vec<F>,
pub frest_atom: Vec<F>,
pub nmols: Vec<usize>,
pub natoms: Vec<usize>,
pub idfirst: Vec<usize>,
pub ntype: usize,
pub ntype_with_fixed: usize,
pub ntotmol: usize,
pub ntotat: usize,
pub nfixedat: usize,
pub constrain_rot: Vec<[bool; 3]>,
pub rot_bound: Vec<[[F; 2]; 3]>,
pub restraints: Vec<Arc<dyn AtomRestraint>>,
pub iratom_offsets: Vec<usize>,
pub iratom_data: Vec<RestraintRef>,
pub collective: Vec<(usize, Arc<dyn Restraint>)>,
pub ibtype: Vec<usize>,
pub ibmol: Vec<usize>,
pub fixedatom: Vec<bool>,
pub comptype: Vec<bool>,
pub ncells: [usize; 3],
pub cell_length: [F; 3],
pub pbc_length: [F; 3],
pub pbc_min: [F; 3],
pub pbc_periodic: [bool; 3],
pub latomfirst: Vec<u32>,
pub latomnext: Vec<u32>,
pub latomfix: Vec<u32>,
pub lcellfirst: u32,
pub lcellnext: Vec<u32>,
pub empty_cell: Vec<bool>,
pub fixed_cells: Vec<usize>,
pub active_cells: Vec<usize>,
pub neighbor_cells_f: Vec<[usize; 13]>,
pub neighbor_cells_g: Vec<[usize; 13]>,
pub init1: bool,
pub move_flag: bool,
pub parallel_pair_eval: bool,
pub scale: F,
pub scale2: F,
pub sizemin: [F; 3],
pub sizemax: [F; 3],
pub dmax: Vec<F>,
pub work: WorkBuffers,
pub frame: Frame,
/* private fields */
}Expand description
Full runtime context for one packing execution. All arrays are 0-based; Fortran 1-based arrays are shifted by -1.
Fields§
§constraints: Constraints§xcart: Vec<[F; 3]>Current Cartesian positions: xcart[icart] = [x, y, z]. Size: ntotat.
elements: Vec<Option<Element>>Element per atom: elements[icart]. Size: ntotat. None means unknown/“X”.
coor: Vec<[F; 3]>Reference coordinates coor[idatom] = [x, y, z]. Size: total atoms across all types.
radius: Vec<F>Current radii (may be scaled): radius[icart]. Size: ntotat.
radius_ini: Vec<F>Original (unscaled) radii: radius_ini[icart]. Size: ntotat.
fscale: Vec<F>Function scaling per atom: fscale[icart]. Size: ntotat.
use_short_radius: Vec<bool>§short_radius: Vec<F>§short_radius_scale: Vec<F>§any_short_radius: boolSummary flag — true iff any atom has use_short_radius set. Lets
the objective hot loop skip the short-radius branch entirely for the
common case (no short-radius usage). Maintained incrementally via
setters + re-synced by Self::sync_atom_props.
any_fixed_atoms: boolSummary flag — true iff any atom is a fixed-structure atom. Lets
the objective hot loop skip the fixedatom[i] && fixedatom[j]
short-circuit when there are no fixed atoms. Maintained
incrementally via setters + re-synced by Self::sync_atom_props.
atom_props: Vec<AtomProps>AoS mirror of the frequently-read per-atom fields. Kept in sync
with the individual Vec<_>s by Self::sync_atom_props plus the
per-field setters (set_radius, set_fscale, set_fixed_atom,
set_use_short_radius, set_ibmol, set_ibtype). The objective
hot kernels read exclusively from here; callers mutating the
underlying Vec<_>s directly must call Self::sync_atom_props
before the next evaluate(), or the debug-build invariant in
Self::debug_assert_atom_props_sync will catch the drift.
fdist: FMaximum inter-molecular distance violation (fdist in Fortran).
frest: FMaximum constraint violation (frest in Fortran).
fdist_atom: Vec<F>Per-atom distance violation (for movebad).
frest_atom: Vec<F>Per-atom constraint violation (for movebad).
nmols: Vec<usize>Number of molecules per type: nmols[itype]. 0-based type index.
natoms: Vec<usize>Number of atoms per type: natoms[itype]. 0-based type index.
idfirst: Vec<usize>First datum atom index (0-based) for each type: idfirst[itype].
ntype: usizeTotal number of types (free).
ntype_with_fixed: usizeTotal number of types including fixed types.
ntotmol: usizeTotal number of free molecules.
ntotat: usizeTotal number of atoms (free + fixed).
nfixedat: usizeNumber of fixed atoms.
constrain_rot: Vec<[bool; 3]>Rotation constraint flags per free type in Euler variable order [beta(y), gama(z), teta(x)].
rot_bound: Vec<[[F; 2]; 3]>Rotation bounds per free type and Euler variable: [center_rad, half_width_rad].
restraints: Vec<Arc<dyn AtomRestraint>>All restraints pool: restraints[irest].
iratom_offsets: Vec<usize>CSR offsets for per-atom restraint indices:
restraints of atom icart are in iratom_data[iratom_offsets[icart]..iratom_offsets[icart+1]].
iratom_data: Vec<RestraintRef>Flattened per-atom restraint indices.
collective: Vec<(usize, Arc<dyn Restraint>)>Group-level restraints, paired with the (0-based) type they act on:
(itype, restraint). Evaluated once per group in the objective with the
coordinates of all copies of itype; the coupled gradient is scattered
back into work.gxcar. Empty in the common (no collective restraint) case.
ibtype: Vec<usize>Type index per atom: ibtype[icart] (0-based type index).
ibmol: Vec<usize>Molecule index within its type: ibmol[icart] (0-based).
fixedatom: Vec<bool>Is this a fixed atom?
comptype: Vec<bool>Is this type being computed in the current iteration?
ncells: [usize; 3]§cell_length: [F; 3]§pbc_length: [F; 3]§pbc_min: [F; 3]§pbc_periodic: [bool; 3]Per-axis periodicity flags. pbc_periodic[k] == true means axis
k wraps in the pair-kernel minimum image and the cell list;
false means the cell list clamps and no wrap is applied. Set
from restraints that override AtomRestraint::periodic_box().
latomfirst: Vec<u32>latomfirst[icell] = first atom index in cell, NONE_IDX if empty.
Stored as flat Vec indexed by index_cell.
latomnext: Vec<u32>latomnext[icart] = next atom in the same cell (NONE_IDX = end).
latomfix: Vec<u32>Fixed atom list per cell (permanent), NONE_IDX if cell has no fixed atoms.
lcellfirst: u32Occupied cell linked list: first cell (NONE_IDX if none occupied).
lcellnext: Vec<u32>lcellnext[icell] = next occupied cell (NONE_IDX = end).
empty_cell: Vec<bool>Is cell empty?
fixed_cells: Vec<usize>Cells that contain fixed atoms and must be restored on every reset.
active_cells: Vec<usize>Cells touched during the previous objective/gradient evaluation.
neighbor_cells_f: Vec<[usize; 13]>Precomputed 13 forward-neighbor cell indices per cell for compute_f.
neighbor_cells_g: Vec<[usize; 13]>Precomputed 13 forward-neighbor cell indices per cell for compute_g.
The parallel gradient path (crate::objective) walks this same
half-stencil — each pair once — accumulating into per-worker scratch
buffers, so no full 26-neighbor list is needed.
init1: boolIf true, skip pair-distance computations (constraints only during init).
move_flag: boolIf true, accumulate per-atom fdist/frest (movebad mode).
parallel_pair_eval: boolRun the pair-kernel reductions (accumulate_pair_f,
accumulate_pair_fg) on rayon. Off by default — parallelism is
an explicit opt-in via Molpack::with_parallel_eval because the
crossover is workload-shaped and can’t be inferred reliably from
active_cells.len(). The flag is stored regardless of the
rayon feature so the Molpack API stays the same; when the
feature is off the field is read but the parallel path doesn’t
exist and the serial branch runs unconditionally.
scale: F§scale2: F§sizemin: [F; 3]§sizemax: [F; 3]§dmax: Vec<F>§work: WorkBuffers§frame: FrameFrame that accumulates constant columns (element, mol_id) during init and receives position columns at the end of packing.
Implementations§
Source§impl PackContext
impl PackContext
Sourcepub fn new(ntotat: usize, ntotmol: usize, ntype: usize) -> Self
pub fn new(ntotat: usize, ntotmol: usize, ntype: usize) -> Self
Allocate and zero-initialize all arrays.
Sourcepub fn runtime(&self) -> RuntimeState<'_>
pub fn runtime(&self) -> RuntimeState<'_>
Read-only runtime state view.
Sourcepub fn runtime_mut(&mut self) -> RuntimeStateMut<'_>
pub fn runtime_mut(&mut self) -> RuntimeStateMut<'_>
Mutable runtime state view.
Sourcepub fn evaluate(
&mut self,
x: &[F],
mode: EvalMode,
gradient: Option<&mut [F]>,
) -> EvalOutput
pub fn evaluate( &mut self, x: &[F], mode: EvalMode, gradient: Option<&mut [F]>, ) -> EvalOutput
Unified constraints evaluation entrypoint.
Sourcepub fn resize_cell_arrays(&mut self)
pub fn resize_cell_arrays(&mut self)
Resize cell list arrays after ncells is set.
Sourcepub fn resetcells(&mut self)
pub fn resetcells(&mut self)
Reset cell lists (called at start of each compute_f/compute_g).
Port of resetcells.f90.
pub fn reset_eval_counters(&mut self)
Sourcepub fn sync_atom_props(&mut self)
pub fn sync_atom_props(&mut self)
Rebuild atom_props from the individual per-atom Vec<_>s. Call
once after packer setup has populated every per-atom field, and
whenever a field has been mutated via the underlying Vec<_>
directly rather than through a setter.
Also refreshes the summary flags (any_fixed_atoms,
any_short_radius) and their backing counters.
Sourcepub fn set_radius(&mut self, i: usize, value: F)
pub fn set_radius(&mut self, i: usize, value: F)
Update atom i’s live radius on both the Vec<F> and the AoS
mirror. Preferred over writing sys.radius[i] directly: the
hot-loop kernel reads atom_props[i].radius, so a raw write
would silently desynchronize.
Sourcepub fn set_fscale(&mut self, i: usize, value: F)
pub fn set_fscale(&mut self, i: usize, value: F)
Update atom i’s live fscale on both storages. Used by the
scaling-phase paths that modulate per-atom weight.
Sourcepub fn set_fixed_atom(&mut self, i: usize, is_fixed: bool)
pub fn set_fixed_atom(&mut self, i: usize, is_fixed: bool)
Toggle atom i’s fixed-structure flag and keep the atom_props
mirror, the any_fixed_atoms summary flag, and the private
counter in lock-step.
Sourcepub fn set_use_short_radius(&mut self, i: usize, use_short: bool)
pub fn set_use_short_radius(&mut self, i: usize, use_short: bool)
Toggle atom i’s use_short_radius flag, maintaining the mirror,
summary flag, and counter.
Sourcepub fn set_ibmol(&mut self, i: usize, value: usize)
pub fn set_ibmol(&mut self, i: usize, value: usize)
Update ibmol[i] and the matching mirror field.
Sourcepub fn set_ibtype(&mut self, i: usize, value: usize)
pub fn set_ibtype(&mut self, i: usize, value: usize)
Update ibtype[i] and the matching mirror field.
Sourcepub fn debug_assert_atom_props_sync(&self)
pub fn debug_assert_atom_props_sync(&self)
Debug-only invariant: every atom_props[i] matches the state
derivable from the individual per-atom Vec<_>s, and the
summary counters / flags agree with reality.
O(ntotat) per call in debug builds; compiled to a single
early-return in release builds (see the cfg!(debug_assertions)
gate below — with #[inline(always)] the release body DCE’s).
The objective hot loop calls this at the entry of compute_f /
compute_g / compute_fg so direct-write drift fires at the
next evaluate instead of silently producing wrong energies.
pub fn increment_ncf(&mut self)
pub fn increment_ncg(&mut self)
pub fn ncf(&self) -> usize
pub fn ncg(&self) -> usize
Trait Implementations§
Source§impl Objective for PackContext
impl Objective for PackContext
Source§fn bounds(&self, l: &mut [F], u: &mut [F])
fn bounds(&self, l: &mut [F], u: &mut [F])
Port of gencan::build_bounds (pre-A.6). COM variables (first n/2)
stay [-1e20, +1e20]; Euler variables (last n/2) inherit
rot_bound when constrain_rot is set for the owning type /
molecule / axis.
Source§fn evaluate(
&mut self,
x: &[F],
mode: EvalMode,
gradient: Option<&mut [F]>,
) -> EvalOutput
fn evaluate( &mut self, x: &[F], mode: EvalMode, gradient: Option<&mut [F]>, ) -> EvalOutput
mode selects between f only,
gradient only, and both. When a gradient is requested, gradient
must be Some(buf) with buf.len() == x.len(); when it is not,
gradient is ignored. Read moreSource§fn ncf(&self) -> usize
fn ncf(&self) -> usize
reset_eval_counters call.Source§fn ncg(&self) -> usize
fn ncg(&self) -> usize
reset_eval_counters call.