43#include "../base/base_uses.f90"
49 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'ai_moments'
77 iatom, ncoa, nsgfa, sgfa, sphi_a, ldsa, &
78 jatom, ncob, nsgfb, sgfb, sphi_b, ldsb, &
79 expab, work, ldwork, ordered)
81 REAL(
dp),
DIMENSION(:, :),
POINTER :: cos_block, sin_block
82 INTEGER,
INTENT(IN) :: iatom, ncoa, nsgfa, sgfa
83 REAL(
dp),
DIMENSION(:, :),
INTENT(IN) :: sphi_a
84 INTEGER,
INTENT(IN) :: ldsa, jatom, ncob, nsgfb, sgfb
85 REAL(
dp),
DIMENSION(:, :),
INTENT(IN) :: sphi_b
86 INTEGER,
INTENT(IN) :: ldsb
87 COMPLEX(dp),
DIMENSION(:, :),
INTENT(IN) :: expab
88 REAL(
dp),
DIMENSION(:, :) :: work
89 INTEGER,
INTENT(IN) :: ldwork
90 LOGICAL,
INTENT(IN),
OPTIONAL :: ordered
92 LOGICAL :: direct_block
93 REAL(
dp),
ALLOCATABLE :: primitive(:, :)
95 direct_block = iatom <= jatom
96 IF (
PRESENT(ordered)) direct_block = direct_block .OR. ordered
98 ALLOCATE (primitive(ncoa, ncob))
99 primitive(:, :) = real(expab(1:ncoa, 1:ncob), kind=
dp)
100 CALL dgemm(
"N",
"N", ncoa, nsgfb, ncob, &
101 1.0_dp, primitive(1, 1), ncoa, &
102 sphi_b(1, sgfb), ldsb, &
103 0.0_dp, work(1, 1), ldwork)
105 IF (direct_block)
THEN
106 CALL dgemm(
"T",
"N", nsgfa, nsgfb, ncoa, &
107 1.0_dp, sphi_a(1, sgfa), ldsa, &
108 work(1, 1), ldwork, &
109 1.0_dp, cos_block(sgfa, sgfb), &
112 CALL dgemm(
"T",
"N", nsgfb, nsgfa, ncoa, &
113 1.0_dp, work(1, 1), ldwork, &
114 sphi_a(1, sgfa), ldsa, &
115 1.0_dp, cos_block(sgfb, sgfa), &
118 primitive(:, :) = aimag(expab(1:ncoa, 1:ncob))
119 CALL dgemm(
"N",
"N", ncoa, nsgfb, ncob, &
120 1.0_dp, primitive(1, 1), ncoa, &
121 sphi_b(1, sgfb), ldsb, &
122 0.0_dp, work(1, 1), ldwork)
124 IF (direct_block)
THEN
125 CALL dgemm(
"T",
"N", nsgfa, nsgfb, ncoa, &
126 1.0_dp, sphi_a(1, sgfa), ldsa, &
127 work(1, 1), ldwork, &
128 1.0_dp, sin_block(sgfa, sgfb), &
131 CALL dgemm(
"T",
"N", nsgfb, nsgfa, ncoa, &
132 1.0_dp, work(1, 1), ldwork, &
133 sphi_a(1, sgfa), ldsa, &
134 1.0_dp, sin_block(sgfb, sgfa), &
161 SUBROUTINE expikr(la_max_set, npgfa, zeta, rpgfa, la_min_set, &
162 lb_max, npgfb, zetb, rpgfb, lb_min, rac, rbc, kvec, expab, dexpab, dexpba, momentab)
163 INTEGER,
INTENT(IN) :: la_max_set, npgfa
164 REAL(kind=
dp),
INTENT(IN) :: zeta(:), rpgfa(:)
165 INTEGER,
INTENT(IN) :: la_min_set, lb_max, npgfb
166 REAL(kind=
dp),
INTENT(IN) :: zetb(:), rpgfb(:)
167 INTEGER,
INTENT(IN) :: lb_min
168 REAL(kind=
dp),
INTENT(IN) :: rac(3), rbc(3), kvec(3)
169 COMPLEX(KIND=dp),
INTENT(INOUT) :: expab(:, :)
170 COMPLEX(KIND=dp),
INTENT(INOUT),
OPTIONAL,
TARGET :: dexpab(:, :, :), dexpba(:, :, :), &
173 COMPLEX(KIND=dp) :: prefactor, zrap(3), zrbp(3)
174 COMPLEX(KIND=dp),
ALLOCATABLE :: opr_rr(:, :, :), rr(:, :, :)
175 COMPLEX(KIND=dp),
POINTER :: opr_values(:, :, :)
176 INTEGER :: avec(3), bvec(3), coa, cob, ia, ib, &
177 idir, ipgf, jdir, jpgf, kdir, ldrr, &
178 lma, lmb, ma, mb, na, nb, op
179 LOGICAL :: derivative, right
180 REAL(kind=
dp) :: dab, exponent, f0, f1, f2, k2, kdp, &
181 origin(3), rab(3), rab2, zet, zetp
189 IF (
PRESENT(dexpab) .OR.
PRESENT(momentab)) lma = lma + 1
190 IF (
PRESENT(dexpba)) lmb = lmb + 1
191 ldrr = max(lma, lmb) + 1
192 ALLOCATE (rr(0:ldrr - 1, 0:ldrr - 1, 3))
193 IF (
PRESENT(dexpab) .OR.
PRESENT(dexpba) .OR.
PRESENT(momentab))
THEN
194 ALLOCATE (opr_rr(0:la_max_set, 0:lb_max, 3))
199 expab(1:na*npgfa, 1:nb*npgfb) = 0.0_dp
200 IF (
PRESENT(dexpab)) dexpab(1:na*npgfa, 1:nb*npgfb, 1:3) = 0.0_dp
201 IF (
PRESENT(dexpba)) dexpba(1:na*npgfa, 1:nb*npgfb, 1:3) = 0.0_dp
202 IF (
PRESENT(momentab)) momentab(1:na*npgfa, 1:nb*npgfb, 1:3) = 0.0_dp
207 IF (rpgfa(ipgf) + rpgfb(jpgf) < dab) cycle
209 zet = zeta(ipgf) + zetb(jpgf)
211 f0 = (
pi*zetp)**1.5_dp
214 kdp = zetp*dot_product(kvec, zeta(ipgf)*rac + zetb(jpgf)*rbc)
215 prefactor = f0*exp(cmplx(-zeta(ipgf)*f1*rab2 - 0.25_dp*k2*zetp, kdp, kind=
dp))
218 zrap = cmplx(f1*rab, f2*kvec, kind=
dp)
220 CALL os_rr_ovlp(zrap, lma, zrbp, lmb, zet, ldrr, rr)
221 DO cob =
ncoset(lb_min - 1) + 1, nb
223 DO coa =
ncoset(la_min_set - 1) + 1, na
225 expab(ma + coa, mb + cob) = prefactor*rr(avec(1), bvec(1), 1)* &
226 rr(avec(2), bvec(2), 2)*rr(avec(3), bvec(3), 3)
233 IF (.NOT.
PRESENT(dexpab)) cycle
235 exponent = zeta(ipgf)
237 IF (.NOT.
PRESENT(dexpba)) cycle
239 exponent = zetb(jpgf)
241 IF (.NOT.
PRESENT(momentab)) cycle
242 opr_values => momentab
248 IF (.NOT. derivative) origin = rac
249 CALL apply_cartesian_1d(rr, opr_rr, la_max_set, lb_max, right, derivative, exponent, origin)
257 jdir = mod(idir, 3) + 1
258 kdir = mod(idir + 1, 3) + 1
259 opr_values(ia, ib, idir) = prefactor*opr_rr(avec(idir), bvec(idir), idir)* &
260 rr(avec(jdir), bvec(jdir), jdir)*rr(avec(kdir), bvec(kdir), kdir)
287 SUBROUTINE moment(la_max, npgfa, zeta, rpgfa, la_min, &
288 lb_max, npgfb, zetb, rpgfb, lc_max, rac, rbc, mab, overlap)
289 INTEGER,
INTENT(IN) :: la_max, npgfa
290 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: zeta, rpgfa
291 INTEGER,
INTENT(IN) :: la_min, lb_max, npgfb
292 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: zetb, rpgfb
293 INTEGER,
INTENT(IN) :: lc_max
294 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: rac, rbc
295 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(INOUT) :: mab
296 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT),
OPTIONAL ::
overlap
298 INTEGER :: ax, ay, az, bx, by, bz, coa, cob, i, ia, &
299 ib, imom, ipgf, jpgf, ldrr, lx, ly, &
300 lz, ma, mb, powers(0:lc_max)
301 REAL(kind=
dp) :: a, b, dab, f0, rab(3), rab2, rap(3), &
303 REAL(kind=
dp),
ALLOCATABLE :: polynomial(:, :, :, :), rr(:, :, :)
309 ldrr = max(la_max + lc_max, lb_max) + 1
310 ALLOCATE (rr(0:ldrr - 1, 0:ldrr - 1, 3), polynomial(0:la_max, 0:lb_max, 0:lc_max, 3))
311 powers = [(i, i=0, lc_max)]
315 ma = (ipgf - 1)*
ncoset(la_max)
317 IF (rpgfa(ipgf) + rpgfb(jpgf) < dab) cycle
318 mb = (jpgf - 1)*
ncoset(lb_max)
324 f0 = (
pi/zet)**1.5_dp*exp(-a*b*rab2/zet)
325 CALL os_rr_ovlp(rap, la_max + lc_max, rbp, lb_max, zet, ldrr, rr)
328 DO cob = 1,
ncoset(lb_max)
333 DO coa = 1,
ncoset(la_max)
339 overlap(ia, ib) = f0*polynomial(ax, bx, 0, 1)* &
340 polynomial(ay, by, 0, 2)*polynomial(az, bz, 0, 3)
343 DO imom = 1,
ncoset(lc_max) - 1
344 lx =
indco(1, imom + 1)
345 ly =
indco(2, imom + 1)
346 lz =
indco(3, imom + 1)
347 mab(ia, ib, imom) = f0*polynomial(ax, bx, lx, 1)* &
348 polynomial(ay, by, ly, 2)*polynomial(az, bz, lz, 3)
388 lb_max, npgfb, zetb, rpgfb, lb_min, &
389 order, rac, rbc, difmab, mab_ext, deltaR, lambda, iatom, jatom)
391 INTEGER,
INTENT(IN) :: la_max, npgfa
392 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: zeta, rpgfa
393 INTEGER,
INTENT(IN) :: la_min, lb_max, npgfb
394 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: zetb, rpgfb
395 INTEGER,
INTENT(IN) :: lb_min, order
396 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: rac, rbc
397 REAL(kind=
dp),
DIMENSION(:, :, :, :),
INTENT(OUT) :: difmab
398 REAL(kind=
dp),
DIMENSION(:, :, :),
OPTIONAL, &
400 REAL(kind=
dp),
DIMENSION(:, :),
OPTIONAL,
POINTER :: deltar
401 INTEGER,
INTENT(IN),
OPTIONAL :: lambda, iatom, jatom
403 INTEGER :: ider, imom, lda, lda_min, ldb, ldb_min
404 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: difmab_tmp
405 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: mab
407 lda_min = max(0, la_min - 1)
408 ldb_min = max(0, lb_min - 1)
409 lda =
ncoset(la_max)*npgfa
410 ldb =
ncoset(lb_max)*npgfb
411 ALLOCATE (difmab_tmp(lda, ldb, 3))
413 IF (
PRESENT(mab_ext))
THEN
416 ALLOCATE (mab(npgfa*
ncoset(la_max + 1), npgfb*
ncoset(lb_max + 1), &
420 CALL moment(la_max + 1, npgfa, zeta, rpgfa, lda_min, &
421 lb_max + 1, npgfb, zetb, rpgfb, &
422 order, rac, rbc, mab)
425 DO imom = 1,
ncoset(order) - 1
427 difmab_tmp, right=.true., derivative=.true., exponents=zetb)
428 IF (
PRESENT(deltar))
THEN
429 cpassert(
ASSOCIATED(deltar))
430 cpassert(
PRESENT(iatom) .AND.
PRESENT(jatom))
432 difmab(1:lda, 1:ldb, imom, ider) = &
433 difmab_tmp(1:lda, 1:ldb, ider)*deltar(ider, jatom)
437 difmab_tmp, right=.false., derivative=.true., exponents=zeta)
439 difmab(1:lda, 1:ldb, imom, ider) = difmab(1:lda, 1:ldb, imom, ider) &
440 + difmab_tmp(1:lda, 1:ldb, ider)*deltar(ider, iatom)
443 difmab(1:lda, 1:ldb, imom, :) = difmab_tmp(1:lda, 1:ldb, :)
447 IF (
PRESENT(lambda))
THEN
448 cpassert(.NOT.
PRESENT(deltar))
449 cpassert(
PRESENT(iatom) .AND.
PRESENT(jatom))
450 IF (iatom == lambda .AND. jatom == lambda)
THEN
452 ELSE IF (iatom == lambda)
THEN
454 ELSE IF (jatom == lambda)
THEN
461 IF (
PRESENT(mab_ext))
THEN
466 DEALLOCATE (difmab_tmp)
493 lb_max, npgfb, zetb, rpgfb, lb_min, &
494 order, rac, rbc, pab, forcea, forceb)
496 INTEGER,
INTENT(IN) :: la_max, npgfa
497 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: zeta, rpgfa
498 INTEGER,
INTENT(IN) :: la_min, lb_max, npgfb
499 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: zetb, rpgfb
500 INTEGER,
INTENT(IN) :: lb_min, order
501 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: rac, rbc
502 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: pab
503 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT),
TARGET :: forcea, forceb
505 INTEGER,
PARAMETER :: components(2, 9) = reshape([1, 1, 2, 1, 3, 1, 1, 2, 2, 2, 3, 2, 1, 3, 2, 3, 3, 3], [2, 9])
506 INTEGER :: axis, first_a, first_b, icomp, ipgf, jpgf, ma, mb, nrow, ncol, side
507 INTEGER :: map_a(4,
ncoset(la_max) -
ncoset(la_min - 1), 3), &
509 REAL(kind=
dp) :: origin(3, 2), rab(3), distance, rr_work(3*(max(la_max, lb_max) + 2)**2)
510 REAL(kind=
dp),
ALLOCATABLE :: source(:, :), work(:, :), derivatives(:, :, :)
511 REAL(kind=
dp),
POINTER :: forces(:, :)
515 first_a =
ncoset(la_min - 1) + 1
516 first_b =
ncoset(lb_min - 1) + 1
517 nrow =
ncoset(la_max) - first_a + 1
518 ncol =
ncoset(lb_max) - first_b + 1
520 derivatives(nrow, ncol, 9))
527 distance = norm2(rab)
529 ma = (ipgf - 1)*
ncoset(la_max)
531 IF (rpgfa(ipgf) + rpgfb(jpgf) < distance) cycle
532 mb = (jpgf - 1)*
ncoset(lb_max)
533 CALL overlap_ab(la_max + 1, 0, 1, rpgfa(ipgf:ipgf), zeta(ipgf:ipgf), &
534 lb_max + 1, 0, 1, rpgfb(jpgf:jpgf), zetb(jpgf:jpgf), rab, &
535 sab=source, rr_work=rr_work)
542 [.false., .true.], [0.0_dp, zeta(ipgf)], &
543 [.true., .false.], work(:, 1:ncol), origin)
548 [.false., .true.], [0.0_dp, zetb(jpgf)], &
549 [.false., .true.], work(1:nrow, :), origin)
552 forces(components(1, icomp), components(2, icomp)) = &
553 forces(components(1, icomp), components(2, icomp)) + &
554 sum(pab(ma + first_a:ma +
ncoset(la_max), mb + first_b:mb +
ncoset(lb_max))*derivatives(:, :, icomp))
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Coordinate and basis-center derivative ladders for Cartesian Gaussian integrals. Derivatives act on a...
subroutine, public cartesian_polynomial_1d(source, values, la_max, lb_max, powers, origin)
Form requested coordinate powers from separable Cartesian integral tables. Only requested powers are ...
subroutine, public cartesian_ladder_map(lmax, lmin, axis, map, source_lmin)
Construct base, raised, lowered and degree indices for a Cartesian ladder.
subroutine, public apply_cartesian_operator(la_max, la_min, npgfa, lb_max, lb_min, npgfb, ab, values, right, derivative, exponents, origin)
Apply a Cartesian operator on either side of a primitive integral block. The input includes one extra...
Calculation of the moment integrals over Cartesian Gaussian-type functions.
subroutine, public moment(la_max, npgfa, zeta, rpgfa, la_min, lb_max, npgfb, zetb, rpgfb, lc_max, rac, rbc, mab, overlap)
...
subroutine, public dipole_force(la_max, npgfa, zeta, rpgfa, la_min, lb_max, npgfb, zetb, rpgfb, lb_min, order, rac, rbc, pab, forcea, forceb)
This returns the derivative of the dipole integrals [a|x|b], with respect to the position of the prim...
subroutine, public expikr(la_max_set, npgfa, zeta, rpgfa, la_min_set, lb_max, npgfb, zetb, rpgfb, lb_min, rac, rbc, kvec, expab, dexpab, dexpba, momentab)
Evaluate primitive exp(i k.r) integrals through the complex overlap recurrence.
subroutine, public diff_momop(la_max, npgfa, zeta, rpgfa, la_min, lb_max, npgfb, zetb, rpgfb, lb_min, order, rac, rbc, difmab, mab_ext, deltar, lambda, iatom, jatom)
This returns the derivative of the moment integrals [a|\mu|b]. By default, it differentiates the prim...
subroutine, public contract_expikr(cos_block, sin_block, iatom, ncoa, nsgfa, sgfa, sphi_a, ldsa, jatom, ncob, nsgfb, sgfb, sphi_b, ldsb, expab, work, ldwork, ordered)
Contract complex primitive integrals into real cosine and sine AO blocks.
Calculation of the overlap integrals over Cartesian Gaussian-type functions.
subroutine, public overlap(la_max_set, la_min_set, npgfa, rpgfa, zeta, lb_max_set, lb_min_set, npgfb, rpgfb, zetb, rab, dab, sab, da_max_set, return_derivatives, s, lds)
Purpose: Calculation of the two-center overlap integrals [a|b] over Cartesian Gaussian-type functions...
subroutine, public overlap_ab(la_max, la_min, npgfa, rpgfa, zeta, lb_max, lb_min, npgfb, rpgfb, zetb, rab, sab, dab, ddab, rr_work)
Calculation of the two-center overlap integrals [a|b] over Cartesian Gaussian-type functions....
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public ncoset
integer, dimension(:, :), allocatable, public indco