(git:ed6f26b)
Loading...
Searching...
No Matches
grpp_type1_integrals.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#include <assert.h>
16#include <math.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20
21#ifndef M_PI
22#define M_PI 3.14159265358979323846
23#endif
24
26#include "grpp_binomial.h"
27#include "grpp_norm_gaussian.h"
30#include "grpp_utils.h"
31#include "libgrpp.h"
32#include "libgrpp_types.h"
33/* for the old (numerical) version:
34void evaluate_type1_integral_primitive_gaussians(double *A, int n_cart_A, int
35*cart_list_A, double alpha_A, double *B, int n_cart_B, int *cart_list_B, double
36alpha_B, double *C, libgrpp_potential_t *potential, double *matrix);
37*/
38
40
42 double *A, int n_cart_A, int *cart_list_A, double alpha_A, double *B,
43 int n_cart_B, int *cart_list_B, double alpha_B, double *C,
44 double (*potential)(double r, void *params), void *potential_params,
45 double *matrix);
46
47static double evaluate_pseudopotential(double r, void *params);
48
49/**
50 * Evaluation of type 1 RPP integrals (scalar-relativistic radially local RPP).
51 */
53 double *rpp_origin, libgrpp_potential_t *potential,
54 double *matrix) {
55 assert(libgrpp_is_initialized());
56
57 int size_A = libgrpp_get_shell_size(shell_A);
58 int size_B = libgrpp_get_shell_size(shell_B);
59 memset(matrix, 0, size_A * size_B * sizeof(double));
60
61 if (potential == NULL) {
62 return;
63 }
64
65 /*
66 * RPP terms with n = 1, 2 are evaluated in a completely analytic manner
67 * using the Obara-Saika-like recurrence relations
68 */
69
70 double *buf = calloc(size_A * size_B, sizeof(double));
71
72 for (int k = 0; k < potential->num_primitives; k++) {
73 double pot_coef = potential->coeffs[k];
74 double pot_alpha = potential->alpha[k];
75 int pot_n = potential->powers[k];
76
78 shell_A, shell_B, rpp_origin, pot_alpha, pot_n, buf);
79
80 libgrpp_daxpy(size_A * size_B, pot_coef, buf, matrix);
81 }
82
83 free(buf);
84
85 /*
86 * old (numerical) version
87 */
88
89 /*for (int i = 0; i < shell_A->num_primitives; i++) {
90 for (int j = 0; j < shell_B->num_primitives; j++) {
91 double coef_A_i = shell_A->coeffs[i];
92 double coef_B_j = shell_B->coeffs[j];
93
94 if (fabs(coef_A_i * coef_B_j) < 1e-15) {
95 continue;
96 }
97
98 evaluate_type1_integral_primitive_gaussians(
99 shell_A->origin, size_A, shell_A->cart_list,
100 shell_A->alpha[i], shell_B->origin, size_B, shell_B->cart_list,
101 shell_B->alpha[j], rpp_origin, potential, buf
102 );
103
104 libgrpp_daxpy(size_A * size_B, coef_A_i * coef_B_j, buf, matrix);
105 }
106 }*/
107}
108
109/**
110 * Evaluation of type 1 RPP integrals (scalar-relativistic radially local RPP)
111 * for the pair of shells constructed from primitive Gaussians.
112 */
114 double *A, int n_cart_A, int *cart_list_A, double alpha_A, double *B,
115 int n_cart_B, int *cart_list_B, double alpha_B, double *C,
116 libgrpp_potential_t *potential, double *matrix) {
117 libgrpp_potential_t *potential_shrinked = libgrpp_shrink_potential(potential);
118
120 A, n_cart_A, cart_list_A, alpha_A, B, n_cart_B, cart_list_B, alpha_B, C,
121 evaluate_pseudopotential, potential_shrinked, matrix);
122
123 libgrpp_delete_potential(potential_shrinked);
124}
125
126static double evaluate_pseudopotential(double r, void *params) {
127 libgrpp_potential_t *potential = (libgrpp_potential_t *)params;
128
129 double u = libgrpp_potential_value(potential, r);
130
131 return u;
132}
133
134/**
135 * Evaluation of AO integrals for an arbitrary radially-local operator
136 * for the pair of shells constructed from primitive Gaussians.
137 */
139 double *A, int n_cart_A, int *cart_list_A, double alpha_A, double *B,
140 int n_cart_B, int *cart_list_B, double alpha_B, double *C,
141 double (*potential)(double r, void *params), void *potential_params,
142 double *matrix) {
143 assert(n_cart_A > 0);
144 assert(n_cart_B > 0);
145
146 memset(matrix, 0, n_cart_A * n_cart_B * sizeof(double));
147
148 double CA_x = C[0] - A[0];
149 double CA_y = C[1] - A[1];
150 double CA_z = C[2] - A[2];
151 double CB_x = C[0] - B[0];
152 double CB_y = C[1] - B[1];
153 double CB_z = C[2] - B[2];
154 double CA_2 = CA_x * CA_x + CA_y * CA_y + CA_z * CA_z;
155 double CB_2 = CB_x * CB_x + CB_y * CB_y + CB_z * CB_z;
156
157 double kx = -2.0 * (alpha_A * CA_x + alpha_B * CB_x);
158 double ky = -2.0 * (alpha_A * CA_y + alpha_B * CB_y);
159 double kz = -2.0 * (alpha_A * CA_z + alpha_B * CB_z);
160 double k = sqrt(kx * kx + ky * ky + kz * kz);
161 double kvec[3];
162 kvec[0] = kx;
163 kvec[1] = ky;
164 kvec[2] = kz;
165
166 int L_A = cart_list_A[0] + cart_list_A[1] + cart_list_A[2];
167 int L_B = cart_list_B[0] + cart_list_B[1] + cart_list_B[2];
168
169 double N_A = libgrpp_gaussian_norm_factor(L_A, 0, 0, alpha_A);
170 double N_B = libgrpp_gaussian_norm_factor(L_B, 0, 0, alpha_B);
171 double D_ABC = 4 * M_PI * N_A * N_B;
172
173 int lambda_max = L_A + L_B;
174 int n_max = lambda_max;
175 // create_real_spherical_harmonic_coeffs_tables(lambda_max);
176
177 /*
178 * pre-compute type 1 radial integrals
179 */
181 lambda_max, n_max, CA_2, CB_2, alpha_A, alpha_B, k, D_ABC, potential,
182 potential_params);
183
184 /*
185 * main loop
186 * over shell pairs
187 */
188 for (int icart = 0; icart < n_cart_A; icart++) {
189 for (int jcart = 0; jcart < n_cart_B; jcart++) {
190
191 double chi_AB = 0.0;
192
193 int n_A = cart_list_A[3 * icart + 0];
194 int l_A = cart_list_A[3 * icart + 1];
195 int m_A = cart_list_A[3 * icart + 2];
196 int n_B = cart_list_B[3 * jcart + 0];
197 int l_B = cart_list_B[3 * jcart + 1];
198 int m_B = cart_list_B[3 * jcart + 2];
199
200 for (int a = 0; a <= n_A; a++) {
201 double C_nA_a = libgrpp_binomial(n_A, a);
202 double pow_CA_x = pow(CA_x, n_A - a);
203
204 for (int b = 0; b <= l_A; b++) {
205 double C_lA_b = libgrpp_binomial(l_A, b);
206 double pow_CA_y = pow(CA_y, l_A - b);
207
208 for (int c = 0; c <= m_A; c++) {
209 double C_mA_c = libgrpp_binomial(m_A, c);
210 double pow_CA_z = pow(CA_z, m_A - c);
211
212 for (int d = 0; d <= n_B; d++) {
213 double C_nB_d = libgrpp_binomial(n_B, d);
214 double pow_CB_x = pow(CB_x, n_B - d);
215
216 for (int e = 0; e <= l_B; e++) {
217 double C_lB_e = libgrpp_binomial(l_B, e);
218 double pow_CB_y = pow(CB_y, l_B - e);
219
220 for (int f = 0; f <= m_B; f++) {
221 double C_mB_f = libgrpp_binomial(m_B, f);
222 double pow_CB_z = pow(CB_z, m_B - f);
223
224 double factor = C_nA_a * C_lA_b * C_mA_c * C_nB_d * C_lB_e *
225 C_mB_f * pow_CA_x * pow_CA_y * pow_CA_z *
226 pow_CB_x * pow_CB_y * pow_CB_z;
227
228 if (fabs(factor) < 1e-13) {
229 continue;
230 }
231
232 int N = a + b + c + d + e + f;
233 double sum_omega_Q = 0.0;
234 for (int lambda = 0; lambda <= lambda_max; lambda++) {
235
236 double Q = libgrpp_get_radial_type1_integral(radial_table,
237 lambda, N);
238 if (fabs(Q) < 1e-16) {
239 continue;
240 }
241
242 double omega = libgrpp_angular_type1_integral(
243 lambda, a + d, b + e, c + f, kvec);
244
245 sum_omega_Q += omega * Q;
246 }
247
248 chi_AB += factor * sum_omega_Q;
249 }
250 }
251 }
252 }
253 }
254 }
255
256 matrix[icart * n_cart_B + jcart] = chi_AB;
257 }
258 }
259
261}
double libgrpp_angular_type1_integral(int lambda, int II, int JJ, int KK, double *k)
uint64_t libgrpp_binomial(uint64_t n, uint64_t k)
int libgrpp_is_initialized()
double libgrpp_gaussian_norm_factor(int n, int l, int m, double alpha)
double libgrpp_potential_value(libgrpp_potential_t *potential, double r)
void libgrpp_delete_potential(libgrpp_potential_t *potential)
libgrpp_potential_t * libgrpp_shrink_potential(libgrpp_potential_t *src_potential)
double libgrpp_get_radial_type1_integral(radial_type1_table_t *table, int lambda, int n)
radial_type1_table_t * libgrpp_tabulate_radial_type1_integrals(int lambda_max, int n_max, double CA_2, double CB_2, double alpha_A, double alpha_B, double k, double prefactor, double(*potential)(double r, void *params), void *potential_params)
int libgrpp_get_shell_size(libgrpp_shell_t *shell)
Definition grpp_shell.c:98
static double evaluate_pseudopotential(double r, void *params)
void evaluate_type1_integral_primitive_gaussians(double *A, int n_cart_A, int *cart_list_A, double alpha_A, double *B, int n_cart_B, int *cart_list_B, double alpha_B, double *C, libgrpp_potential_t *potential, double *matrix)
void libgrpp_type1_integrals(libgrpp_shell_t *shell_A, libgrpp_shell_t *shell_B, double *rpp_origin, libgrpp_potential_t *potential, double *matrix)
void libgrpp_evaluate_radially_local_potential_integral_primitive_gaussians(double *A, int n_cart_A, int *cart_list_A, double alpha_A, double *B, int n_cart_B, int *cart_list_B, double alpha_B, double *C, double(*potential)(double r, void *params), void *potential_params, double *matrix)
void libgrpp_delete_radial_type1_integrals(radial_type1_table_t *table)
#define M_PI
void libgrpp_type1_integrals_mcmurchie_davidson_1978(libgrpp_shell_t *shell_A, libgrpp_shell_t *shell_B, double *origin_C, double alpha_C, int ecp_power, double *rpp_matrix)
void libgrpp_daxpy(int n, double a, double *x, double *y)
Definition grpp_utils.c:46