-
Notifications
You must be signed in to change notification settings - Fork 183
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
Tests and Bugfixes for the GB potential #3091
Tests and Bugfixes for the GB potential #3091
Conversation
Codecov Report
@@ Coverage Diff @@
## python #3091 +/- ##
=======================================
+ Coverage 83% 83% +<1%
=======================================
Files 530 530
Lines 26100 26102 +2
=======================================
+ Hits 21915 21919 +4
+ Misses 4185 4183 -2
Continue to review full report at Codecov.
|
So far we've always used analytical solutions to calculate reference forces. Using a numerical approximation of the gradient is an interesting approach. I'm actually surprised that forces calculated with an integral step of 2e-7 can pass a After re-organizing my version of the force function to match the nomenclature of the variables in the energy function, I still can't follow the force code. For example, in the calculation of epsilon, at line: espresso/src/core/nonbonded_interactions/gay_berne.hpp Lines 70 to 72 in d79e9c1
I would expect variable E2 to be raised to the power of mu - 1 in a subsequent variable to evaluate the derivative (d epsilon / d r), but I can't find it. It would be very helpful if we had the formula of the GB force, possibly with the intermediate steps to obtain it from the derivative of energy. We could write them with LaTeX in a Doxygen page, like we did for the derivation of the bond angle force.
|
I saw that two of them failed. This one failed because the reaction_ensemble test had a timeout. The second one failed because of different timeouts and fails, non of which was the interactions_non-bonded.py. Do you know why those failed?
I think this way testing derivatives can be very powerful, if the analytical solution is long or complicated. Although it is much slower to calculate the derivative this way, it is not so prone to error. To advertise the approach a little bit more: If I had just implemented the same analytical solution used in the c++ code for testing I would not have found the error. I borrowed the idea from machine learning, see here and here.
It is a little bit confusing. The change in power comes with this line:
And with this line:
And also with these lines: espresso/src/core/nonbonded_interactions/gay_berne.hpp Lines 89 to 90 in d79e9c1
If you want I can send you my jupyter notebook (using python 3) or the python script, where I did the calculations of the derivative.
The problem is that I do not know what paper the orginal author used, so I can't cite anything. I will try to work out a new nomenclatur for the problem and then we can put it in latex code, if you want. |
* add extra intermediate variables * use same variable names for identical or very similar intermediate quantities in the force/energy kernels * simplify code logic with vector/scalar utility functions
The non-amd tests are known to sometimes false trigger, that's why we don't run them automatically. The gradient approach seems to work, though. Your UFLDL link states that an epsilon of 1e-4 will usually provide results at 4 digits precision, but in my experience a test is safer when the reference force is at least one order of magnitude more precise than the test threshold delta. Maybe @KaiSzuttor can comment on that. The book or article used by the original author is unknown, all we know is this code is 16 years old. Given the notation in the energy function and the LaTeX formula in the docs, I would bet on Cleaver et al. 1996, equations 3-4 and 7-9. Here is my modified version of the GB force function. Although it looks more verbose, when compiled with |
Okay, I will change the epsilon of my force calculation and update the pull request.
I worked on a better nomenclature just now too. If it is okay with you I would combine my version with yours and we see how it fits. What do you think? |
I can't attach the files here, because the file type is not supported by github. I will send them to you by mail. |
I think you're version is the best we can do. Can you just add the changed version to my pull request or should I do so? |
I added a commit that changes the delta value to 1x10E-6. For some reason it does not show here yet. |
You can use my version. The simplest way to do it is to merge my branch into your branch (this is a trivial fast-forward), then add the new commit that changes the precision. Doing it the other way around (adding the precision commit, then merging my branch) would require a complex merge commit. Also, I would not change delta to a bigger value, instead I would change epsilon to 1x10E-8. |
You probably forgot to push the new commit to the GitHub repository. If it's ok with you, I can add my new version into your branch on GitHub. Then on you computer, you'll have to discard the precision commit (for example with |
No, it is already pushed. I'll merge your commit, change the delta and epsilon and push again. |
The value of 1x10E-8 does not work, probably because of the numerical errors mentioned in the UFLDL link . I think 1x10E-7 is the lowest we can go here. Therefore I would recommend changing the delta value to 1x10E-6. Is that fine with you or not? |
testsuite/python/tests_common.py
Outdated
@@ -596,6 +596,20 @@ def gay_berne_potential(r_ij, u_i, u_j, epsilon_0, sigma_0, mu, nu, k_1, k_2): | |||
return 4. * epsilon * (rr**-12 - rr**-6) | |||
|
|||
|
|||
def calc_derivative(func, x, eps=1.0e-7, index=None): |
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.
could you please use scipy.misc.derivative
. If that does not suit your needs you should definitely add a docstring to this function. Actually we could even use sympy
. But we probably don't want to depend on that.
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 will add a docstring. scipy.misc.derivative does not allow for a multidimensional input.
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 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.
Does that help? I need to manipulate the element at a specific index while the rest stays the same.
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 added a docstring. I could have thrown an error if someone gives a multidimensional input and index=None, but I think it would be a "overkill". In the docstring it is stated, that the index needs to be specified if x is an array.
I've just discussed it with Kai, and we're both fine with a larger delta. |
Thanks for the update. |
bors r+ |
3091: Tests and Bugfixes for the GB potential r=jngrad a=Kischy Fixes #2922 Description of changes: - Added tests for the gb potential for the force and torque - Fixed bugs in gay_berne.hpp - Removed condition in gay_berne.hpp PR Checklist ------------ - [x] Tests? - [ ] Interface - [x] Core - [ ] Docs? Co-authored-by: Christian Kischy Haege <[email protected]> Co-authored-by: Jean-Noël Grad <[email protected]> Co-authored-by: Christian Haege <[email protected]>
…/espresso into Bugfix_Tests_Gay_Berne_Issue_2922
Canceled |
I was not yet done... |
I think we should have all reviewers approve the PR before merging |
You changed the interface of the gradient function so that Could you also update the Docstring? |
the scope of the function is limited to |
That's why I thought that it doesn't matter.
No |
I thought it's just more readable |
Yeah, you are right. |
Can you exchange every "derivative" with "gradient" in the Docstring? I think than we are done. :) |
sorry for the long discussion, but I think we overall improved readability. Thanks for your contribution! |
@KaiSzuttor I like your implementation of the gradiant function, it is quite compact. However it might be slower, which does not matter in this case. Just keep that in mind, if you ever use it heavily somewhere else. |
Yes, it looks better now. Thank you. I'm glad I could help. And no worries about the discussion. |
Why? |
There will be one lambda for each call to the function. That will make it slower in comparison. I shouldn't have brought it up, because it does not matter. |
bors r+ |
3091: Tests and Bugfixes for the GB potential r=KaiSzuttor a=Kischy Fixes #2922 Description of changes: - Added tests for the gb potential for the force and torque - Fixed bugs in gay_berne.hpp - Removed condition in gay_berne.hpp PR Checklist ------------ - [x] Tests? - [ ] Interface - [x] Core - [ ] Docs? Co-authored-by: Christian Kischy Haege <[email protected]> Co-authored-by: Jean-Noël Grad <[email protected]> Co-authored-by: Christian Haege <[email protected]> Co-authored-by: Kai Szuttor <[email protected]>
Build succeeded |
Fixes #2922
Description of changes:
PR Checklist