(git:ed6f26b)
Loading...
Searching...
No Matches
grpp_specfunc_gfun.c
Go to the documentation of this file.
1/*----------------------------------------------------------------------------*/
2/* CP2K: A general program to perform molecular dynamics simulations */
3/* Copyright 2000-2025 CP2K developers group <https://cp2k.org> */
4/* */
5/* SPDX-License-Identifier: MIT */
6/*----------------------------------------------------------------------------*/
7
8/*
9 * libgrpp - a library for the evaluation of integrals over
10 * generalized relativistic pseudopotentials.
11 *
12 * Copyright (C) 2021-2023 Alexander Oleynichenko
13 */
14
15/*
16 * Implementation of the Gn(x) auxiliary function.
17 * This function is required to calculate integrals over the 1/r^2 operator.
18 *
19 * More on the Gn(x) function evaluation:
20 * (1) J. 0. Jensen, A. H. Cameri, C. P. Vlahacos, D. Zeroka, H. F. Hameka, C.
21 * N. Merrow, Evaluation of one-electron integrals for arbitrary operators V(r)
22 * over cartesian Gaussians: Application to inverse-square distance and Yukawa
23 * operators. J. Comput. Chem. 14(8), 986 (1993). doi: 10.1002/jcc.540140814 (2)
24 * B. Gao, A. J. Thorvaldsen, K. Ruud, GEN1INT: A unified procedure for the
25 * evaluation of one-electron integrals over Gaussian basis functions and their
26 * geometric derivatives. Int. J. Quantum Chem. 111(4), 858 (2011).
27 * doi: 10.1002/qua.22886
28 */
29#include <math.h>
30#include <string.h>
31
32#ifndef M_PI
33#define M_PI 3.1415926535897932384626433
34#endif
35
36#include "grpp_factorial.h"
37#include "grpp_specfunc.h"
38
39static double gfun_taylor(int n, double x);
40
41/**
42 * Calculates values of the Gn(x) auxiliary function for n = 0, ..., nmax
43 * and stores them into the g[] array.
44 */
45void libgrpp_gfun_values(double x, int nmax, double *g) {
46 memset(g, 0, (nmax + 1) * sizeof(double));
47
48 if (x <= 12.0) {
49 /*
50 * downward recursion
51 */
52 g[nmax] = gfun_taylor(nmax, x);
53
54 for (int n = nmax; n > 0; n--) {
55 g[n - 1] = (1.0 - 2.0 * x * g[n]) / (2.0 * n - 1.0);
56 }
57 } else {
58 /*
59 * upward recursion
60 */
61 double sqrt_x = sqrt(x);
62 g[0] = libgrpp_Dawsons_Integral(sqrt_x) / sqrt_x;
63
64 for (int n = 0; n < nmax; n++) {
65 g[n + 1] = (1.0 - (2 * n + 1) * g[n]) / (2.0 * x);
66 }
67 }
68}
69
70/**
71 * Calculates value of the Gn(x) auxiliary function using the Taylor expansion.
72 * The Taylor series converges for x <= 30.
73 */
74static double gfun_taylor(int n, double x) {
75 const double thresh = 1e-15;
76 double sum = 0.0;
77
78 for (int k = 0; k < 100; k++) {
79
80 double y_exp = exp(-x);
81 double y_pow = pow(x, k);
82 double y_fac = libgrpp_factorial(k);
83 double y_nk1 = 2.0 * n + 2.0 * k + 1.0;
84
85 double contrib = y_exp * y_pow / y_fac / y_nk1;
86 sum += contrib;
87
88 if (fabs(contrib) < thresh) {
89 break;
90 }
91 }
92
93 return sum;
94}
double libgrpp_factorial(int n)
double libgrpp_Dawsons_Integral(double x)
void libgrpp_gfun_values(double x, int nmax, double *g)
static double gfun_taylor(int n, double x)