-
Notifications
You must be signed in to change notification settings - Fork 189
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
Widom excess chemical potential calculation and RxMC performance improvement #4374
Conversation
Contentwise this looks good. However, we use semantic versioning. I.e., as long as the major version (4 in 4.1.2) is the same, we promise not to change the outcome of a simulation script silently. |
samples/widom_insertion.py
Outdated
np.mean(gamma_samples[block * size_block:(block + 1) * size_block])) | ||
|
||
mu_ex_mean = -1 * np.log(np.mean(gamma_block)) * temperature | ||
mu_ex_std = np.sqrt(np.var(gamma_block) / np.mean(gamma_block)) * temperature |
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.
Please add a note that this is due to linearized error propagation. In principle you can do better via not using linearization: mu_ex_Delta =abs( -1 * np.log(np.mean(gamma_block)+np.std(gamma_block, dof =1)) * temperature -(-1 * np.log(np.mean(gamma_block)-np.std(gamma_block, dof =1)) * temperature)
the excess chemical potential. The error estimate assumes that | ||
your samples are uncorrelated. | ||
|
||
Returns the instantaneous excess chemical potential |
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.
There is no instantaneous chemical potential (which is always an ensemble average, please find a better name), it would also miss the application of -kT log().
If you change the logic of how this function works, please describe the needed computations in the doc string
There is no such thing as an instanteous chemical potential. The chemical potential is per definition an ensemble average. Additionally, the value returned cannot be energy: The application of -kT log is missing (surely because log and the ensemble average do not commute). You could name it compute_exp_of_potential_energy_change_for_excess_chemical_potential_computatiom() which would at be a telling name. |
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 current naming is misleading, please improve
samples/widom_insertion.py
Outdated
@@ -123,7 +123,7 @@ | |||
n_iterations = 5000 | |||
for i in range(n_iterations): | |||
|
|||
mu_ex = widom.calc_instantaneous_chemical_potential(insertion_reaction_id) | |||
E_ins = widom.calc_particle_insertion_potential_energy(insertion_reaction_id) |
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.
consider E_pot_insertion. The inserted particles also carry kinetic energy which is not reported in this observable
|
||
const double mu = E_pot_new - E_pot_old; | ||
const double E_ins = E_pot_new - E_pot_old; |
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 we should avoid abbreviation whenever possible https://medium.com/ltunes/what-is-clean-code-naming-conventions-part-1-426d383eb85d
@jonaslandsgesell I belive I have resolved all your comments, please take a look and let me know if you find anything else |
Thank you for taking care. |
This PR would be a good check for your benchmark PR. What is the performance before/after your suggested change, when running e.g. 10 reactions in a row for 1000 times? |
@jonaslandsgesell I did a performance test with the benchmark script of my PR. Performing 1000 MC reactions steps prior my implementation takes ~ 1.5 s on my laptop. Performing the same number of MC steps with the implementation proposed in this PR takes ~ 0.9 s on my laptop. For a sufficiently large number of reaction steps you gain roughly a factor of 2 in computational time (only in the reaction side, of course). |
Could you please add the unittests which checks if the energy is altered after it is passed in? Then this PR is fine from my side |
Once the comments by Jonas are resolved, it would be nice to rebase the PR. I find it challenging to follow the changes, because the 19 commits alternate between the Widom refactoring and the |
@jonaslandsgesell @jngrad I will try to attend your comments ASAP. Honestly, I have not yet done the unit test because I am unsure on how to implement such test straightforwardly, but I will try to propose something. |
@jngrad , could you please assist in the unittest? It might require refactoring to get something which is easily testable. |
@jonaslandsgesell it took me a while to figure it out how to do it properly, but I managed to implement one unit test in |
@jngrad it is now failing the CI due to some weird error due to an "unexpected indentation in the docstring" in |
For the rebase, it's as simple as # backup current state of the branch
git branch Widom+RxMC_fix_backup
# squash all changes
git reset 5bab6bd51e7 Then do |
Cache the potential energy value. This saves the cost of an energy calculation per loop when running multiple reactions.
Widom now returns the particle insertion potential energy and calculates the excess chemical potential afterwards with block analysis.
8f68795
to
dcd5df8
Compare
@jngrad the PR is now blocked because it does not detect that I did the changes you requested, I belive |
Description of changes:
WidomInsertion.measure_excess_chemical_potential()
was replaced byWidomInsertion.calculate_excess_chemical_potential()
which returns the instantaneous value of the excess chemical potential instead of the accumulated mean and std. The mean value and std of the excess chemical potential must be now be calculated by the user elsewhere. An example of how to do it is given insamples/widom_insertion.py
.ReactionAlgorithm::do_reaction()
now only computes the potential energy of the old state at the begininng of the reaction loop. This value is updated after each successful reaction trial move.