70#include "math/Factorials.hpp"
71#include "utils/Constants.hpp"
73#ifndef NONBONDED_SLATERINTEGRALS_HPP
74#define NONBONDED_SLATERINTEGRALS_HPP
81inline T mod(T x, T m) {
82 return x < 0 ? m - 1 - ((-x) - 1) % m : x % m;
101inline RealType RosenA(
int n, RealType a) {
102 RealType RosenA_ = 0.;
106 for (
int nu = 1; nu <= n; nu++) {
110 RosenA_ = (RosenA_ / Term) * (exp(-a) / a);
130inline RealType RosenB(
int n, RealType alpha) {
135 bool IsPositive =
true;
140 RealType PSinhRosenA = exp(alpha) - exp(-alpha);
141 RealType PCoshRosenA = -exp(alpha) - exp(-alpha);
142 RealType TheSum = PSinhRosenA;
143 RealType PHyperRosenA;
144 for (
unsigned nu = 1; nu <= (unsigned)n; nu++) {
146 PHyperRosenA = PCoshRosenA;
150 PHyperRosenA = PSinhRosenA;
154 TheSum += Term * PHyperRosenA;
156 RosenB_ = TheSum / (alpha * Term);
159 printf(
"WARNING, a = 0 in RosenB\n");
160 RosenB_ = (1. - pow(-1., n)) / (n + 1.);
175inline RealType RosenD(
int m,
int n,
int p) {
176 if (m + n + p > maxFact) {
177 printf(
"Error, arguments exceed maximum factorial computed %d > %d\n",
182 RealType RosenD_ = 0;
183 for (
int k = max(p - m, 0); k <= min(n, p); k++) {
185 RosenD_ += (fact[m] / (fact[p - k] * fact[m - p + k])) *
186 (fact[n] / (fact[n - k] * fact[k]));
188 RosenD_ -= (fact[m] / (fact[p - k] * fact[m - p + k])) *
189 (fact[n] / (fact[n - k] * fact[k]));
206inline RealType sSTOCoulInt(RealType a, RealType b,
int m,
int n, RealType R) {
208 RealType Factor1, Factor2, Term, OneElectronTerm;
213 RealType epsilon = 0.;
219 RealType sSTOCoulInt_ = 0.;
221 std::numeric_limits<RealType>::epsilon())
226 RealType Term1 = fact[2 * m - 1] / pow(2 * a, 2 * m);
228 for (
int nu = 1; nu <= 2 * n; nu++) {
229 Term2 += nu * pow(2 * b, 2 * n - nu) * fact[2 * (m + n) - nu - 1] /
230 (fact[2 * n - nu] * 2 * n * pow(2 * (a + b), 2 * (m + n) - nu));
232 sSTOCoulInt_ = pow(2 * a, 2 * m + 1) * (Term1 - Term2) / fact[2 * m];
256 OneElectronTerm = 1. / R +
257 pow(x, 2 * m) / (fact[2 * m] * R) *
258 ((x - 2 * m) * RosenA(2 * m - 1, x) - exp(-x)) +
260 eps = epsilon / OneElectronTerm;
263 Factor1 = -a * pow(a * R, 2 * m) / (n * fact[2 * m]);
264 for (
int nu = 0; nu <= 2 * n - 1; nu++) {
265 Factor2 = (2. * n - nu) / fact[nu] * pow(a * R, nu);
266 epsi = eps / fabs(Factor1 * Factor2);
268 for (
int p = 0; p <= m + (nu - 1) / 2; p++) {
269 Term = RosenD(2 * m - 1, nu, 2 * p) / (2. * p + 1.) *
270 RosenA(2 * m + nu - 1 - 2 * p, x);
272 if ((Term > 0) && (Term < epsi))
goto label1;
274 sSTOCoulInt_ += K2 * Factor2;
277 sSTOCoulInt_ *= Factor1;
279 Factor1 = -a * pow(a * R, 2 * m) / (2. * n * fact[2 * m]);
280 epsi = eps / fabs(Factor1);
282 printf(
"WARNING: b = 0 in sSTOCoulInt\n");
285 for (
int nu = 0; nu <= 2 * n - 1; nu++) {
287 for (
int p = 0; p <= 2 * m + nu - 1; p++)
288 K2 = K2 + RosenD(2 * m - 1, nu, p) * RosenB(p, R * (a - b)) *
289 RosenA(2 * m + nu - 1 - p, R * (a + b));
290 Term = K2 * (2 * n - nu) / fact[nu] * pow(b * R, nu);
291 sSTOCoulInt_ += Term;
292 if (fabs(Term) < epsi)
goto label2;
295 sSTOCoulInt_ *= Factor1;
299 sSTOCoulInt_ += OneElectronTerm;
317inline RealType sSTOOvInt(RealType a, RealType b,
int m,
int n, RealType R) {
318 RealType Factor, Term, eps;
322 RealType epsilon = 0.;
323 RealType sSTOOvInt_ = 0.;
326 Factor = pow(a * R, m + n + 1) / sqrt(fact[2 * m] * fact[2 * n]);
327 eps = epsilon / fabs(Factor);
328 for (
int q = 0; q <= (m + n) / 2; q++) {
329 Term = RosenD(m, n, 2 * q) / (2. * q + 1.) * RosenA(m + n - 2 * q, a * R);
331 if (fabs(Term) < eps) exit(0);
333 sSTOOvInt_ *= Factor;
335 Factor = 0.5 * pow(a * R, m + 0.5) * pow(b * R, n + 0.5) /
336 sqrt(fact[2 * m] * fact[2 * n]);
337 eps = epsilon / fabs(Factor);
338 for (
int q = 0; q <= m + n; q++) {
339 Term = RosenD(m, n, q) * RosenB(q, R / 2. * (a - b)) *
340 RosenA(m + n - q, R / 2. * (a + b));
342 if (fabs(Term) < eps) exit(0);
344 sSTOOvInt_ *= Factor;
361inline RealType KinInt(RealType a, RealType b,
int m,
int n, RealType R) {
362 RealType KinInt_ = -0.5 * b * b * sSTOOvInt(a, b, m, n, R);
365 b * b * pow(2 * b / (2 * b - 1), 0.5) * sSTOOvInt(a, b, m, n - 1, R);
367 KinInt_ += pow(n * (n - 1) / ((n - 0.5) * (n - 1.5)), 0.5) *
368 sSTOOvInt(a, b, m, n - 2, R);
385inline RealType sSTOCoulIntGrad(RealType a, RealType b,
int m,
int n,
392 RealType sSTOCoulIntGrad_ = 0.;
395 printf(
"WARNING: argument given to sSTOCoulIntGrad is 0\n");
396 printf(
"a = %lf R= %lf\n", a, R);
401 for (
int nu = 0; nu <= 2 * (n - 1); nu++) {
403 for (
int p = 0; p <= (m + nu) / 2; p++)
404 K2 += RosenD(2 * m - 1, nu + 1, 2 * p) / (2 * p + 1.) *
405 RosenA(2 * m + nu - 1 - 2 * p, x);
406 TheSum += (2 * n - nu - 1) / fact[nu] * pow(a * R, nu) * K2;
409 -pow(a, 2 * m + 2) * pow(R, 2 * m) / (n * fact[2 * m]) * TheSum;
411 for (
int nu = 0; nu <= 2 * n - 1; nu++) {
413 for (
int p = 0; p <= (m + nu - 1) / 2; p++)
414 K2 += RosenD(2 * m - 1, nu, 2 * p) / (2 * p + 1.) *
415 RosenA(2 * m + nu - 2 * p, x);
416 TheSum += (2 * n - nu) / fact[nu] * pow(a * R, nu) * K2;
419 2 * pow(a, 2 * m + 2) * pow(R, 2 * m) / (n * fact[2 * m]) * TheSum;
423 RealType y = R * (a + b);
424 RealType z = R * (a - b);
426 for (
int nu = 0; nu <= 2 * n - 1; nu++) {
428 for (
int p = 0; p <= 2 * m + nu; p++)
429 K2 += RosenD(2 * m - 1, nu + 1, p) * RosenB(p, z) *
430 RosenA(2 * m + nu - p, y);
431 TheSum += (2 * n - nu - 1) / fact[nu] * pow(b * R, nu) * K2;
433 sSTOCoulIntGrad_ = -b * pow(a, 2 * m + 1) * pow(R, 2 * m) /
434 (2 * n * fact[2 * m]) * TheSum;
436 for (
int nu = 0; nu <= 2 * n; nu++) {
438 for (
int p = 0; p <= 2 * m - 1 + nu; p++)
439 K2 += RosenD(2 * m - 1, nu, p) *
440 ((a - b) * RosenB(p + 1, z) * RosenA(2 * m + nu - p - 1, y) +
441 (a + b) * RosenB(p, z) * RosenA(2 * m + nu - p, y));
442 TheSum += (2 * n - nu) / fact[nu] * pow(b * R, nu) * K2;
445 pow(a, 2 * m + 1) * pow(R, 2 * m) / (2 * n * fact[2 * m]) * TheSum;
448 sSTOCoulIntGrad_ = sSTOCoulIntGrad_ - (2. * m + 1.) / sqr(R) +
449 2. * m / R * sSTOCoulInt(a, b, m, n, R) +
450 pow(x, 2 * m) / (fact[2 * m] * sqr(R)) *
451 ((2. * m + 1.) * exp(-x) +
452 2. * m * (1. + 2. * m - x) * RosenA(2 * m - 1, x));
454 return sSTOCoulIntGrad_;
469inline RealType sSTOOvIntGrad(RealType a, RealType b,
int m,
int n,
472 RealType sSTOOvIntGrad_ = (m + n + 1.) / R * sSTOOvInt(a, b, m, n, R);
475 RealType TheSum = 0.;
478 for (
int q = 0; q <= (m + n) / 2; q++)
480 RosenD(m, n, 2 * q) / (2 * q + 1.) * RosenA(m + n - 2 * q + 1, x);
482 a * pow(x, m + n + 1) / sqrt(fact[2 * m] * fact[2 * n]) * TheSum;
485 RealType y = 0.5 * R * (a + b);
486 RealType z = 0.5 * R * (a - b);
487 for (
int q = 0; q < m + n; q++)
488 TheSum = TheSum + RosenD(m, n, q) *
489 ((a - b) * RosenB(q + 1, z) * RosenA(m + n - q, y) +
490 (a + b) * RosenB(q, z) * RosenA(m + n - q + 1, y));
491 sSTOOvIntGrad_ -= 0.25 *
492 sqrt((pow(x, 2 * m + 1) * pow(w, 2 * n + 1)) /
493 (fact[2 * m] * fact[2 * n])) *
496 return sSTOOvIntGrad_;
506inline RealType getSTOZeta(
int n, RealType hardness) {
510 RealType epsilon = 1.0e-8;
513 return pow(sSTOCoulInt(1., 1., n, n, epsilon) / hardness,
514 -1. / (3. + 2. * n));
527inline RealType sSTDCoulSF(RealType a, RealType b, RealType R, RealType Rc) {
529 RealType a4 = a2 * a2;
531 RealType b4 = b2 * b2;
532 RealType apb = a + b;
533 RealType a2b23 = pow(a2 - b2, 3);
535 RealType term1 = 2.0 * exp(R * apb) * a2b23;
536 RealType term2 = exp(R * b) * b4 * (b2 * (2.0 + R * a) - a2 * (6.0 + R * a));
537 RealType term3 = -exp(R * a) * a4 * (a2 * (2.0 + R * b) - b2 * (6.0 + R * b));
539 RealType denom = 2.0 * R * a2b23;
540 RealType numer = exp(-R * apb) * (term1 + term2 + term3);
542 RealType S = numer / denom;
544 term1 = 2.0 * exp(Rc * apb) * a2b23;
545 term2 = exp(Rc * b) * b4 * (b2 * (2.0 + Rc * a) - a2 * (6.0 + Rc * a));
546 term3 = -exp(Rc * a) * a4 * (a2 * (2.0 + Rc * b) - b2 * (6.0 + Rc * b));
548 numer = exp(-Rc * apb) * (term1 + term2 + term3);
549 denom = 2.0 * Rc * pow(a2 - b2, 3);
551 RealType Sc = numer / denom;
553 term1 = -2.0 * exp(3 * Rc * a + 4 * Rc * b) * a2b23;
554 term2 = exp(2.0 * Rc * (a + 2.0 * b)) * b4 *
555 (a2 * (6.0 + Rc * a * (6.0 + Rc * a)) -
556 b2 * (2.0 + Rc * a * (2.0 + Rc * a)));
557 term3 = exp(3.0 * Rc * apb) * a4 *
558 (a2 * (2.0 + Rc * b * (2.0 + Rc * b)) -
559 b2 * (6.0 + Rc * b * (6.0 + Rc * b)));
561 numer = exp(-3.0 * Rc * a - 4.0 * Rc * b) * (term1 + term2 + term3);
562 denom = 2.0 * Rc * Rc * a2b23;
564 RealType Scp = numer / denom;
566 return S - Sc - Scp * (R - Rc);
578inline RealType sSTDCoulSF(RealType a, RealType R, RealType Rc) {
580 (-48.0 + 48.0 * exp(R * a) - R * a * (33.0 + R * a * (9.0 + R * a)));
582 (-48.0 + 48.0 * exp(Rc * a) - Rc * a * (33.0 + Rc * a * (9.0 + Rc * a)));
584 RealType S = exp(-R * a) * poly / (48.0 * R);
585 RealType Sc = exp(-Rc * a) * polyc / (48.0 * Rc);
588 (48.0 - 48.0 * exp(Rc * a) +
589 Rc * a * (4.0 + Rc * a) * (12.0 + Rc * a * (3.0 + Rc * a)));
590 RealType Scp = exp(-Rc * a) * poly2c / (48.0 * Rc * Rc);
592 return S - Sc - Scp * (R - Rc);