(git:374b731)
Loading...
Searching...
No Matches
eri_mme_gaussian.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Methods related to properties of Hermite and Cartesian Gaussian functions.
10!> \par History
11!> 2015 09 created
12!> \author Patrick Seewald
13! **************************************************************************************************
14
16 USE kinds, ONLY: dp
17 USE mathconstants, ONLY: gamma1
19#include "../base/base_uses.f90"
20
21 IMPLICIT NONE
22
23 PRIVATE
24
25 LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .false.
26
27 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'eri_mme_gaussian'
28
29 INTEGER, PARAMETER, PUBLIC :: eri_mme_coulomb = 1, &
30 eri_mme_yukawa = 2, &
32
33 PUBLIC :: &
38
39CONTAINS
40
41! **************************************************************************************************
42!> \brief Create matrix to transform between cartesian and hermite gaussian
43!> basis functions.
44!> \param zet exponent
45!> \param l_max ...
46!> \param h_to_c transformation matrix with dimensions (0:l_max, 0:l_max)
47!> \note is idempotent, so transformation is the same
48!> in both directions.
49! **************************************************************************************************
50 PURE SUBROUTINE create_hermite_to_cartesian(zet, l_max, h_to_c)
51 REAL(kind=dp), INTENT(IN) :: zet
52 INTEGER, INTENT(IN) :: l_max
53 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :), &
54 INTENT(OUT) :: h_to_c
55
56 INTEGER :: k, l
57
58 ALLOCATE (h_to_c(-1:l_max + 1, 0:l_max))
59 h_to_c(:, :) = 0.0_dp
60 h_to_c(0, 0) = 1.0_dp
61 DO l = 0, l_max - 1
62 DO k = 0, l + 1
63 h_to_c(k, l + 1) = -(k + 1)*h_to_c(k + 1, l) + 2.0_dp*zet*h_to_c(k - 1, l)
64 END DO
65 END DO
66
67 END SUBROUTINE create_hermite_to_cartesian
68
69! **************************************************************************************************
70!> \brief Norm of 1d Hermite-Gauss functions
71!> \param zet ...
72!> \param l ...
73!> \return ...
74! **************************************************************************************************
75 PURE FUNCTION hermite_gauss_norm(zet, l) RESULT(norm)
76 REAL(kind=dp), INTENT(IN) :: zet
77 INTEGER, DIMENSION(3), INTENT(IN) :: l
78 REAL(kind=dp) :: norm
79
80 norm = 1.0_dp/sqrt((2.0_dp*zet)**(sum(l) - 1.5_dp)*(gamma1(l(1))*gamma1(l(2))*gamma1(l(3))))
81
82 END FUNCTION hermite_gauss_norm
83
84! **************************************************************************************************
85!> \brief Get minimax coefficient a_i and w_i for approximating
86!> 1/G^2 by sum_i w_i exp(-a_i G^2)
87!> \param n_minimax Number of minimax terms
88!> \param cutoff Plane Wave cutoff
89!> \param G_min Minimum absolute value of G
90!> \param minimax_aw Minimax coefficients a_i, w_i
91!> \param potential potential to use. Accepts the following values:
92!> 1: coulomb potential V(r)=1/r
93!> 2: yukawa potential V(r)=e(-a*r)/r
94!> 3: long-range coulomb erf(a*r)/r
95!> \param pot_par potential parameter a for yukawa V(r)=e(-a*r)/r or long-range coulomb V(r)=erf(a*r)/r
96!> \param err_minimax Maximum error MAX (|1/G^2-\sum_i w_i exp(-a_i G^2)|)
97! **************************************************************************************************
98 SUBROUTINE get_minimax_coeff_v_gspace(n_minimax, cutoff, G_min, minimax_aw, potential, pot_par, err_minimax)
99 INTEGER, INTENT(IN) :: n_minimax
100 REAL(kind=dp), INTENT(IN) :: cutoff, g_min
101 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: minimax_aw
102 INTEGER, INTENT(IN), OPTIONAL :: potential
103 REAL(kind=dp), INTENT(IN), OPTIONAL :: pot_par
104 REAL(kind=dp), INTENT(OUT), OPTIONAL :: err_minimax
105
106 INTEGER :: potential_prv
107 REAL(kind=dp) :: dg, g_max, minimax_rc
108 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: a, w
109
110 IF (PRESENT(potential)) THEN
111 potential_prv = potential
112 ELSE
113 potential_prv = eri_mme_coulomb
114 END IF
115
116 IF (potential_prv > 3) THEN
117 cpabort("unknown potential")
118 END IF
119
120 IF ((potential_prv >= 2) .AND. .NOT. PRESENT(pot_par)) THEN
121 cpabort("potential parameter pot_par required for yukawa or long-range Coulomb")
122 END IF
123
124 dg = 1.0e-3 ! Resolution in G to determine error of minimax approximation
125
126 ! Note: G_c = SQRT(2*cutoff) cutoff in 1 cartesian direction
127 ! G_max = SQRT(3*G_c**2) maximum absolute value of G vector
128 ! Minimax approx. needs to be valid in range [G_min, G_max]
129
130 ! 1) compute minimax coefficients
131
132 g_max = sqrt(3.0_dp*2.0_dp*cutoff)
133 cpassert(g_max .GT. g_min)
134 IF (potential_prv == eri_mme_coulomb .OR. potential_prv == eri_mme_longrange) THEN
135 minimax_rc = (g_max/g_min)**2
136 ELSEIF (potential_prv == eri_mme_yukawa) THEN
137 minimax_rc = (g_max**2 + pot_par**2)/(g_min**2 + pot_par**2)
138 END IF
139
140 CALL get_exp_minimax_coeff(n_minimax, minimax_rc, minimax_aw, err_minimax)
141
142 ALLOCATE (a(n_minimax)); ALLOCATE (w(n_minimax))
143 a(:) = minimax_aw(:n_minimax)
144 w(:) = minimax_aw(n_minimax + 1:)
145 SELECT CASE (potential_prv)
146 ! Scale minimax coefficients to incorporate different Fourier transforms
147 CASE (eri_mme_coulomb)
148 ! FT = 1/G**2
149 a(:) = a/g_min**2
150 w(:) = w/g_min**2
151 CASE (eri_mme_yukawa)
152 ! FT = 1/(G**2 + pot_par**2)
153 w(:) = w*exp((-a*pot_par**2)/(g_min**2 + pot_par**2))/(g_min**2 + pot_par**2)
154 a(:) = a/(g_min**2 + pot_par**2)
155 CASE (eri_mme_longrange)
156 ! FT = exp(-(G/pot_par)**2)/G**2
157 ! approximating 1/G**2 as for Coulomb:
158 a(:) = a/g_min**2
159 w(:) = w/g_min**2
160 ! incorporate exponential factor:
161 a(:) = a + 1.0_dp/pot_par**2
162 END SELECT
163 minimax_aw = [a(:), w(:)]
164
165 IF (PRESENT(err_minimax)) THEN
166 IF (potential_prv == eri_mme_coulomb) THEN
167 err_minimax = err_minimax/g_min**2
168 ELSEIF (potential_prv == eri_mme_yukawa) THEN
169 err_minimax = err_minimax/(g_min**2 + pot_par**2)
170 ELSEIF (potential_prv == eri_mme_longrange) THEN
171 err_minimax = err_minimax/g_min**2 ! approx. of Coulomb
172 err_minimax = err_minimax*exp(-g_min**2/pot_par**2) ! exponential factor
173 END IF
174 END IF
175
176 END SUBROUTINE get_minimax_coeff_v_gspace
177
178! **************************************************************************************************
179!> \brief Expand 1d product of cartesian (or hermite) gaussians into single hermite gaussians:
180!> Find E_t^{lm} s.t.
181!> F(l, a, r-R1) * F(m, b, r-R2) = sum_{t=0}^{l+m} E_t^{lm} H(t, p, r-R_P)
182!> with p = a + b, R_P = (a*R1 + b*R2)/p. The function F can be either Cartesian
183!> Gaussian or Hermite Gaussian.
184!> \param l ...
185!> \param m ...
186!> \param a ...
187!> \param b ...
188!> \param R1 ...
189!> \param R2 ...
190!> \param H_or_C_product 1: cartesian product, 2: hermite product
191!> \param E ...
192! **************************************************************************************************
193 PURE SUBROUTINE create_gaussian_overlap_dist_to_hermite(l, m, a, b, R1, R2, H_or_C_product, E)
194 INTEGER, INTENT(IN) :: l, m
195 REAL(kind=dp), INTENT(IN) :: a, b, r1, r2
196 INTEGER, INTENT(IN) :: h_or_c_product
197 REAL(kind=dp), DIMENSION(-1:l+m+1, -1:l, -1:m), &
198 INTENT(OUT) :: e
199
200 INTEGER :: ll, mm, t
201 REAL(kind=dp) :: c1, c2, c3
202
203 e(:, :, :) = 0.0_dp
204 e(0, 0, 0) = exp(-a*b/(a + b)*(r1 - r2)**2) ! cost: exp_w flops
205
206 c1 = 0.5_dp/(a + b)
207 c2 = (b/(a + b))*(r2 - r1)
208 c3 = (a/(a + b))*(r1 - r2)
209
210 IF (h_or_c_product .EQ. 1) THEN ! Cartesian overlap dist
211 DO mm = 0, m
212 DO ll = 0, l
213 DO t = 0, ll + mm + 1
214 IF (ll .LT. l) THEN
215 e(t, ll + 1, mm) = c1*e(t - 1, ll, mm) + & ! cost: 8 flops
216 c2*e(t, ll, mm) + &
217 (t + 1)*e(t + 1, ll, mm)
218 END IF
219 IF (mm .LT. m) THEN
220 e(t, ll, mm + 1) = c1*e(t - 1, ll, mm) + & ! cost: 8 flops
221 c3*e(t, ll, mm) + &
222 (t + 1)*e(t + 1, ll, mm)
223 END IF
224 END DO
225 END DO
226 END DO
227 ELSE ! Hermite overlap dist
228 DO mm = 0, m
229 DO ll = 0, l
230 DO t = 0, ll + mm + 1
231 IF (ll .LT. l) THEN
232 e(t, ll + 1, mm) = a*(2*c1*e(t - 1, ll, mm) + & ! cost: 16 flops
233 2*c2*e(t, ll, mm) + &
234 2*(t + 1)*e(t + 1, ll, mm) - &
235 2*ll*e(t, ll - 1, mm))
236 END IF
237 IF (mm .LT. m) THEN
238 e(t, ll, mm + 1) = b*(2*c1*e(t - 1, ll, mm) + & ! cost: 16 flops
239 2*c3*e(t, ll, mm) + &
240 2*(t + 1)*e(t + 1, ll, mm) - &
241 2*mm*e(t, ll, mm - 1))
242
243 END IF
244 END DO
245 END DO
246 END DO
247 END IF
248
250END MODULE eri_mme_gaussian
Methods related to properties of Hermite and Cartesian Gaussian functions.
pure real(kind=dp) function, public hermite_gauss_norm(zet, l)
Norm of 1d Hermite-Gauss functions.
pure subroutine, public create_hermite_to_cartesian(zet, l_max, h_to_c)
Create matrix to transform between cartesian and hermite gaussian basis functions.
integer, parameter, public eri_mme_longrange
integer, parameter, public eri_mme_coulomb
subroutine, public get_minimax_coeff_v_gspace(n_minimax, cutoff, g_min, minimax_aw, potential, pot_par, err_minimax)
Get minimax coefficient a_i and w_i for approximating 1/G^2 by sum_i w_i exp(-a_i G^2)
pure subroutine, public create_gaussian_overlap_dist_to_hermite(l, m, a, b, r1, r2, h_or_c_product, e)
Expand 1d product of cartesian (or hermite) gaussians into single hermite gaussians: Find E_t^{lm} s....
integer, parameter, public eri_mme_yukawa
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
real(kind=dp), dimension(0:maxfac), parameter, public gamma1
Routines to calculate the minimax coefficients in order to approximate 1/x as a sum over exponential ...
Definition minimax_exp.F:29
subroutine, public get_exp_minimax_coeff(k, rc, aw, mm_error, which_coeffs)
Get best minimax approximation for given input parameters. Automatically chooses the most exact set o...