Force field¶
The forcefield section holds the parameters that define the energy model
of the record's particles: atom types, bonded and non-bonded styles, their
per-type tables, the unit system those numbers are in, and the 1-2 / 1-3 /
1-4 scaling. It is a peer of meta, system and trajectory at the
root. How a job used the model (engine, cutoff schedule,
thermostat) is method; which particle carries which type is
system.
forcefield is frame-shaped: a JSON document stored as the group's
attributes, plus one block per style. A
reader that knows nothing of force fields reads it with the frame codec and
loses nothing.
forcefield
+-- name: string[]
+-- units
| +-- (preset: string[])
| +-- (length | energy | angle | charge | mass | time: string[])
+-- (source)
| +-- format: string[]
| +-- (uri: string[])
| +-- (sha256: string[])
+-- (special_bonds)
| +-- lj: f64[3]
| +-- coul: f64[3]
+-- styles: [{category, style, (params), (expression), (endpoint_key)}, ...]
\-- <category>.<style> one block per entry of styles
\-- name: string[T]
\-- (itom | jtom | ktom | ltom: string[T])
\-- (<annotation>: string[T])
\-- (<param>: f64[T] | string[T])
\-- (_validity)
A record whose only substantive section is forcefield is valid: it is a
force-field package.
The document¶
The group's attribute map is exactly the force-field document. Keys other than those below are preserved by every reader.
name
Required. The force field's name ("OPLS-AA", "GAFF2", "openff-2.1.0").
units
Required. The unit of every number in the section, by quantity. Every parameter in a style table and every style-level parameter is a number in these units, and a reader MUST NOT convert it on read. A writer that translates a file states the file's own units here rather than converting, except where one quantity is mixed inside the source (a degree angle beside a per-radian force constant): it then converts that quantity to one unit and states that unit.
| Key | Quantity | Example |
|---|---|---|
length |
lengths, and the length part of every derived unit | angstrom, nm |
energy |
energies, and the energy part of every derived unit | kcal/mol, kJ/mol, eV |
angle |
angles and phases, and the angle part of force constants | radian, degree |
charge |
charges | e |
mass |
masses | dalton |
time |
times (rarely present) | fs |
A unit string is parseable by pint. A derived
dimension (a bond force constant, energy/length²) is composed from these;
it has no key of its own.
preset names a unit system instead of listing it. The presets are:
| Preset | length | energy | angle | charge | mass | time |
|---|---|---|---|---|---|---|
real |
angstrom |
kcal/mol |
radian |
e |
dalton |
fs |
metal |
angstrom |
eV |
radian |
e |
dalton |
ps |
si |
m |
J |
radian |
C |
kg |
s |
cgs |
cm |
erg |
radian |
statcoulomb |
g |
s |
electron |
bohr |
hartree |
radian |
e |
dalton |
fs |
micro |
micrometer |
picogram * micrometer**2 / microsecond**2 |
radian |
picocoulomb |
picogram |
microsecond |
nano |
nm |
attogram * nm**2 / ns**2 |
radian |
e |
attogram |
ns |
lj |
— | — | radian |
— | — | — |
The names are those of the LAMMPS units command, but the angle is a radian
in every preset: a LAMMPS input file's degrees are an input convention, not
the unit system. lj is reduced units: no quantity but angle has a unit,
and the numbers are in the reduced scale of the producer's choosing.
units MUST carry preset or at least one quantity. When both a preset
and a quantity are present they MUST agree (pint-equivalent strings); a
reader refuses a document where they do not. A style whose parameters need a
quantity that units does not resolve is not refused on read; a validator
SHOULD report it.
source
Optional provenance of the parameters: format ("openmm-xml", "offxml",
"gromacs-top", "lammps", "amber-frcmod", …), uri, and sha256 (64
lowercase hex digits) of the source file's bytes.
special_bonds
Optional. The scale applied to non-bonded interactions between atoms that are
1-2, 1-3 and 1-4 neighbours through bonds: lj for the van-der-Waals styles,
coul for the electrostatic ones, each [w12, w13, w14]. 0 excludes the
class, 1 leaves it at full strength. Pairs further apart are at full
strength. Absent means the force field declares no weights; a consumer
supplies its own default and SHOULD say so. Which weight set a pair style
takes is its registry entry's special class (Style registry).
styles
Required (it may be empty). An ordered list; each entry is one style:
| Field | Required | Meaning |
|---|---|---|
category |
yes | what the style's rows parameterize (Categories); matches ^[a-z][a-z0-9_]*$ |
style |
yes | the functional form's name within its category (harmonic, lj/cut); non-empty UTF-8 |
params |
no | style-level parameters: a map of name to a finite number or a string (cutoff, mixing) |
expression |
no | the energy expression (Expressions) |
endpoint_key |
no | "type" (default), "class" or "smirks": what a row's endpoints name (Endpoints) |
A (category, style) pair appears at most once. Order is preserved; it
carries no physical meaning. Every entry has exactly one table, at the block
name below, even when the table has no rows.
Two style-level parameter names are reserved on pair styles. params.special
("lj" or "coul") gives an unregistered pair style its special class.
params.mixing on a van-der-Waals pair style is its combining rule:
arithmetic (Lorentz–Berthelot: σ = ½(σᵢ+σⱼ), ε = √(εᵢεⱼ)), geometric
(σ = √(σᵢσⱼ), ε = √(εᵢεⱼ)) or sixthpower (σ⁶ = ½(σᵢ⁶+σⱼ⁶),
ε = 2√(εᵢεⱼ)σᵢ³σⱼ³/(σᵢ⁶+σⱼ⁶)). Absent means the style declares none.
Style tables¶
Block name¶
A style's table is the block named
where the encoded style is the style's UTF-8 bytes with every byte outside
A–Z a–z 0–9 - _ written as % and two uppercase hex digits. So
bond/harmonic lives at bond.harmonic and pair/lj/cut/coul/long at
pair.lj%2Fcut%2Fcoul%2Flong. Decoding splits at the first . and
percent-decodes the rest. A reader resolves a style's table by this name; a
block whose name no style entry produces is preserved as unknown content.
Rows and columns¶
A table has one row per type. Its count is the number of types. It carries no structural shape.
name
Required, string, never null, unique within the table. The label a system
row names (Linking a system). Any UTF-8 string; it is
never parsed into endpoints.
itom, jtom, ktom, ltom
The endpoints, string, never null: the first arity of them, in this
order, and no others (Categories). A pair row always carries
both itom and jtom; a self pair has itom == jtom.
Annotation columns, string, nullable:
| Column | Meaning |
|---|---|
class |
the atom class (OpenMM class, GROMACS bond_type); atom tables only |
element |
IUPAC symbol; atom tables only |
smarts |
a SMARTS pattern that assigns this type (foyer def) |
smirks |
a SMIRKS pattern that assigns this row (OpenFF) |
overrides |
comma-separated names of types this one takes precedence over |
desc |
free text |
doi |
a reference |
Parameter columns: every other column is one parameter, named as the style
names it (k, r0, epsilon, periodicity2), and is f64 or string.
No other dtype is admitted, with one exception: a column whose name is a
canonical key has that key's dtype, as it
does in every block (atomic_number is u64). An integer-valued parameter
that is not a canonical key (a periodicity) is an f64. A parameter a row
does not have is null in that row (nullable columns),
never a sentinel such as 0 or NaN. A column declares no
precision: parameters are stored exactly.
An atom table additionally recognises mass (f64, units.mass), charge
(f64, units.charge) and atomic_number (u64).
Endpoints¶
endpoint_key says what the endpoint strings name:
"type": thenameof a row of an atom table;"class": theclassof a row of an atom table (OpenMM bonded forces key on classes). Every atom table MUST then carryclass;"smirks": nothing. The table carries no endpoint columns; each row'ssmirks(required, never null) assigns it, and the arity is the number of mapped atoms in the pattern.
The empty string "" is the wildcard: it matches any type or class.
GROMACS X, LAMMPS * and an absent OpenMM attribute become "".
When a consumer assigns rows to a topology by endpoints (typing, not linking), a row matches a tuple of atom types when its endpoints equal the tuple in order or reversed (an improper: in order only); among matching rows the one with the fewest wildcards wins, and among those the first in table order. A record that names its rows (Linking a system) needs none of this.
Categories¶
| Category | Arity | Rows parameterize | System block |
|---|---|---|---|
atom |
0 | an atom type | atoms (type) |
bond |
2 | a bond type | bonds |
angle |
3 | an angle type; jtom the vertex |
angles |
dihedral |
4 | a proper torsion type | dihedrals |
improper |
4 | an improper type | impropers |
pair |
2 | a non-bonded pair of atom types | resolved through atoms.type |
pair14 |
2 | an explicit 1-4 pair of atom types | pairs rows with is_14 |
constraint |
2 | a constrained distance type | constraints |
virtual_site |
0 | a virtual-site construction | virtual_sites |
drude |
2 | a core–Drude pair type (itom core, jtom Drude) |
drudes |
The system blocks are standardized identifiers. A category
outside this table is legal and preserved; its arity is the number of
endpoint columns its table carries, which MUST be a prefix of itom,
jtom, ktom, ltom.
A pair14 row replaces, for a 1-4 pair of its two types, the parameters the
same-named pair style would give it, and that pair's special_bonds 1-4
weight is then not applied on top.
Linking a system¶
Types are linked by name. Each rule below is how a reader finds the parameters of a system row:
atoms.typenames a row of an atom table. A force field whose styles are allsmirks-keyed has no atom table;atoms.typethen names a row of itspairtable.- A row of a relation block of category c (table above) names, in its
typecolumn, a row of a c table. If the block carries astylecolumn (string), the row's table is<c>.<style>; otherwise every c table holding that name applies, and their energies add. pairandpair14tables are resolved through atom types, not row names: for atoms of types a and b, the row whose endpoints are{a, b}. Failing one, apairstyle uses itsmixingof the two self rows{a, a}and{b, b}; apair14style gives nothing, and the pair keeps its scaledpairinteraction. Every pair style of the force field applies to every non-excluded pair, scaled byspecial_bonds(ljorcoulper the style's special class). Thepairsblock, where present, lists intramolecular pairs explicitly; itsis_14rows are the 1-4 pairspair14tables apply to.- A relation block may carry a parameter column named as its style names it. Its value, where not null, is that row's parameter and overrides the table; a style whose table has no rows takes every parameter from the relation (a per-instance style, as MMFF and UFF are).
type_id, where present, is a format-local ordinal and plays no part in linking.
A name that resolves to nothing is not a format error. A reader MUST NOT refuse a record for it; a validator SHOULD report it.
Style registry¶
A style named here MUST mean exactly this energy and these parameters.
A style not named here SHOULD carry an expression; a reader preserves it
either way. Dimensions: E energy, L length, A angle, 1 a pure number.
φ is the signed dihedral, χ = |φ|, θ the angle at jtom, r the distance.
| Style | Energy | Per-type parameters | Style parameters |
|---|---|---|---|
atom.full |
— | mass, charge |
— |
bond.harmonic |
½·k·(r − r0)² | k E/L², r0 L |
— |
bond.morse |
D·(1 − e^{−alpha·(r − r0)})² | D E, alpha 1/L, r0 L |
— |
bond.class2 |
k2·Δ² + k3·Δ³ + k4·Δ⁴, Δ = r − r0 | r0 L, k2 E/L², k3 E/L³, k4 E/L⁴ |
— |
angle.harmonic |
½·k·(θ − theta0)² | k E/A², theta0 A |
— |
angle.class2 |
k2·Δ² + k3·Δ³ + k4·Δ⁴, Δ = θ − theta0 | theta0 A, k2 E/A², k3 E/A³, k4 E/A⁴ |
— |
dihedral.periodic |
Σₘ kₘ·[1 + cos(nₘ·φ − γₘ)] | k E, periodicity 1, phase A — or, per term m = 1, 2, …, k<m>, periodicity<m>, phase<m> |
— |
dihedral.opls |
½·[k1(1 + cos φ) + k2(1 − cos 2φ) + k3(1 + cos 3φ) + k4(1 − cos 4φ)] | k1…k4 E |
— |
dihedral.rb |
Σₙ₌₀⁵ cₙ·cosⁿ(φ − π) | c0…c5 E |
— |
dihedral.charmm |
k·[1 + cos(n·φ − γ)] | k E, periodicity 1, phase A, w 1 (the 1-4 weight; not in this term) |
— |
dihedral.harmonic |
k·[1 + sign·cos(n·φ)] | k E, sign 1 (±1), periodicity 1 |
— |
dihedral.multi/harmonic |
Σₙ₌₁⁵ aₙ·cosⁿ⁻¹ φ | a1…a5 E |
— |
dihedral.class2 |
Σₙ₌₁³ kₙ·[1 − cos(n·φ − phiₙ)] | k1, phi1, k2, phi2, k3, phi3 (E, A) |
— |
improper.harmonic |
k·(χ − chi0)² | k E/A², chi0 A |
— |
improper.periodic |
as dihedral.periodic |
as dihedral.periodic |
— |
improper.cvff |
k·[1 + sign·cos(n·χ)] | k E, sign 1, periodicity 1 |
— |
improper.trefoil |
⅓·Σ over the three orderings of the outer atoms, central atom jtom, of the dihedral.periodic energy |
as dihedral.periodic |
— |
pair.lj/cut |
C·ε·[(σ/r)ⁿ − (σ/r)ᵐ], C = n/(n−m)·(n/m)^{m/(n−m)}, r < cutoff; n = 12, m = 6 gives 4ε[(σ/r)¹² − (σ/r)⁶] | epsilon E, sigma L |
cutoff L, mixing, n 1, m 1, shift 1 (non-zero: shifted to 0 at cutoff) |
pair.lj/class2 |
ε·[2(σ/r)⁹ − 3(σ/r)⁶] | epsilon E, sigma L |
cutoff L, mixing |
pair.buck |
a·e^{−r/rho} − c/r⁶ | a E, rho L, c E·L⁶ |
cutoff L |
pair.morse |
d0·[(1 − e^{−alpha(r − r0)})² − 1] | d0 E, alpha 1/L, r0 L |
cutoff L |
pair.coul/cut |
coulomb·qᵢqⱼ / (dielectric·(r + delta)), r < cutoff | — (charges from atoms.charge) |
coulomb E·L/Q², dielectric 1, delta L, cutoff L |
pair.coul/long/pme |
Ewald-summed coulomb·qᵢqⱼ/r (particle-mesh) | — (charges from atoms.charge) |
coulomb E·L/Q², cutoff L, alpha 1/L, order 1, grid_x, grid_y, grid_z 1 |
pair14.lj/cut |
as pair.lj/cut |
epsilon E, sigma L |
— |
constraint.fixed |
|rᵢ − rⱼ| = r0 | r0 L |
— |
virtual_site.average2 |
x = w1·x_j + w2·x_k | w1, w2 1 |
— |
virtual_site.average3 |
x = w1·x_j + w2·x_k + w3·x_l | w1, w2, w3 1 |
— |
virtual_site.outofplane3 |
x = x_j + w12·r_jk + w13·r_jl + wcross·(r_jk × r_jl) | w12, w13 1, wcross 1/L |
— |
drude.harmonic |
½·k·|r_core − r_drude|²; polarizability alpha; Thole screening thole | k E/L², alpha L³, thole 1 |
— |
Special classes: pair.lj/cut, pair.lj/class2, pair.buck, pair.morse
take special_bonds.lj; pair.coul/cut and pair.coul/long/pme take
special_bonds.coul. An unregistered pair style takes lj unless its
params.special is "coul". pair14 styles take no weight.
In virtual_site rows the constructed site is atomi of its
virtual_sites row and x_j, x_k, x_l are the positions of atomj, atomk,
atoml; r_jk = x_k − x_j.
The registry's conventions are the reference implementation's. Where a
source format differs — LAMMPS bond_style harmonic is K·(r − r0)², so
k = 2K — the translation is in Format mappings.
Expressions¶
expression is the style's energy as one formula in the syntax of OpenMM's
custom forces (Lepton): + - * / ^, parentheses, exp log sqrt sin cos tan
asin acos atan abs min max step delta select, numeric literals. Its free
variables are the geometric variable of the category (r for bond, pair,
pair14, constraint; theta for angle; phi for dihedral; chi for
improper), the style's per-type and style-level parameter names, and, for
pair styles, q1 and q2. Per-term sums are written out.
A reader MUST preserve expression byte for byte. It MAY evaluate
it. An expression on a registered style MUST agree with the registry.
Collections¶
A collection carries at most one force field, shared by
every record: atoms.type and every relation type in every record link
into it. A record of a collection carries no forcefield of its own. The
LMDB binding stores it under the key ff.
Format mappings¶
Informative. How the common sources map onto this section. "→" names the table and column a source item lands in; units are the source's own unless the row says otherwise.
OpenMM / foyer XML¶
units: length nm, energy kJ/mol, angle radian, charge e,
mass dalton.
| Source | Section |
|---|---|
<ForceField name combining_rule> |
name; combining_rule → params.mixing of pair.lj/cut |
<Info><Source> |
source.uri |
<AtomTypes><Type name class element mass def desc doi overrides> |
atom.full: name, class, element, mass, smarts (def), desc, doi, overrides |
<HarmonicBondForce><Bond class1 class2 length k> |
bond.harmonic: itom, jtom, r0 = length, k; endpoint_key class (or type for type1/type2) |
<HarmonicAngleForce><Angle … angle k> |
angle.harmonic: theta0 = angle, k |
<PeriodicTorsionForce><Proper … periodicityN phaseN kN> |
dihedral.periodic: periodicity<N>, phase<N>, k<N> |
<PeriodicTorsionForce><Improper …> |
improper.periodic, endpoints in file order (class1 central) |
<RBTorsionForce><Proper … c0…c5> |
dihedral.rb: c0…c5 |
<NonbondedForce coulomb14scale lj14scale> |
special_bonds lj [0, 0, lj14scale], coul [0, 0, coulomb14scale] |
<NonbondedForce><Atom type charge sigma epsilon> |
pair.lj/cut self row (itom = jtom = type) with sigma, epsilon; charge → atom.full.charge; a pair.coul/long/pme style with no rows |
<Custom*Force energy> with <PerBondParameter> / <GlobalParameter> |
a style named by the force, expression = energy, per-type columns and params |
<Residues> |
not carried |
OpenFF (SMIRNOFF .offxml)¶
Every value carries its unit in the file; a translator converts each into the
declared units (commonly angstrom, kcal/mol, radian, e, dalton;
angles convert from degrees because force constants are per radian²).
| Source | Section |
|---|---|
<SMIRNOFF version aromaticity_model> |
source.format offxml; aromaticity_model kept as a document key |
<Bonds potential="harmonic"><Bond smirks id length k> |
bond.harmonic, endpoint_key smirks: name = id, smirks, r0, k |
<Angles potential="harmonic"><Angle smirks id angle k> |
angle.harmonic, smirks-keyed: theta0, k |
<ProperTorsions><Proper smirks id periodicityN phaseN kN idivfN> |
dihedral.periodic, smirks-keyed: k<N> = kN / idivfN |
<ImproperTorsions><Improper …> |
improper.trefoil, smirks-keyed, k<N> = kN / idivfN |
<vdW potential="Lennard-Jones-12-6" combining_rules scale12 scale13 scale14 cutoff switch_width><Atom smirks id epsilon sigma\|rmin_half> |
pair.lj/cut, smirks-keyed: sigma (= rmin_half·2^{⅚} when given as rmin_half), epsilon; params mixing arithmetic, cutoff, switch_width; special_bonds.lj = [scale12, scale13, scale14] (a scale15 other than 1 has no form here) |
<Electrostatics scale12 scale13 scale14 cutoff> |
special_bonds.coul; pair.coul/long/pme |
<Constraints><Constraint smirks id distance> |
constraint.fixed, smirks-keyed: r0 = distance (null when absent) |
<LibraryCharges>, <ToolkitAM1BCC>, <ChargeIncrementModel> |
not tables: charges land in atoms.charge |
A system parameterized from it names rows by id: bonds.type = "b1",
atoms.type = "n16".
GROMACS topology¶
units: length nm, energy kJ/mol, angle radian, charge e,
mass dalton. GROMACS degrees (θ₀, φₛ) convert to radians.
| Source | Section |
|---|---|
[ defaults ] nbfunc comb-rule gen-pairs fudgeLJ fudgeQQ |
special_bonds lj [0, 0, fudgeLJ], coul [0, 0, fudgeQQ]; comb-rule 2 → mixing arithmetic, 3 → geometric (comb-rule 1, C6/C12, is an unregistered pair style with expression) |
[ atomtypes ] name bond_type at.num mass charge ptype V W |
atom.full: name, class (= bond_type), atomic_number, mass, charge, ptype; pair.lj/cut self row with sigma = V, epsilon = W |
[ bondtypes ] funct 1 / 3 |
bond.harmonic (r0 = b0, k = kb) / bond.morse (r0, D, alpha = β) |
[ angletypes ] funct 1 |
angle.harmonic (theta0, k) |
[ dihedraltypes ] funct 1 / 9 |
dihedral.periodic; funct 9 rows with equal endpoints become terms k<m>, periodicity<m>, phase<m> of one row |
[ dihedraltypes ] funct 2 |
improper.harmonic, k = k_ξ/2, chi0 = ξ₀ (agrees only at ξ₀ = 0) |
[ dihedraltypes ] funct 3 / 4 |
dihedral.rb (c0…c5) / improper.periodic |
[ pairtypes ] funct 1 |
pair14.lj/cut (sigma, epsilon) |
[ constrainttypes ] funct 1 |
constraint.fixed (r0) |
endpoint X |
"" |
| molecule sections | the system (conventions) |
LAMMPS coefficients¶
units.preset is the file's units style; angles convert from degrees to
radians.
| Source | Section |
|---|---|
bond_style harmonic / bond_coeff t K r0 |
bond.harmonic: k = 2K, r0 |
angle_style harmonic / angle_coeff t K θ0 |
angle.harmonic: k = 2K, theta0 |
dihedral_style opls K1 K2 K3 K4 |
dihedral.opls: k1…k4 |
dihedral_style fourier m K1 n1 d1 … |
dihedral.periodic: k<i>, periodicity<i>, phase<i> |
dihedral_style charmm K n d w |
dihedral.charmm: k, periodicity, phase, w |
dihedral_style harmonic K d n |
dihedral.harmonic: k, sign = d, periodicity |
dihedral_style multi/harmonic A1…A5 |
dihedral.multi/harmonic: a1…a5 |
improper_style harmonic K χ0 |
improper.harmonic: k = K, chi0 |
improper_style cvff K d n |
improper.cvff: k, sign = d, periodicity |
pair_style lj/cut/coul/long rc / pair_coeff i j ε σ |
pair.lj/cut (params.cutoff = rc; row itom i, jtom j) and pair.coul/long/pme |
pair_modify mix <rule> |
params.mixing |
special_bonds lj a b c coul d e f |
special_bonds |
pair_style hybrid sub-styles |
one style each; relation rows carry style |
type labels (Atom Type Labels) |
name; without labels the decimal type number |
* |
"" |
Conformance¶
The force-field suite (module = "forcefield") pins down:
ff-minimal: a name,unitsand one atom style round-trip;ff-round-trip: atom, bond, angle, multi-term dihedral, improper, two pair styles withmixing,special_bondsandsourceround-trip exactly;ff-wildcard-endpoints:""endpoints survive;ff-absent-params: a parameter some rows lack is null there, not filled;ff-string-params:class,element,smartsand a non-canonical string parameter survive;ff-style-name-encoding:pair.lj%2Fcut%2Fcoul%2Flongresolves tolj/cut/coul/long;ff-hybrid-styles: two bond styles, and a record whosebondscarrystyle;ff-per-instance-style: a style with no rows beside relation columns that carry its parameters;ff-unknown-style-with-expressionandff-unknown-category: preserved verbatim;ff-units-preserved:nm/kJ/molnumbers come back unconverted;ff-lj-preset:preset ljwith no quantity strings;ff-smirks-keyed: asmirks-keyed table with no endpoint columns;ff-without-special-bonds: absence survives as absence;ff-document-keys-preserved: a document key and a table no style names survive as unknown content;- refusals on read:
reject-ff-no-units,reject-ff-units-conflict,reject-ff-duplicate-style,reject-ff-missing-table,reject-ff-duplicate-type-name,reject-ff-wrong-arity,reject-ff-param-dtype,reject-ff-null-name,reject-ff-class-key-without-class.
The record suite adds record-with-forcefield (a system whose atoms.type
and bonds.type link into it) and forcefield-only-record; the collection
suite adds collection-forcefield.