-
Notifications
You must be signed in to change notification settings - Fork 100
Description
Is your feature request related to a problem? Please describe.
- Some partial charge assignment methods only report three or four decimal places of precision
- Some System/Topology file formats only store three or four decimals of precision
Both of these issues can lead to rounding errors that become significant in larger molecules.
Describe the solution you'd like
ParmEd implemented this approach, which rounds existing charges to the desired precision, and then adds the sum of the rounding errors to the first particle to achieve the correct net charge on each residue. This may be tricky for OFFTK, since it has no concept of "Residues", thus a large biopolymer could require a substantial correction, which should not be dumped on a first atom (for example, if 1000 residues each contributed 0.001e of rounding error, then the first atom might end up getting +1 added to its charge).
It seems likely that we could apply the same solution, but just with a slightly more complex algorithm to spread out the final charge correction over several atoms. It's not clear to me that this is a question with an "automagic" solution -- pathological cases could lead us to introducing errors with this functionality (for example, accumulating a large error given a biopolymer, or adding a dipole to a symmetric system).
We'd want to figure out how this would interface with our current functionality. Basically, we should allow
- Users disabling the rounding altogether
- Users rounding to a custom precision
- Users applying this rounding only to certain molecules
Further, we should figure out where this would live in our current API. Some possibilities include
- kwarg to create_openmm_system:
do_not_round_charges=[molecules]orcustom_charge_rounding={molecule:precision} - Tag-level element in the ForceField itself -- likely in
ElectrostaticsHandler(but this prevents us from handling different molecules individually). So, for example,<Electrostatics version="0.3" method="PME" scale12="0.0" scale13="0.0" scale14="0.833333" cutoff="9.0 * angstrom" rounding_precision="4"/> - In our eventual OFF
Systemclass, which would know which simulation format it is exporting to, and thus which precision to use.
I'm most in favor of the first and third options, since the second would require a change to the SMIRNOFF spec and disallow treating molecules differently. The first option is the only one that is immediately available.
Additional context
In the LibraryCharges PR that was already merged (#433), we added a check that the sum of a molecule's partial charges must be within 0.01 of the molecule's formal charge. This can be overridden by a kwarg (allow_nonintegral_charges=True).