LCOV - code coverage report
Current view: top level - src/grpp - grpp_type1_integrals.c (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:b4bd748) Lines: 0 95 0.0 %
Date: 2025-03-09 07:56:22 Functions: 0 4 0.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 1.15