(git:08825b9)
Loading...
Searching...
No Matches
upf_local_integrals.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Local UPF matrix elements from the original radial potential.
10!> The Gaussian core electrostatics supplies -Z erf(sqrt(alpha)*r)/r.
11!> Its complement is integrated with analytic angles and radial quadrature.
12!> Gaussian products, center derivatives and RI integrals share this operator.
13! **************************************************************************************************
15 USE kinds, ONLY: dp
16 USE mathconstants, ONLY: fourpi,&
17 pi
18 USE mathlib, ONLY: binomial
19 USE orbital_pointers, ONLY: coset,&
20 indco,&
21 ncoset
26#include "../base/base_uses.f90"
27
28 IMPLICIT NONE
29 PRIVATE
30 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'upf_local_integrals'
31
33 TYPE(upf_projector_type) :: radial
34 REAL(kind=dp) :: eps = 0.0_dp
35 END TYPE upf_local_type
36
38
39CONTAINS
40
41! **************************************************************************************************
42!> \brief Prepare the short-range local potential outside parallel regions.
43!> \param pot Original UPF data, with PP_LOCAL already converted to Hartree.
44!> \param alpha Gaussian core-charge exponent, not its screening radius.
45!> \param degree Largest Gaussian product degree, including derivatives or moments.
46!> \param local Immutable integration data. Reinitialization retains its threshold.
47!> \param eps Optional threshold for estimating the potential's neighbor-list radius.
48!> This is NOT an integration tolerance: EPS_PPL is normally 1e-2.
49!> All original radial samples, including the tail, enter the quadrature.
50! **************************************************************************************************
51 SUBROUTINE upf_local_init(pot, alpha, degree, local, eps)
52 TYPE(atom_upfpot_type), INTENT(IN) :: pot
53 REAL(kind=dp), INTENT(IN) :: alpha
54 INTEGER, INTENT(IN) :: degree
55 TYPE(upf_local_type), INTENT(INOUT) :: local
56 REAL(kind=dp), INTENT(IN), OPTIONAL :: eps
57
58 INTEGER :: i, last, n
59 REAL(kind=dp), ALLOCATABLE :: short_range(:)
60 TYPE(atom_upfpot_type) :: scalar
61
62 cpassert(alpha > 0.0_dp)
63 cpassert(SIZE(pot%r) == SIZE(pot%vlocal))
64 cpassert(SIZE(pot%r) >= 3)
65 IF (PRESENT(eps)) local%eps = eps
66 cpassert(local%eps >= 0.0_dp)
67 ALLOCATE (short_range(SIZE(pot%vlocal)))
68 short_range(:) = pot%vlocal
69 DO i = 1, SIZE(pot%r)
70 IF (pot%r(i) > 0.0_dp) THEN
71 short_range(i) = short_range(i) + pot%zion*erf(sqrt(alpha)*pot%r(i))/pot%r(i)
72 ELSE
73 short_range(i) = short_range(i) + 2.0_dp*pot%zion*sqrt(alpha/pi)
74 END IF
75 END DO
76 last = 0
77 DO i = SIZE(short_range), 1, -1
78 IF (abs(short_range(i)) > local%eps) THEN
79 last = i
80 EXIT
81 END IF
82 END DO
83 n = SIZE(short_range)
84 scalar%number_of_proj = 1
85 ALLOCATE (scalar%r(n), scalar%rab(n), scalar%lbeta(1))
86 scalar%r(:) = pot%r(:n)
87 scalar%rab(:) = pot%rab(:n)
88 scalar%lbeta = 0
89 ALLOCATE (scalar%beta(n, 1), scalar%dion(1, 1))
90 ! Y00 = 1/sqrt(4*pi); absorb it to integrate a scalar radial potential.
91 scalar%beta(:, 1) = sqrt(fourpi)*short_range(:n)
92 scalar%dion = 0.0_dp
93 CALL upf_projector_init(scalar, degree, local%radial)
94 ! Screening estimates the support in a pair-list bound. It must never
95 ! truncate the function actually integrated within a retained pair.
96 local%radial%radius = 0.0_dp
97 IF (last > 0) local%radial%radius = pot%r(last)
98 END SUBROUTINE upf_local_init
99
100! **************************************************************************************************
101!> \brief Evaluate primitive three-center local integrals by the Gaussian product theorem.
102!> \param local Prepared radial potential.
103!> \param la Largest Cartesian degree at A; all degrees 0..la are returned.
104!> \param alpha Primitive exponents at A.
105!> \param lb Largest Cartesian degree at B; all degrees 0..lb are returned.
106!> \param beta Primitive exponents at B.
107!> \param rab B minus A.
108!> \param rac Potential center C minus A.
109!> \param v Matrix elements in primitive-major Cartesian order.
110!> \param da Optional derivatives with respect to A, at fixed B and C.
111!> \param db Optional derivatives with respect to B, at fixed A and C.
112!> The derivative with respect to C is -(da+db).
113! **************************************************************************************************
114 SUBROUTINE upf_local_matrix(local, la, alpha, lb, beta, rab, rac, v, da, db)
115 TYPE(upf_local_type), INTENT(IN) :: local
116 INTEGER, INTENT(IN) :: la
117 REAL(kind=dp), INTENT(IN) :: alpha(:)
118 INTEGER, INTENT(IN) :: lb
119 REAL(kind=dp), INTENT(IN) :: beta(:), rab(3), rac(3)
120 REAL(kind=dp), INTENT(OUT) :: v(:, :)
121 REAL(kind=dp), INTENT(OUT), OPTIONAL :: da(:, :, :), db(:, :, :)
122
123 INTEGER :: a, aa, axis, b, bb, da_max, db_max, &
124 degree, i, ia, ib, ix, iy, iz, j, k, &
125 pa(3), pb(3), shifted(3)
126 REAL(kind=dp) :: center(3), p, pref, shift_a(3), &
127 shift_b(3), value
128 REAL(kind=dp), ALLOCATABLE :: moments(:, :, :), &
129 polynomial(:, :, :, :), work(:, :)
130
131 cpassert(la >= 0 .AND. lb >= 0)
132 cpassert(all(alpha > 0.0_dp) .AND. all(beta > 0.0_dp))
133 cpassert(SIZE(v, 1) == SIZE(alpha)*ncoset(la))
134 cpassert(SIZE(v, 2) == SIZE(beta)*ncoset(lb))
135 degree = la + lb
136 IF (PRESENT(da) .OR. PRESENT(db)) degree = degree + 1
137 da_max = la
138 db_max = lb
139 IF (PRESENT(da)) THEN
140 cpassert(all(shape(da) == [SIZE(v, 1), SIZE(v, 2), 3]))
141 da = 0.0_dp
142 da_max = la + 1
143 END IF
144 IF (PRESENT(db)) THEN
145 cpassert(all(shape(db) == [SIZE(v, 1), SIZE(v, 2), 3]))
146 db = 0.0_dp
147 db_max = lb + 1
148 END IF
149 ALLOCATE (moments(ncoset(degree), 1, 1), polynomial(0:da_max, 0:db_max, 0:degree, 3))
150 ALLOCATE (work(ncoset(da_max), ncoset(db_max)))
151 v = 0.0_dp
152 DO ib = 1, SIZE(beta)
153 DO ia = 1, SIZE(alpha)
154 p = alpha(ia) + beta(ib)
155 shift_a = beta(ib)*rab/p
156 shift_b = -alpha(ia)*rab/p
157 center = rac - shift_a
158 pref = exp(-alpha(ia)*beta(ib)/p*sum(rab**2))
159 IF (pref == 0.0_dp) cycle
160 CALL upf_projector_overlap(local%radial, degree, [p], center, 0, moments)
161 polynomial = 0.0_dp
162 DO axis = 1, 3
163 DO a = 0, da_max
164 DO b = 0, min(db_max, degree - a)
165 DO i = 0, a
166 DO j = 0, b
167 polynomial(a, b, i + j, axis) = polynomial(a, b, i + j, axis) &
168 + binomial(a, i)*binomial(b, j)*shift_a(axis)**(a - i)*shift_b(axis)**(b - j)
169 END DO
170 END DO
171 END DO
172 END DO
173 END DO
174 DO b = 1, ncoset(db_max)
175 pb = indco(:, b)
176 DO a = 1, ncoset(da_max)
177 pa = indco(:, a)
178 IF (sum(pa + pb) > degree) cycle
179 value = 0.0_dp
180 DO iz = 0, pa(3) + pb(3)
181 DO iy = 0, pa(2) + pb(2)
182 DO ix = 0, pa(1) + pb(1)
183 k = coset(ix, iy, iz)
184 value = value + polynomial(pa(1), pb(1), ix, 1)*polynomial(pa(2), pb(2), iy, 2) &
185 *polynomial(pa(3), pb(3), iz, 3)*moments(k, 1, 1)
186 END DO
187 END DO
188 END DO
189 work(a, b) = pref*value
190 END DO
191 END DO
192 DO b = 1, ncoset(lb)
193 pb = indco(:, b)
194 bb = (ib - 1)*ncoset(lb) + b
195 DO a = 1, ncoset(la)
196 pa = indco(:, a)
197 aa = (ia - 1)*ncoset(la) + a
198 v(aa, bb) = work(a, b)
199 DO axis = 1, 3
200 IF (PRESENT(da)) THEN
201 shifted = pa
202 shifted(axis) = shifted(axis) + 1
203 da(aa, bb, axis) = 2*alpha(ia)*work(coset(shifted(1), shifted(2), shifted(3)), b)
204 IF (pa(axis) > 0) THEN
205 shifted = pa
206 shifted(axis) = shifted(axis) - 1
207 da(aa, bb, axis) = da(aa, bb, axis) &
208 - pa(axis)*work(coset(shifted(1), shifted(2), shifted(3)), b)
209 END IF
210 END IF
211 IF (PRESENT(db)) THEN
212 shifted = pb
213 shifted(axis) = shifted(axis) + 1
214 db(aa, bb, axis) = 2*beta(ib)*work(a, coset(shifted(1), shifted(2), shifted(3)))
215 IF (pb(axis) > 0) THEN
216 shifted = pb
217 shifted(axis) = shifted(axis) - 1
218 db(aa, bb, axis) = db(aa, bb, axis) &
219 - pb(axis)*work(a, coset(shifted(1), shifted(2), shifted(3)))
220 END IF
221 END IF
222 END DO
223 END DO
224 END DO
225 END DO
226 END DO
227 END SUBROUTINE upf_local_matrix
228
229! **************************************************************************************************
230!> \brief Local potential against a single Cartesian Gaussian for RI.
231!> \param local Prepared radial potential.
232!> \param la Largest Cartesian degree.
233!> \param zeta Primitive exponents.
234!> \param rac Potential center minus Gaussian center.
235!> \param v Primitive-major Cartesian integrals.
236!> \param dv Optional Gaussian-center derivatives, in x,y,z order.
237! **************************************************************************************************
238 SUBROUTINE upf_local_ri(local, la, zeta, rac, v, dv)
239 TYPE(upf_local_type), INTENT(IN) :: local
240 INTEGER, INTENT(IN) :: la
241 REAL(kind=dp), INTENT(IN) :: zeta(:), rac(3)
242 REAL(kind=dp), INTENT(OUT) :: v(:)
243 REAL(kind=dp), INTENT(OUT), OPTIONAL :: dv(:, :)
244
245 INTEGER :: n, nder
246 REAL(kind=dp), ALLOCATABLE :: integrals(:, :, :)
247
248 nder = 0
249 IF (PRESENT(dv)) nder = 1
250 n = SIZE(zeta)*ncoset(la)
251 cpassert(SIZE(v) == n)
252 ALLOCATE (integrals(n, 1, ncoset(nder)))
253 CALL upf_projector_overlap(local%radial, la, zeta, rac, nder, integrals)
254 v = integrals(:, 1, 1)
255 IF (PRESENT(dv)) THEN
256 cpassert(all(shape(dv) == [n, 3]))
257 dv = integrals(:, 1, 2:4)
258 END IF
259 END SUBROUTINE upf_local_ri
260END MODULE upf_local_integrals
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), parameter, public pi
real(kind=dp), parameter, public degree
real(kind=dp), parameter, public fourpi
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
elemental real(kind=dp) function, public binomial(n, k)
The binomial coefficient n over k for 0 <= k <= n is calculated, otherwise zero is returned.
Definition mathlib.F:214
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public ncoset
integer, dimension(:, :, :), allocatable, public coset
integer, dimension(:, :), allocatable, public indco
Local UPF matrix elements from the original radial potential. The Gaussian core electrostatics suppli...
subroutine, public upf_local_matrix(local, la, alpha, lb, beta, rab, rac, v, da, db)
Evaluate primitive three-center local integrals by the Gaussian product theorem.
subroutine, public upf_local_init(pot, alpha, degree, local, eps)
Prepare the short-range local potential outside parallel regions.
subroutine, public upf_local_ri(local, la, zeta, rac, v, dv)
Local potential against a single Cartesian Gaussian for RI.
Half-numerical overlaps with the original scalar UPF radial projectors. Cartesian polynomials and ang...
subroutine, public upf_projector_init(pot, degree, projectors)
Prepare immutable radial and angular data outside parallel regions.
subroutine, public upf_projector_overlap(projectors, la, zeta, rac, nder, integrals, moment_origin)
Evaluate <Cartesian Gaussian|beta_i Y_lm> and AO-center derivatives.
Owned UPF dataset and radial conventions shared by ATOM and Quickstep. Dataset availability does not ...
Definition upf_types.F:12