LCOV - code coverage report
Current view: top level - src/grpp - grpp_type1_integrals.c (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 0.0 % 95 0
Test Date: 2025-12-04 06:27:48 Functions: 0.0 % 4 0

            Line data    Source code
       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              : 
      25              : #include "grpp_angular_integrals.h"
      26              : #include "grpp_binomial.h"
      27              : #include "grpp_norm_gaussian.h"
      28              : #include "grpp_radial_type1_integral.h"
      29              : #include "grpp_type1_mcmurchie_davidson.h"
      30              : #include "grpp_utils.h"
      31              : #include "libgrpp.h"
      32              : #include "libgrpp_types.h"
      33              : /* for the old (numerical) version:
      34              : void 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
      36              : alpha_B, double *C, libgrpp_potential_t *potential, double *matrix);
      37              : */
      38              : 
      39              : extern void libgrpp_delete_radial_type1_integrals(radial_type1_table_t *table);
      40              : 
      41              : void libgrpp_evaluate_radially_local_potential_integral_primitive_gaussians(
      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              : 
      47              : static double evaluate_pseudopotential(double r, void *params);
      48              : 
      49              : /**
      50              :  * Evaluation of type 1 RPP integrals (scalar-relativistic radially local RPP).
      51              :  */
      52            0 : void libgrpp_type1_integrals(libgrpp_shell_t *shell_A, libgrpp_shell_t *shell_B,
      53              :                              double *rpp_origin, libgrpp_potential_t *potential,
      54              :                              double *matrix) {
      55            0 :   assert(libgrpp_is_initialized());
      56              : 
      57            0 :   int size_A = libgrpp_get_shell_size(shell_A);
      58            0 :   int size_B = libgrpp_get_shell_size(shell_B);
      59            0 :   memset(matrix, 0, size_A * size_B * sizeof(double));
      60              : 
      61            0 :   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            0 :   double *buf = calloc(size_A * size_B, sizeof(double));
      71              : 
      72            0 :   for (int k = 0; k < potential->num_primitives; k++) {
      73            0 :     double pot_coef = potential->coeffs[k];
      74            0 :     double pot_alpha = potential->alpha[k];
      75            0 :     int pot_n = potential->powers[k];
      76              : 
      77            0 :     libgrpp_type1_integrals_mcmurchie_davidson_1978(
      78              :         shell_A, shell_B, rpp_origin, pot_alpha, pot_n, buf);
      79              : 
      80            0 :     libgrpp_daxpy(size_A * size_B, pot_coef, buf, matrix);
      81              :   }
      82              : 
      83            0 :   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              :  */
     113            0 : void evaluate_type1_integral_primitive_gaussians(
     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            0 :   libgrpp_potential_t *potential_shrinked = libgrpp_shrink_potential(potential);
     118              : 
     119            0 :   libgrpp_evaluate_radially_local_potential_integral_primitive_gaussians(
     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            0 :   libgrpp_delete_potential(potential_shrinked);
     124            0 : }
     125              : 
     126            0 : static double evaluate_pseudopotential(double r, void *params) {
     127            0 :   libgrpp_potential_t *potential = (libgrpp_potential_t *)params;
     128              : 
     129            0 :   double u = libgrpp_potential_value(potential, r);
     130              : 
     131            0 :   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              :  */
     138            0 : void libgrpp_evaluate_radially_local_potential_integral_primitive_gaussians(
     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            0 :   assert(n_cart_A > 0);
     144            0 :   assert(n_cart_B > 0);
     145              : 
     146            0 :   memset(matrix, 0, n_cart_A * n_cart_B * sizeof(double));
     147              : 
     148            0 :   double CA_x = C[0] - A[0];
     149            0 :   double CA_y = C[1] - A[1];
     150            0 :   double CA_z = C[2] - A[2];
     151            0 :   double CB_x = C[0] - B[0];
     152            0 :   double CB_y = C[1] - B[1];
     153            0 :   double CB_z = C[2] - B[2];
     154            0 :   double CA_2 = CA_x * CA_x + CA_y * CA_y + CA_z * CA_z;
     155            0 :   double CB_2 = CB_x * CB_x + CB_y * CB_y + CB_z * CB_z;
     156              : 
     157            0 :   double kx = -2.0 * (alpha_A * CA_x + alpha_B * CB_x);
     158            0 :   double ky = -2.0 * (alpha_A * CA_y + alpha_B * CB_y);
     159            0 :   double kz = -2.0 * (alpha_A * CA_z + alpha_B * CB_z);
     160            0 :   double k = sqrt(kx * kx + ky * ky + kz * kz);
     161            0 :   double kvec[3];
     162            0 :   kvec[0] = kx;
     163            0 :   kvec[1] = ky;
     164            0 :   kvec[2] = kz;
     165              : 
     166            0 :   int L_A = cart_list_A[0] + cart_list_A[1] + cart_list_A[2];
     167            0 :   int L_B = cart_list_B[0] + cart_list_B[1] + cart_list_B[2];
     168              : 
     169            0 :   double N_A = libgrpp_gaussian_norm_factor(L_A, 0, 0, alpha_A);
     170            0 :   double N_B = libgrpp_gaussian_norm_factor(L_B, 0, 0, alpha_B);
     171            0 :   double D_ABC = 4 * M_PI * N_A * N_B;
     172              : 
     173            0 :   int lambda_max = L_A + L_B;
     174            0 :   int n_max = lambda_max;
     175              :   // create_real_spherical_harmonic_coeffs_tables(lambda_max);
     176              : 
     177              :   /*
     178              :    * pre-compute type 1 radial integrals
     179              :    */
     180            0 :   radial_type1_table_t *radial_table = libgrpp_tabulate_radial_type1_integrals(
     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            0 :   for (int icart = 0; icart < n_cart_A; icart++) {
     189            0 :     for (int jcart = 0; jcart < n_cart_B; jcart++) {
     190              : 
     191            0 :       double chi_AB = 0.0;
     192              : 
     193            0 :       int n_A = cart_list_A[3 * icart + 0];
     194            0 :       int l_A = cart_list_A[3 * icart + 1];
     195            0 :       int m_A = cart_list_A[3 * icart + 2];
     196            0 :       int n_B = cart_list_B[3 * jcart + 0];
     197            0 :       int l_B = cart_list_B[3 * jcart + 1];
     198            0 :       int m_B = cart_list_B[3 * jcart + 2];
     199              : 
     200            0 :       for (int a = 0; a <= n_A; a++) {
     201            0 :         double C_nA_a = libgrpp_binomial(n_A, a);
     202            0 :         double pow_CA_x = pow(CA_x, n_A - a);
     203              : 
     204            0 :         for (int b = 0; b <= l_A; b++) {
     205            0 :           double C_lA_b = libgrpp_binomial(l_A, b);
     206            0 :           double pow_CA_y = pow(CA_y, l_A - b);
     207              : 
     208            0 :           for (int c = 0; c <= m_A; c++) {
     209            0 :             double C_mA_c = libgrpp_binomial(m_A, c);
     210            0 :             double pow_CA_z = pow(CA_z, m_A - c);
     211              : 
     212            0 :             for (int d = 0; d <= n_B; d++) {
     213            0 :               double C_nB_d = libgrpp_binomial(n_B, d);
     214            0 :               double pow_CB_x = pow(CB_x, n_B - d);
     215              : 
     216            0 :               for (int e = 0; e <= l_B; e++) {
     217            0 :                 double C_lB_e = libgrpp_binomial(l_B, e);
     218            0 :                 double pow_CB_y = pow(CB_y, l_B - e);
     219              : 
     220            0 :                 for (int f = 0; f <= m_B; f++) {
     221            0 :                   double C_mB_f = libgrpp_binomial(m_B, f);
     222            0 :                   double pow_CB_z = pow(CB_z, m_B - f);
     223              : 
     224            0 :                   double factor = C_nA_a * C_lA_b * C_mA_c * C_nB_d * C_lB_e *
     225            0 :                                   C_mB_f * pow_CA_x * pow_CA_y * pow_CA_z *
     226            0 :                                   pow_CB_x * pow_CB_y * pow_CB_z;
     227              : 
     228            0 :                   if (fabs(factor) < 1e-13) {
     229            0 :                     continue;
     230              :                   }
     231              : 
     232            0 :                   int N = a + b + c + d + e + f;
     233            0 :                   double sum_omega_Q = 0.0;
     234            0 :                   for (int lambda = 0; lambda <= lambda_max; lambda++) {
     235              : 
     236            0 :                     double Q = libgrpp_get_radial_type1_integral(radial_table,
     237              :                                                                  lambda, N);
     238            0 :                     if (fabs(Q) < 1e-16) {
     239            0 :                       continue;
     240              :                     }
     241              : 
     242            0 :                     double omega = libgrpp_angular_type1_integral(
     243              :                         lambda, a + d, b + e, c + f, kvec);
     244              : 
     245            0 :                     sum_omega_Q += omega * Q;
     246              :                   }
     247              : 
     248            0 :                   chi_AB += factor * sum_omega_Q;
     249              :                 }
     250              :               }
     251              :             }
     252              :           }
     253              :         }
     254              :       }
     255              : 
     256            0 :       matrix[icart * n_cart_B + jcart] = chi_AB;
     257              :     }
     258              :   }
     259              : 
     260            0 :   libgrpp_delete_radial_type1_integrals(radial_table);
     261            0 : }
        

Generated by: LCOV version 2.0-1