Closed jchodera closed 8 years ago
Great catch! The parameter had previously been named lambda_coulomb
, but I migrated later to be more consistent and must have missed this.
In general, I think it is very easy to introduce this kind of bugs when passing arguments as kwargs without any type of checking (as we do in AlchemicalState). I usually prefer sticking to normal named_argument=default unless absolutely necessary.
In this case, we definitely want these arguments to be optional, since we want to be able to (1) only specify arguments that are not pinned to 1.0, and (2) add arguments without breaking existing code. But I should have inserted a check that made sure that no unknown arguments were provided to AlchemicalState
.
After correcting the lambda_coulomb to lambda_electrostatics thing, this is ready to be merged for me!
Do you want to tackle that, or should I?
Do you want to tackle that, or should I?
Oh, nevermind! This is my PR, so I'll fix it!
Thanks again!
Hm, I am still only seeing the water box tests failing.
If you have a chance, could you give a bit more info about the new failures you saw? Did you make additional changes beyond changing lamda_coulomb? Or did you test on CUDA/OpenCL?
Oh! Nevermind---I didn't actually add the check that throws an exception in test_annihilated_states
. Thanks!
OK, I can confirm I see this discrepancy. This is with CutoffPeriodic
:
2016-08-13 09:42:49,785: Creating alchemically modified system...
2016-08-13 09:42:49,797: Elapsed time 0.012 s.
2016-08-13 09:42:49,797: Creating alchemically modified intermediate...
2016-08-13 09:42:49,800: Elapsed time 0.003 s.
2016-08-13 09:42:49,803: Creating alchemically modified system...
2016-08-13 09:42:49,812: Elapsed time 0.009 s.
2016-08-13 09:42:49,812: Creating alchemically modified intermediate...
2016-08-13 09:42:49,815: Elapsed time 0.003 s.
2016-08-13 09:42:50,018: vacuum lambda = 1 : 2.999 kcal/mol
2016-08-13 09:42:50,018: vacuum lambda = 0 : 0.168 kcal/mol
2016-08-13 09:42:50,018: difference : 2.831 kcal/mol
2016-08-13 09:42:50,018: periodic lambda = 1 : 1.337 kcal/mol
2016-08-13 09:42:50,018: periodic lambda = 0 : 0.168 kcal/mol
2016-08-13 09:42:50,018: difference : 1.169 kcal/mol
The lambda = 0
state has the same energy between NoCutoff
and CutoffPeriodic
, but the lambda = 1
state does not.
For PME
, we recover the same energies at lambda = 0
and lambda = 1
, however:
2016-08-13 09:46:29,330: Creating alchemically modified system...
2016-08-13 09:46:29,343: Elapsed time 0.013 s.
2016-08-13 09:46:29,344: Creating alchemically modified intermediate...
2016-08-13 09:46:29,347: Elapsed time 0.003 s.
2016-08-13 09:46:29,349: Creating alchemically modified system...
2016-08-13 09:46:29,358: Elapsed time 0.008 s.
2016-08-13 09:46:29,358: Creating alchemically modified intermediate...
2016-08-13 09:46:29,363: Elapsed time 0.005 s.
2016-08-13 09:46:29,734: vacuum lambda = 1 : 2.999 kcal/mol
2016-08-13 09:46:29,734: vacuum lambda = 0 : 0.168 kcal/mol
2016-08-13 09:46:29,735: difference : 2.831 kcal/mol
2016-08-13 09:46:29,735: periodic lambda = 1 : 2.999 kcal/mol
2016-08-13 09:46:29,735: periodic lambda = 0 : 0.168 kcal/mol
2016-08-13 09:46:29,735: difference : 2.831 kcal/mol
It looks like the energy discrepancy in the fully-interacting state is due to a shift that is applied for reaction-field electrostatics. Reaction-field uses this equation, which adds a term like
E_shift = - ONE_4PI_EPS0 * q_i * q_j * c_rf
where for epsilon_solvent = 1
, c_rf
just goes to r_cutoff^(-3)
, meaning we have a shift of
E_shift = - ONE_4PI_EPS0 * q_i * q_j / r_cutoff^3
Now, the problem is that we scale the charges down to 0, meaning this shift goes away, causing a discrepancy in the energy difference from lambda = 1 -> 0
between vacuum and reaction field. The question is whether this discrepancy should remain or not.
In principle, reaction field models the effects of solvent outside the cutoff, so unless we take r_cutoff -> infinity
(in which case the shift vanishes), we will see this effect, which may be something we should really be including.
So I think this is actually a correct effect to include. Making the cutoff larger or eliminating c_rf
eliminates the discrepancy.
The OpenMM bug was fixed in https://github.com/pandegroup/openmm/pull/1561
I've noticed that in several points in
test_alchemy.py
we uselambda_coulomb
instead oflambda_electrostatics
. When I switched the two intest_annihilated_states()
, I got differences that can explain what happens with solvation free energies! I'll have some time to verify this on Tuesday/Wednesday.In general, I think it is very easy to introduce this kind of bugs when passing arguments as
kwargs
without any type of checking (as we do inAlchemicalState
). I usually prefer sticking to normalnamed_argument=default
unless absolutely necessary.After correcting the
lambda_coulomb
tolambda_electrostatics
thing, this is ready to be merged for me!