-
Notifications
You must be signed in to change notification settings - Fork 150
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
Added C API option to call gradient calculations on point charges #584
Conversation
Signed-off-by: Felix Pultar <[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.
Thanks for sharing.
I think this makes a nice addition, however we need proper error checking in the API. Also, I have a hard time believing that the proposed implementation is actually working, since the function prototype is not matching the implementation (a unit test would be really nice).
Further, I'm not completely happy with the design, the point charge gradient should probably be queried from the results object rather than the calculator. Instead of passing the calculator it would be prudent to extend the single point procedure to save the point charge gradient in the results object and write a simple query to return the point charge gradient from there.
I understand your concern and agree we should add also a unit test, I'll set up something. Speaking of which, is there a reason that the API is only being tested with Intel's compiler? Line 17 in 9908849
|
That's an artifact to avoid testing GCC / Apple-Clang mixtures on MacOS because Apple-Clang would run into problems with missing the OpenMP runtime, however I don't recall the reason why I checked for Intel rather than using the former condition. |
Thank you, I will extend the test to GCC then once it is implemented correctly from the Fortran side. Another question about your second point. I agree that it is better to store gradients on point charges in the result object. I actually found the point charge gradients might otherwise be 0 when called via the double pcgrad[npc*7] =
{1.0, 2.0, 3.0,
1.0, 2.0, 3.0,
1.0, 2.0, 3.0,
1.0, 2.0, 3.0,
1.0, 2.0, 3.0,
1.0, 2.0, 3.0,
1.0, 2.0, 3.0}; Maybe the Just to summarize the necessary steps to do it in line with other API functions (assuming I started fresh from branch I would need to (1) adapt the function prototype in /// Query singlepoint results object for pc gradient in Hartree / Bohr
extern XTB_API_ENTRY void XTB_API_CALL
xtb_getPCGradient(xtb_TEnvironment /* env */,
xtb_TResults /* res */,
double* /* gradient [natoms][3] */) XTB_API_SUFFIX__VERSION_1_0_0; (2) add (3) implement the subroutine in the same file in an identical fashion to (4) in Would I also need to add Line 28 in 7dd7710
This is the code area where I would have gotten the calculation results from. However, in my minimal example, the if statement is evaluated as Line 190 in 7dd7710
I am not sure, however, if I need to change the signature of the |
Signed-off-by: Felix Pultar <[email protected]>
I added your suggested changes for now while I am working on the cleaner solution that goes via storing the results in a results object and querying them from there. In the meantime, I added a minimal working example as proof of concept: https://github.com/pultar/xtb-example I will also implement the unit test in a similar way. |
Signed-off-by: Felix Pultar <[email protected]>
Signed-off-by: Felix Pultar <[email protected]>
Signed-off-by: Felix Pultar <[email protected]>
Signed-off-by: Felix Pultar <[email protected]>
Signed-off-by: Felix Pultar <[email protected]>
I think I refactored everything the way you described it. The minimal example prints the expected gradients: https://github.com/pultar/xtb-example/tree/point_charges_refactoring I included gcc and clang for the C API test and also added my minimal example to it. All tests pass with cmake / make (Mac OS X with gcc-9 and CentOS 7 with gcc-8.2.0). However, if the tests are built with meson / ninja the assert in my test fails because the whole point charge array is filled with zeros. I made xtb more verbose (1e7d11a) and found that when I run the created test binary directly, everything is as expected. Do you have any idea what could cause this behavior? |
test/api/c_api_example.c
Outdated
int numbers[32] = { | ||
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, | ||
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, | ||
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, | ||
99, 99}; |
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 chemical hardness for element 99 (Es) is not defined with neither GFN1-xTB nor GFN2-xTB and will therefore be zero leading to an infinity and therefore removing the interaction with the external charges effectively from the calculation.
Usually we use 7 (nitrogen) as dummy element for external charges.
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 chemical hardness for element 99 (Es) is not defined with neither GFN1-xTB nor GFN2-xTB and will therefore be zero leading to an infinity and therefore removing the interaction with the external charges effectively from the calculation.
Usually we use 7 (nitrogen) as dummy element for external charges.
I was taking the value from this page of the docs: https://github.com/grimme-lab/xtb_docs/blob/main/source/pcem.rst
For future reference, is nitrogen your general recommendation if one does not know where the point charges come from?
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.
They are no real point charges, rather Slater like densities parametrized with a hardness. Setting the hardness to a large value makes them point charge like.
There is a subtle issue there, we specify element symbols to get the hardness of the element, however if a number is given it is taken as hardness in Eh/e^2. In the API we don't bother dealing with strings and therefore use atomic numbers to identify elements, this leaves no room for overwriting the hardness for each element.
Recommendations are always difficult, we try to choose something that doesn't break most of the time, whatever this meant when the original implementation was done. For an actual calculation you should carefully check whether the hardnesses provided by the method work, you can use a stub hardness or better go for a point charge like behavior.
I noticed that the gradient norm is huge with a value of 14.0 Eh/a0, this is usually not wanted for tests because systems far away from the equilibrium will introduce some instability in the SCF solution. Since the repulsion energy with 26.7 Eh is also huge I would presume the cartesian coordinates are provided in Ångström rather than in Bohr, right? |
Signed-off-by: Felix Pultar <[email protected]>
Signed-off-by: Felix Pultar <[email protected]>
Nice catch, I copied the results from an orca calculation and forgot to change the units. The tests are running through now. I don't understand though how this can be dependent on the build system used. Is the rest of my code correct and in line with the rest of the code base and design you had in mind? I hope I didn't oversee a check for allocation etc. |
Signed-off-by: Felix Pultar <[email protected]>
I have no idea why it only shows up with meson, but that is the reason why we do testing on multiple platforms and build systems to also catch corner cases. One possible cause for the CMake build to pass would be the |
I see - I was worried I had introduced a memory leak somewhere. Good to see everything passes now. |
- some whitespace stuff - make use of automatic LHS allocation - initialize pcem member in scc_results
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 for sharing. The implementation looks good to me.
- clang-format for consistency - use TGM for checking values and generating error messages - return status and accumulate over all tests before returning
As of now, the C API of
xtb
does not grant access to functions regarding gradient calculations on point charges. We implemented this feature for our purposes and would like to share this little addition with you.xtb.h
and linking tolibxtb.so.6
Signed-off-by: Felix Pultar [email protected]