dftlibs / xcfun

XCFun: A library of exchange-correlation functionals with arbitrary-order derivatives
https://dftlibs.org/xcfun/
Mozilla Public License 2.0
58 stars 32 forks source link

xc_derivative_index #83

Closed ilfreddy closed 4 years ago

ilfreddy commented 5 years ago

I am implementing linear response with DFT using XCFun in MRChem. I need to collect the derivatives and combine them. For that purpose, I wanted to make use of the xc_derivative_index function which is declared in xcfun.h and to some extent also documented in readthedocs. Unfortunately the definition is nowhere in the latest version. According to @robertodr, such a function existed but has now been removed. Would it be possible to revert such a change? Was there a reason why it has been removed?

robertodr commented 5 years ago

This searches for int xc_derivative_index in the history and shows at which revisions it was present in xcfun.cpp

git rev-list --all | xargs git grep "int xc_derivative_index" | grep "xcfun.cpp"
uekstrom commented 5 years ago

Hi Luca, I am slowly writing a new version of libtaylor using more modern C++. The derivative_index can be computed at compile time using a constexpr function in C++. I have a attached a C++ header file that you can use like this

include

int my_index = polyinfo::info<3,6>::find({1,2,3}); // this is the index of d/dx d^2/y^2 d^3/dz^3 in a three var degree six polynomial. The inverse function is also implemented as polyinfo::info::exponents().

If you want to guarantee compile time evaluation you can use tricks like template force{ static const int value = I; };

int my_index = force< polyinfo:: blah blah >::value;

Now the XCFun API in in C, so you cannot directly build this into the API but you can use it in MRChem.

Regards, Ulf

Den fre 14 dec. 2018 kl 15:39 skrev Roberto Di Remigio < notifications@github.com>:

This searches for int xc_derivative_index in the history and shows at which revisions it was present in xcfun.cpp

git rev-list --all | xargs git grep "int xc_derivative_index" | grep "xcfun.cpp"

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/dftlibs/xcfun/issues/83#issuecomment-447344451, or mute the thread https://github.com/notifications/unsubscribe-auth/AMeumeauH4UX-2xfc2Bg6uagoyf1rYHfks5u47g2gaJpZM4ZTnTj .

ilfreddy commented 5 years ago

Where is the attached file? Anyway it is not so important to have it at compile time for us. We compute/retrieve derivatives only once in each Response calculation, and such a function, for a linear response calculation, would be called roughly 100 times. So efficiency here is not a primary concern.

uekstrom commented 5 years ago

Aha, I cannot attach files in email replies.. You can also use the function at runtime, but it needs a C interface.

pragma once

include

namespace polyinfo { static constexpr int polylen(int nvar, int ndeg) { int len = 1; for (int k=1;k<=nvar;k++) { len *= ndeg + k; len /= k; } return len; }

template<int K, int N> struct info { static constexpr int size() { int len = 1; for (int k=1;k<=K;k++) { len *= N + k; len /= k; } return len; } // This is the offset of the highest order terms. static constexpr int hi() { return info<K,N-1>::size(); } static constexpr int find(const int expo[K]) { int n = 0; for (int i=0;i<K;i++) n += expo[i]; if (n == 0) return 0; else if (n > N) return -1; else { return polylen(K,n-1) + info<K-1,N>::find(expo+1); } } static constexpr int find(const std::array<int,K> &expo) { return find(expo.data()); } static constexpr std::array<int, K> exponents(int term) { if (term == 0) { return {0}; } else if (term < info<K,N-1>::size()) { return info<K,N-1>::exponents(term); } else { std::array<int, K-1> e = info<K-1,N>::exponents(term - info<K,N-1>::size()); int sum = 0; for (int i=0;i<K-1;i++) sum += e[i]; std::array<int, K> res = {N-sum}; for (int i=0;i<K-1;i++) res[i+1] = e[i]; return res; } } }; template struct info<-1,N> { static constexpr int size() { return 0; } static constexpr int hi() { return 0; } }; template struct info<K,0> { static constexpr int size() { return 1; } static constexpr int hi() { return 0; } static constexpr int find(const int expo[K]) { if (expo[0] < 0 || expo[0] > 0) return -1; else return 0; } static constexpr int find(const std::array<int,K> &expo) { return find(expo.data()); } static constexpr std::array<int, K> exponents(int term) { return {term == 0 ? 0 : -1}; } }; };

Den fre 14 dec. 2018 kl 18:49 skrev Luca Frediani <notifications@github.com

:

Where is the attached file? Anyway it is not so important to have it at compile time for us. We compute/retrieve derivatives only once in each Response calculation, and such a function, for a linear response calculation, would be called roughly 100 times. So efficiency here is not a primary concern.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/dftlibs/xcfun/issues/83#issuecomment-447400730, or mute the thread https://github.com/notifications/unsubscribe-auth/AMeume9kppxNWyRcYYYXCCg8_H-wPwSSks5u4-SygaJpZM4ZTnTj .

robertodr commented 4 years ago

@ilfreddy is this still relevant?

ilfreddy commented 4 years ago

I don't think so