-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Solvent-solute splitting #439
base: main
Are you sure you want to change the base?
Conversation
test_split_nb_using_exceptions is failing with: Exception: Maximum allowable relative force error exceeded (was 0.02369251; allowed 0.00000100). test_split_nb_using_subtraction is failing with: Exception: Maximum allowable relative force error exceeded (was 0.00001687; allowed 0.00000100)
The fn split_nb_using_exceptions now works as intended, to split into protein/solvent forces.
JDC suggested to use interaction groups only here, instead of a mixture of interaction groups and exceptions. this appears cleaner and passes quick test that the cloned system is equivalent to the original system. Co-Authored-By: John Chodera <[email protected]>
Thanks to JDC for spotting this. This affected `split_nb_using_interaction_groups` and `split_nb_using_exceptions` but not `split_nb_using_subtraction`... Co-Authored-By: John Chodera <[email protected]>
Current test behavior: 1. test_split_nb_using_interaction_groups() Exception: Maximum allowable relative force error exceeded (was 740.98931192; allowed 0.00000100). E alchemical_force = 651130.50822817, reference_force = 878.74004125, difference = 651136.97852131 2. test_split_nb_using_exceptions(): Exception: Maximum allowable relative force error exceeded (was 746.21620950; allowed 0.00000100). E alchemical_force = 662413.13233660, reference_force = 887.70499600, difference = 662419.85727222 3. test_split_nb_using_subtraction() Exception: Maximum allowable relative force error exceeded (was 0.00001820; allowed 0.00000100). E alchemical_force = 878.52677463, reference_force = 878.52663474, difference = 0.01599347
…forces using a surrogate force Current test behavior: Exception: Maximum allowable relative force error exceeded (was 0.00001101; allowed 0.00000100). E alchemical_force = 881.84056569, reference_force = 881.84068232, difference = 0.00971232
attempted simplification Exception: Maximum allowable relative force error exceeded (was 1554.77679366; allowed 0.00000100). E alchemical_force = 1372003.46106334, reference_force = 882.44334338, difference = 1372002.43200366 Co-Authored-By: John Chodera <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a few comments!
new_force.setCutoffDistance(nonbonded_force.getCutoffDistance()) | ||
#new_force.setEwaldErrorTolerance(nonbonded_force.getEwaldErrorTolerance()) | ||
#new_force.setForceGroup(nonbonded_force.getForceGroup()) | ||
new_force.setNonbondedMethod(nonbonded_force.getNonbondedMethod()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The nobonded methods may not directly translate from NonbondedForce to CustomNonbondedForce.
See: https://github.com/choderalab/openmmtools/blob/master/openmmtools/alchemy.py#L1488-L1491
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Will follow this example more closely
for i in range(num_particles): | ||
new_force.addParticle(nonbonded_force.getParticleParameters(i)) | ||
|
||
# now add all the exceptions? # TODO: check if we want to do this... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you definitely want to copy all exceptions -> exclusions, or else you'll end up in NaNdyland.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do!
# find the default nonbonded force | ||
force_index, nb_force = forces.find_forces(new_system, openmm.NonbondedForce, only_one=True) | ||
# create copies for each interaction. Only half in solvent/solvent and solute/solute as we double-count. | ||
nb_only_solvent_solvent = clone_nonbonded_parameters(nb_force, energy_prefactor='0.5*') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you want to multiple the energy by 0.5?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mistakenly assumed double-counting -- will revert
|
||
nb_only_solvent_solvent.addInteractionGroup(set1=solvent_indices, set2=solvent_indices) | ||
|
||
nb_solute.addInteractionGroup(set1=solute_indices, set2=solute_indices) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can just use
all_indices = solute_indices.union(solvent_indices)
nb_solute.addInteractionGroup(set1=solute_indices, set2=all_indices)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will uncomment this equivalent way (L249 and L256)
#nb_solute.addInteractionGroup(set1=solute_indices, set2=all_indices) | ||
|
||
# remove original force, add new forces | ||
new_system.removeForce(force_index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you want to leave in the original force so you don't have to copy all the exceptions (nonzero 1-4 interactions) to a CustomBondForce.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay!
# create copies for each interaction. Only half in solute/solute as we double count. | ||
nb_only_solvent_solvent = nb_force | ||
nb_only_solvent_solute = clone_nonbonded_parameters(nb_force) | ||
nb_only_solute_solute = clone_nonbonded_parameters(nb_force,energy_prefactor='0.5*') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would you multiply the energy by 0.5?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mistakenly assumed double-counting -- will revert
# Remove solute-solute interactions | ||
for i in solute_indices: | ||
for j in solute_indices: | ||
nb_only_solvent_solvent.addException(i, j, 0, 0, 0, replace=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will probably be slow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May I suggest itertools.product(solute_indices, repeat=2)
instead of the nested for
? Nothing to do with performance but I'd say it's prettier ✨
|
||
# surrogate could deviate in functional form from the NonbondedForce defaults (e.g. using soft-core) | ||
surrogate_energy_expression = default_energy_expression | ||
half_surrogate_energy_expression = '0.5*' + surrogate_energy_expression |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why use a factor of 0.5?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mistakenly assumed double-counting -- will revert
Thanks! |
It's probably a good idea to make sure the total potential energy matches the unmodified system pretty closely! |
This test is currently failing, but we're aiming to match within the same tolerance as the alchemical factories openmmtools/openmmtools/tests/test_forcefactories.py Lines 201 to 210 in be65ec6
|
It's probably much simpler just to compare the potential energy. |
Description
Intention: Efficient implementations of force factories for splitting solvent-solvent interactions from other interactions, for use in multiple-timestepping schemes.
Status
Incomplete. Currently the splitter using exceptions and the splitter using interaction groups are both giving pretty big force errors, and the one using subtraction is giving forces that agree within a very tight tolerance with the original system. However, dynamics with the one using subtraction is unstable at 2fs...
CC'ing @c-matthews and @jchodera
Todos
CutoffPeriodic
nonbonded method