(git:08825b9)
Loading...
Searching...
No Matches
upf_projector_integrals_unittest.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
9 USE ai_moments, ONLY: moment
10 USE ai_overlap, ONLY: overlap
11 USE atom_upf, ONLY: atom_read_upf,&
13 atom_upfpot_type
15 USE ieee_arithmetic, ONLY: ieee_is_finite
16 USE kinds, ONLY: default_path_length,&
17 dp
18 USE libcp2k, ONLY: cp2k_finalize,&
20 USE orbital_pointers, ONLY: nco,&
21 ncoset
26
27 IMPLICIT NONE
28 LOGICAL :: source_root_argument
29
30 INTEGER, PARAMETER :: la = 4, lb = 3, nder = 2, na = 5, nb = 5
31 REAL(kind=dp), PARAMETER :: alpha(na) = [0.04_dp, 0.3_dp, 1.2_dp, 5.0_dp, 24.0_dp]
32 REAL(kind=dp), PARAMETER :: eta(nb) = [0.3_dp, 0.7_dp, 1.1_dp, 2.2_dp, 0.4_dp]
33 CHARACTER(LEN=default_path_length) :: filename
34 INTEGER :: grid, nr, i, j, p, m, l, geometry, id, ld, ldai, first, shell, q, io_unit
35 REAL(kind=dp) :: dx, rac(3), origin(3), error, scale, expected_d
36 REAL(kind=dp), ALLOCATABLE :: sab(:, :), work(:, :, :), moments(:, :, :), integrals(:, :, :), reference(:, :, :)
37 TYPE(atom_upfpot_type) :: pot
38 TYPE(upf_projector_type) :: projectors
39
40 CALL cp2k_init()
42 pot%number_of_proj = nb
43 ALLOCATE (pot%lbeta(nb))
44 pot%lbeta(:) = [0, 1, 2, 3, 1]
45 ALLOCATE (pot%dion(nb, nb))
46 pot%dion = 0.0_dp
47 DO i = 1, nb
48 pot%dion(i, i) = 0.3_dp*i - 0.8_dp
49 END DO
50 pot%dion(2, 5) = 0.17_dp
51 pot%dion(5, 2) = 0.17_dp
52
53 DO grid = 1, 3
54 nr = 2501
55 IF (grid == 2) nr = 2500
56 ALLOCATE (pot%r(nr), pot%rab(nr), pot%beta(nr, nb))
57 DO i = 1, nr
58 IF (grid == 3) THEN
59 dx = log(1.0_dp + 12.5_dp/0.001_dp)/(nr - 1)
60 pot%r(i) = 0.001_dp*(exp((i - 1)*dx) - 1.0_dp)
61 pot%rab(i) = dx*(pot%r(i) + 0.001_dp)
62 ELSE
63 pot%r(i) = (i - 1)*0.005_dp
64 pot%rab(i) = 0.005_dp
65 END IF
66 END DO
67 DO i = 1, nb
68 pot%beta(:, i) = pot%r**pot%lbeta(i)*exp(-eta(i)*pot%r**2)
69 END DO
70 CALL upf_projector_init(pot, la + nder, projectors)
71 ! Independent expansion of D, including non-diagonal coupling of two p projectors.
72 p = 0
73 DO i = 1, nb
74 DO m = -pot%lbeta(i), pot%lbeta(i)
75 p = p + 1
76 q = 0
77 DO j = 1, nb
78 DO l = -pot%lbeta(j), pot%lbeta(j)
79 q = q + 1
80 expected_d = 0.0_dp
81 IF (pot%lbeta(i) == pot%lbeta(j) .AND. m == l) expected_d = pot%dion(i, j)
82 IF (abs(projectors%d(p, q) - expected_d) > 1.e-15_dp) error stop "UPF D expansion failed"
83 END DO
84 END DO
85 END DO
86 END DO
87 ld = max(na*ncoset(la), nb*ncoset(lb))
88 ldai = ncoset(la + nder)
89 ALLOCATE (sab(ld, ld*ncoset(nder)), work(ldai, ldai, ncoset(nder)), &
90 moments(na*ncoset(la), nb*ncoset(lb), ncoset(nder) - 1), &
91 integrals(na*ncoset(la), projectors%nproj, ncoset(nder)), &
92 reference(na*ncoset(la), projectors%nproj, ncoset(nder)))
93 DO geometry = 1, 4
94 SELECT CASE (geometry)
95 CASE (1)
96 rac = 0.0_dp
97 CASE (2)
98 rac = [0.2_dp, -0.5_dp, 0.7_dp]
99 CASE (3)
100 rac = [3.0_dp, 2.0_dp, -1.0_dp]
101 CASE (4)
102 rac = [-7.0_dp, 1.0_dp, 2.0_dp]
103 END SELECT
104 sab = 0.0_dp
105 CALL overlap(la, 0, na, spread(100.0_dp, 1, na), alpha, &
106 lb, 0, nb, spread(100.0_dp, 1, nb), eta, rac, norm2(rac), &
107 sab, nder, .true., work, ldai)
108 DO id = 1, ncoset(nder)
109 p = 0
110 DO i = 1, nb
111 l = pot%lbeta(i)
112 first = (id - 1)*ld + (i - 1)*ncoset(lb) + ncoset(l - 1) + 1
113 reference(:, p + 1:p + 2*l + 1, id) = &
114 matmul(sab(:na*ncoset(la), first:first + nco(l) - 1), transpose(orbtramat(l)%slm))
115 p = p + 2*l + 1
116 END DO
117 END DO
118 CALL upf_projector_overlap(projectors, la, alpha, rac, nder, integrals)
119 DO id = 1, ncoset(nder)
120 scale = max(1.0_dp, maxval(abs(reference(:, :, id))))
121 error = maxval(abs(integrals(:, :, id) - reference(:, :, id)))/scale
122 IF (io_unit > 0) WRITE (io_unit, '(A,3I4,ES16.7)') &
123 "UPF radial Gaussian overlap/derivative:", grid, geometry, id, error
124 IF (error > 1.e-10_dp) error stop "Numerical UPF overlaps disagree with analytic Gaussian integrals"
125 END DO
126 ! Independent moment implementation uses the OS recurrence with a fixed reference.
127 origin = [0.4_dp, 0.6_dp, -0.3_dp]
128 CALL moment(la, na, alpha, spread(100.0_dp, 1, na), 0, &
129 lb, nb, eta, spread(100.0_dp, 1, nb), nder, origin, origin + rac, moments)
130 DO id = 2, ncoset(nder)
131 p = 0
132 DO i = 1, nb
133 l = pot%lbeta(i)
134 shell = (i - 1)*ncoset(lb) + ncoset(l - 1) + 1
135 reference(:, p + 1:p + 2*l + 1, id) = &
136 matmul(moments(:, shell:shell + nco(l) - 1, id - 1), transpose(orbtramat(l)%slm))
137 p = p + 2*l + 1
138 END DO
139 END DO
140 CALL upf_projector_overlap(projectors, la, alpha, rac, nder, integrals, moment_origin=origin)
141 scale = max(1.0_dp, maxval(abs(reference)))
142 error = maxval(abs(integrals - reference))/scale
143 IF (io_unit > 0) WRITE (io_unit, '(A,2I4,ES16.7)') "UPF radial Gaussian moments:", grid, geometry, error
144 IF (error > 1.e-10_dp) error stop "Numerical UPF moments disagree with analytic Gaussian integrals"
145 END DO
146 DEALLOCATE (pot%r, pot%rab, pot%beta, sab, work, moments, integrals, reference)
147 END DO
148 CALL atom_release_upf(pot)
149 ! Optional library audit checks real radial meshes, angular channels, and
150 ! successive cache replacement. Finiteness is not a physical accuracy test.
151 DO i = 1, command_argument_count()
152 CALL get_command_argument(i, filename)
153 ! do_regtest.py passes the CP2K source root before any optional UPF audit files.
154 IF (i == 1) THEN
155 INQUIRE (file=trim(filename)//"/tests/UNIT_TESTS", exist=source_root_argument)
156 IF (source_root_argument) cycle
157 END IF
158 CALL atom_read_upf(pot, trim(filename))
159 IF (pot%number_of_proj > 0) THEN
160 CALL upf_projector_init(pot, la + nder, projectors)
161 IF (.NOT. all(ieee_is_finite(projectors%d))) error stop "Non-finite original UPF D matrix"
162 ALLOCATE (integrals(na*ncoset(la), projectors%nproj, ncoset(nder)))
163 DO geometry = 1, 2
164 rac = 0.0_dp
165 IF (geometry == 2) rac = [0.3_dp, -0.5_dp, 1.0_dp]
166 CALL upf_projector_overlap(projectors, la, alpha, rac, nder, integrals)
167 IF (.NOT. all(ieee_is_finite(integrals))) error stop "Non-finite native UPF projector integrals"
168 END DO
169 IF (io_unit > 0) WRITE (io_unit, '(A,1X,A,1X,I6,1X,ES16.7)') "UPF native integrals:", trim(filename), &
170 projectors%nproj, maxval(abs(integrals))
171 DEALLOCATE (integrals)
172 END IF
173 CALL atom_release_upf(pot)
174 END DO
175 CALL cp2k_finalize()
Calculation of the moment integrals over Cartesian Gaussian-type functions.
Definition ai_moments.F:17
subroutine, public moment(la_max, npgfa, zeta, rpgfa, la_min, lb_max, npgfb, zetb, rpgfb, lc_max, rac, rbc, mab)
...
Definition ai_moments.F:284
Calculation of the overlap integrals over Cartesian Gaussian-type functions.
Definition ai_overlap.F:18
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...
Definition ai_overlap.F:74
Routines that process Quantum Espresso UPF files.
Definition atom_upf.F:14
pure subroutine, public atom_release_upf(upfpot)
...
Definition atom_upf.F:1191
subroutine, public atom_read_upf(pot, upf_filename, read_header, read_augmentation)
...
Definition atom_upf.F:52
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_path_length
Definition kinds.F:58
CP2K C/C++ interface.
Definition libcp2k.F:20
subroutine, public cp2k_finalize()
...
Definition libcp2k.F:139
subroutine, public cp2k_init()
...
Definition libcp2k.F:104
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public nco
integer, dimension(:), allocatable, public ncoset
Calculation of the spherical harmonics and the corresponding orbital transformation matrices.
type(orbtramat_type), dimension(:), pointer, public orbtramat
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.
program upf_projector_integrals_unittest