Line data Source code
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 : !> \par History
10 : !> none
11 : !> \author JGH (11.2017)
12 : ! **************************************************************************************************
13 : MODULE aux_basis_set
14 :
15 : USE basis_set_types, ONLY: gto_basis_set_type
16 : USE kinds, ONLY: default_string_length,&
17 : dp
18 : USE orbital_pointers, ONLY: indco,&
19 : nco,&
20 : ncoset,&
21 : nso
22 : USE orbital_symbols, ONLY: cgf_symbol,&
23 : sgf_symbol
24 : #include "../base/base_uses.f90"
25 :
26 : IMPLICIT NONE
27 :
28 : PRIVATE
29 :
30 : ! *** Global parameters (only in this module)
31 :
32 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'aux_basis_set'
33 :
34 : ! *** Public subroutines ***
35 :
36 : PUBLIC :: create_aux_basis
37 :
38 : CONTAINS
39 :
40 : ! **************************************************************************************************
41 : !> \brief create a basis in GTO form
42 : !> \param aux_basis ...
43 : !> \param bsname ...
44 : !> \param nsets ...
45 : !> \param lmin ...
46 : !> \param lmax ...
47 : !> \param nl ...
48 : !> \param npgf ...
49 : !> \param zet ...
50 : !> \version 1.0
51 : ! **************************************************************************************************
52 344 : SUBROUTINE create_aux_basis(aux_basis, bsname, nsets, lmin, lmax, nl, npgf, zet)
53 :
54 : TYPE(gto_basis_set_type), POINTER :: aux_basis
55 : CHARACTER(LEN=default_string_length) :: bsname
56 : INTEGER, INTENT(IN) :: nsets
57 : INTEGER, DIMENSION(:), INTENT(IN) :: lmin, lmax
58 : INTEGER, DIMENSION(0:, :), INTENT(IN) :: nl
59 : INTEGER, DIMENSION(:), INTENT(IN) :: npgf
60 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN) :: zet
61 :
62 : INTEGER :: i, ico, info, iset, ishell, j, l, &
63 : lshell, m, maxco, maxpgf, maxshell, &
64 : ncgf, ns, nsgf, nx
65 : REAL(KIND=dp) :: za, zb, zetab
66 344 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: so
67 :
68 344 : CPASSERT(.NOT. ASSOCIATED(aux_basis))
69 344 : ALLOCATE (aux_basis)
70 : !
71 344 : aux_basis%name = bsname
72 344 : aux_basis%aliases = bsname
73 344 : aux_basis%nset = nsets
74 : !
75 : ALLOCATE (aux_basis%npgf(nsets), aux_basis%nshell(nsets), &
76 2064 : aux_basis%lmax(nsets), aux_basis%lmin(nsets))
77 1424 : aux_basis%lmax(1:nsets) = lmax(1:nsets)
78 1424 : aux_basis%lmin(1:nsets) = lmin(1:nsets)
79 1424 : aux_basis%npgf(1:nsets) = npgf(1:nsets)
80 1424 : DO iset = 1, nsets
81 1080 : aux_basis%nshell(iset) = 0
82 3452 : DO l = lmin(iset), lmax(iset)
83 3108 : aux_basis%nshell(iset) = aux_basis%nshell(iset) + nl(l, iset)
84 : END DO
85 : END DO
86 1424 : maxpgf = MAXVAL(npgf(1:nsets))
87 1424 : maxshell = MAXVAL(aux_basis%nshell(1:nsets))
88 1376 : ALLOCATE (aux_basis%zet(maxpgf, nsets))
89 7270 : aux_basis%zet(1:maxpgf, 1:nsets) = zet(1:maxpgf, 1:nsets)
90 :
91 1376 : ALLOCATE (aux_basis%n(maxshell, nsets))
92 1032 : ALLOCATE (aux_basis%l(maxshell, nsets))
93 1720 : ALLOCATE (aux_basis%gcc(maxpgf, maxshell, nsets))
94 :
95 1424 : DO iset = 1, nsets
96 1080 : ns = 0
97 3452 : DO l = lmin(iset), lmax(iset)
98 9902 : DO i = 1, nl(l, iset)
99 6794 : ns = ns + 1
100 6794 : aux_basis%l(ns, iset) = l
101 8822 : aux_basis%n(ns, iset) = l + i
102 : END DO
103 : END DO
104 : END DO
105 :
106 : ! contraction
107 117826 : aux_basis%gcc = 0.0_dp
108 1424 : DO iset = 1, nsets
109 1080 : ns = 0
110 3452 : DO l = lmin(iset), lmax(iset)
111 2028 : nx = aux_basis%npgf(iset)
112 8112 : ALLOCATE (so(nx, nx))
113 2028 : CPASSERT(nx >= nl(l, iset))
114 9852 : DO i = 1, nx
115 7824 : za = (2.0_dp*zet(i, iset))**(0.25_dp*(2*l + 3))
116 47270 : DO j = i, nx
117 37418 : zb = (2.0_dp*zet(j, iset))**(0.25_dp*(2*l + 3))
118 37418 : zetab = zet(i, iset) + zet(j, iset)
119 37418 : so(i, j) = za*zb/zetab**(l + 1.5_dp)
120 45242 : IF (i /= j) so(j, i) = so(i, j)
121 : END DO
122 : END DO
123 2028 : info = 0
124 : ! upper triangular form used below
125 2028 : CALL dpotrf('U', nx, so, nx, info)
126 2028 : CPASSERT(info == 0)
127 2028 : CALL dtrtri('U', "N", nx, so, nx, info)
128 2028 : CPASSERT(info == 0)
129 8822 : DO i = ns + 1, ns + nl(l, iset)
130 36374 : DO j = 1, i - ns
131 34346 : aux_basis%gcc(j, i, iset) = so(j, i - ns)
132 : END DO
133 : END DO
134 2028 : IF (nl(l, iset) < nx) THEN
135 360 : i = ns + nl(l, iset)
136 1390 : DO j = nl(l, iset) + 1, nx
137 1390 : aux_basis%gcc(j, i, iset) = 1.0_dp
138 : END DO
139 : END IF
140 2028 : ns = ns + nl(l, iset)
141 3108 : DEALLOCATE (so)
142 : END DO
143 : END DO
144 :
145 : ! Initialise the depending aux_basis structures
146 1032 : ALLOCATE (aux_basis%first_cgf(maxshell, nsets))
147 1032 : ALLOCATE (aux_basis%first_sgf(maxshell, nsets))
148 1032 : ALLOCATE (aux_basis%last_cgf(maxshell, nsets))
149 1032 : ALLOCATE (aux_basis%last_sgf(maxshell, nsets))
150 688 : ALLOCATE (aux_basis%ncgf_set(nsets))
151 688 : ALLOCATE (aux_basis%nsgf_set(nsets))
152 :
153 344 : maxco = 0
154 344 : ncgf = 0
155 344 : nsgf = 0
156 1424 : DO iset = 1, nsets
157 1080 : aux_basis%ncgf_set(iset) = 0
158 1080 : aux_basis%nsgf_set(iset) = 0
159 7874 : DO ishell = 1, aux_basis%nshell(iset)
160 6794 : lshell = aux_basis%l(ishell, iset)
161 6794 : aux_basis%first_cgf(ishell, iset) = ncgf + 1
162 6794 : ncgf = ncgf + nco(lshell)
163 6794 : aux_basis%last_cgf(ishell, iset) = ncgf
164 : aux_basis%ncgf_set(iset) = &
165 6794 : aux_basis%ncgf_set(iset) + nco(lshell)
166 6794 : aux_basis%first_sgf(ishell, iset) = nsgf + 1
167 6794 : nsgf = nsgf + nso(lshell)
168 6794 : aux_basis%last_sgf(ishell, iset) = nsgf
169 : aux_basis%nsgf_set(iset) = &
170 7874 : aux_basis%nsgf_set(iset) + nso(lshell)
171 : END DO
172 1424 : maxco = MAX(maxco, npgf(iset)*ncoset(lmax(iset)))
173 : END DO
174 344 : aux_basis%ncgf = ncgf
175 344 : aux_basis%nsgf = nsgf
176 :
177 1032 : ALLOCATE (aux_basis%lx(ncgf))
178 688 : ALLOCATE (aux_basis%ly(ncgf))
179 688 : ALLOCATE (aux_basis%lz(ncgf))
180 1032 : ALLOCATE (aux_basis%m(nsgf))
181 1032 : ALLOCATE (aux_basis%cgf_symbol(ncgf))
182 1032 : ALLOCATE (aux_basis%sgf_symbol(nsgf))
183 :
184 344 : ncgf = 0
185 344 : nsgf = 0
186 :
187 1424 : DO iset = 1, nsets
188 8218 : DO ishell = 1, aux_basis%nshell(iset)
189 6794 : lshell = aux_basis%l(ishell, iset)
190 28584 : DO ico = ncoset(lshell - 1) + 1, ncoset(lshell)
191 21790 : ncgf = ncgf + 1
192 21790 : aux_basis%lx(ncgf) = indco(1, ico)
193 21790 : aux_basis%ly(ncgf) = indco(2, ico)
194 21790 : aux_basis%lz(ncgf) = indco(3, ico)
195 : aux_basis%cgf_symbol(ncgf) = &
196 : cgf_symbol(aux_basis%n(ishell, iset), [aux_basis%lx(ncgf), &
197 : aux_basis%ly(ncgf), &
198 93954 : aux_basis%lz(ncgf)])
199 : END DO
200 26720 : DO m = -lshell, lshell
201 18846 : nsgf = nsgf + 1
202 18846 : aux_basis%m(nsgf) = m
203 : aux_basis%sgf_symbol(nsgf) = &
204 25640 : sgf_symbol(aux_basis%n(ishell, iset), lshell, m)
205 : END DO
206 : END DO
207 : END DO
208 :
209 : ! orbital radii (initialize later)
210 344 : aux_basis%kind_radius = 0.0_dp
211 344 : aux_basis%short_kind_radius = 0.0_dp
212 1032 : ALLOCATE (aux_basis%set_radius(nsets))
213 1032 : ALLOCATE (aux_basis%pgf_radius(maxpgf, nsets))
214 1424 : aux_basis%set_radius = 0.0_dp
215 7270 : aux_basis%pgf_radius = 0.0_dp
216 :
217 : ! basis transformation matrices
218 1376 : ALLOCATE (aux_basis%cphi(maxco, ncgf))
219 1376 : ALLOCATE (aux_basis%sphi(maxco, nsgf))
220 1032 : ALLOCATE (aux_basis%scon(maxco, nsgf))
221 1032 : ALLOCATE (aux_basis%norm_cgf(ncgf))
222 344 : aux_basis%norm_type = 2
223 :
224 344 : END SUBROUTINE create_aux_basis
225 :
226 : END MODULE aux_basis_set
|