-
Notifications
You must be signed in to change notification settings - Fork 34
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
Add force support for HarmonicTorsion
#363
Conversation
@SHervoe-Hansen is the force calculation consistent with what you derived? |
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.
It is overall consistent yes, however, I am fearing there is a sign error that cancels out since all tests pass.
src/bonds.cpp
Outdated
if (cosine_angle > 1.0) { // is this needed? | ||
cosine_angle = 1.0; | ||
} else if (cosine_angle < -1.0) { | ||
cosine_angle = -1.0; |
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 don't understand the need of these lines.
src/bonds.cpp
Outdated
sine_angle = std::numeric_limits<double>::epsilon(); | ||
} | ||
const auto angle = std::acos(cosine_angle); | ||
const auto du_dangle = 2.0 * half_force_constant * (angle - equilibrium_angle); |
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.
minus sign missing.
F = - dU/dr
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 it's just the direction of the vector (01 vs 10). I checked flipping the sign, and see large differences compared to MC.
src/bonds.cpp
Outdated
} | ||
const auto angle = std::acos(cosine_angle); | ||
const auto du_dangle = 2.0 * half_force_constant * (angle - equilibrium_angle); | ||
auto force0 = du_dangle / sine_angle * d01_inv * (r21 * d21_inv - r01 * d01_inv * cosine_angle); |
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.
In more Eigen friendly manner we could maybe write it as:
force0 = du_dangle / r01 * norm(10x(10x12))
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.
Note the cross product of vector 10 and 12 is used in both expressions so maybe calculate that first and take the norm of the cross product between the newly calculated vector and the vector required.
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 might be faster as it uses one less trigonometric function (sqrt) in exchange of multiplications. However, your suggestion gives NaN and ctest -R unittests -V
fails. Would you be willing to double-check with the current code?
src/bonds.cpp
Outdated
const auto angle = std::acos(cosine_angle); | ||
const auto du_dangle = 2.0 * half_force_constant * (angle - equilibrium_angle); | ||
auto force0 = du_dangle / sine_angle * d01_inv * (r21 * d21_inv - r01 * d01_inv * cosine_angle); | ||
auto force2 = du_dangle / sine_angle * d21_inv * (r01 * d01_inv - r21 * d21_inv * cosine_angle); |
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.
force2 = du_dangle / r12 * norm(21x(10x12))
Thanks, the cross-product code works in Debug mode only, but fails on both GCC and Clang if with RelWithDebMode. I tried updating Eigen from 3.3.7 --> 3.3.9 but to no avail. I kept the code, but enclosed it in a |
@SHervoe-Hansen in the unittest, |
We are partly saved because of my poor memory in terms of vector notation: like we wanted to use the vector ab = b - a however I had named it ba so we might gain our sign cancelation from that. I will go over the math and code ones more in the near future! |
I have been testing for more odd behaviour, it turns out the debug only code can run in release mode if you insert std::cout << force0; and std::cout << force2 before the calculation of force1, which I can only associate with uninitialised variable behaviour. |
I think we just ran into one of Eigen's common pitfalls :-) Fixed in latest commit. Still a bit worried about the force sign more generally in Faunus (bonds, pair potential). |
Let me do a worked out example for unit testing and such that we can compare and I will also check the code for the angular potential. It seems the major problem is the correct usage of the |
Direction of force vector was unclear this commit brings renaming to explicitly give directions of input arguments and calculated forces. Unit test for NewCoulomb is also added. It seems OK, but the documentation in the external CoulombGalore library may need updating
Yes, good idea with more unittests. I made a commit clarifying both |
The commit 4e34050 now reflects the addition of a unit test checking the direction of the force vectors to be correct. The unit test system is illustrated here. The angular harmonic potential now passes this test. Agreement between MC and MD however still remains to be tested in addition to the speed of the two implementations. |
Now |
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 code and physics now match and passes all tests. Ready for merge.
This adds force support for
HarmonicTorsion
and includes some cleanup ofBondData
and force evaluation.bend
example for MD/MC testing of harmonic bonds and anglesBondData
refactoring