(git:374b731)
Loading...
Searching...
No Matches
atom_grb.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
8MODULE atom_grb
9 USE ai_onecenter, ONLY: sg_conf,&
20 USE atom_types, ONLY: &
26 USE cp_files, ONLY: close_file,&
28 USE input_constants, ONLY: barrier_conf,&
38 USE kinds, ONLY: default_string_length,&
39 dp
40 USE lapack, ONLY: lapack_ssygv
41 USE mathconstants, ONLY: dfac,&
42 rootpi
47 USE periodic_table, ONLY: ptable
48 USE physcon, ONLY: bohr
49 USE powell, ONLY: opt_state_type,&
53#include "./base/base_uses.f90"
54
55 IMPLICIT NONE
56
58 TYPE(atom_basis_type), POINTER :: basis => null()
59 END TYPE basis_p_type
60
61 PRIVATE
62 PUBLIC :: atom_grb_construction
63
64 CHARACTER(len=*), PARAMETER, PRIVATE :: modulen = 'atom_grb'
65
66CONTAINS
67
68! **************************************************************************************************
69!> \brief Construct geometrical response basis set.
70!> \param atom_info information about the atomic kind. Two-dimensional array of size
71!> (electronic-configuration, electronic-structure-method)
72!> \param atom_section ATOM input section
73!> \param iw output file unit
74!> \par History
75!> * 11.2016 created [Juerg Hutter]
76! **************************************************************************************************
77 SUBROUTINE atom_grb_construction(atom_info, atom_section, iw)
78
79 TYPE(atom_p_type), DIMENSION(:, :), POINTER :: atom_info
80 TYPE(section_vals_type), POINTER :: atom_section
81 INTEGER, INTENT(IN) :: iw
82
83 CHARACTER(len=default_string_length) :: abas, basname
84 CHARACTER(len=default_string_length), DIMENSION(1) :: basline
85 CHARACTER(len=default_string_length), DIMENSION(3) :: headline
86 INTEGER :: i, ider, is, iunit, j, k, l, lhomo, ll, &
87 lval, m, maxl, mb, method, mo, n, &
88 nder, ngp, nhomo, nr, num_gto, &
89 num_pol, quadtype, s1, s2
90 INTEGER, DIMENSION(0:7) :: nbas
91 INTEGER, DIMENSION(0:lmat) :: next_bas, next_prim
92 INTEGER, DIMENSION(:), POINTER :: num_bas
93 REAL(kind=dp) :: al, amin, aval, cnum, crad, cradx, cval, delta, dene, ear, emax, &
94 energy_ex(0:lmat), energy_ref, energy_vb(0:lmat), expzet, fhomo, o, prefac, rconf, rk, &
95 rmax, scon, zeta, zval
96 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: ale, alp, rho
97 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: amat
98 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: ebasis, pbasis, qbasis, rbasis
99 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :, :) :: wfn
100 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: ovlp
101 TYPE(atom_basis_type), POINTER :: basis, basis_grb, basis_ref, basis_vrb
102 TYPE(atom_integrals), POINTER :: atint
103 TYPE(atom_orbitals), POINTER :: orbitals
104 TYPE(atom_state), POINTER :: state
105 TYPE(atom_type), POINTER :: atom, atom_ref, atom_test
106 TYPE(basis_p_type), DIMENSION(0:10) :: vbasis
107 TYPE(section_vals_type), POINTER :: grb_section, powell_section
108
109 IF (iw > 0) WRITE (iw, '(/," ",79("*"),/,T28,A,/," ",79("*"))') "GEOMETRICAL RESPONSE BASIS"
110
111 DO i = 0, 10
112 NULLIFY (vbasis(i)%basis)
113 END DO
114 ! make some basic checks
115 is = SIZE(atom_info)
116 IF (iw > 0 .AND. is > 1) THEN
117 WRITE (iw, '(/,A,/)') " WARNING: Only use first electronic structure/method for basis set generation"
118 END IF
119 atom_ref => atom_info(1, 1)%atom
120
121 ! check method
122 method = atom_ref%method_type
123 SELECT CASE (method)
125 ! restricted methods are okay
127 cpabort("Unrestricted methods not allowed for GRB generation")
128 CASE DEFAULT
129 cpabort("")
130 END SELECT
131
132 ! input for basis optimization
133 grb_section => section_vals_get_subs_vals(atom_section, "PRINT%GEOMETRICAL_RESPONSE_BASIS")
134
135 ! generate an atom type
136 NULLIFY (atom)
138 CALL copy_atom_basics(atom_ref, atom, state=.true., potential=.true., optimization=.true., xc=.true.)
139 ! set confinement potential
140 atom%potential%confinement = .true.
141 atom%potential%conf_type = barrier_conf
142 atom%potential%acon = 200._dp
143 atom%potential%rcon = 4._dp
144 CALL section_vals_val_get(grb_section, "CONFINEMENT", r_val=scon)
145 atom%potential%scon = scon
146 ! generate main block geometrical exponents
147 basis_ref => atom_ref%basis
148 ALLOCATE (basis)
149 NULLIFY (basis%am, basis%cm, basis%as, basis%ns, basis%bf, basis%dbf, basis%ddbf)
150 ! get information on quadrature type and number of grid points
151 ! allocate and initialize the atomic grid
152 NULLIFY (basis%grid)
153 CALL allocate_grid_atom(basis%grid)
154 CALL section_vals_val_get(grb_section, "QUADRATURE", i_val=quadtype)
155 CALL section_vals_val_get(grb_section, "GRID_POINTS", i_val=ngp)
156 IF (ngp <= 0) &
157 cpabort("# point radial grid < 0")
158 CALL create_grid_atom(basis%grid, ngp, 1, 1, 0, quadtype)
159 basis%grid%nr = ngp
160 !
161 maxl = atom%state%maxl_occ
162 basis%basis_type = gto_basis
163 CALL section_vals_val_get(grb_section, "NUM_GTO_CORE", i_val=num_gto)
164 basis%nbas = 0
165 basis%nbas(0:maxl) = num_gto
166 basis%nprim = basis%nbas
167 CALL section_vals_val_get(grb_section, "GEOMETRICAL_FACTOR", r_val=cval)
168 CALL section_vals_val_get(grb_section, "GEO_START_VALUE", r_val=aval)
169 m = maxval(basis%nbas)
170 ALLOCATE (basis%am(m, 0:lmat))
171 basis%am = 0._dp
172 DO l = 0, lmat
173 DO i = 1, basis%nbas(l)
174 ll = i - 1
175 basis%am(i, l) = aval*cval**(ll)
176 END DO
177 END DO
178
179 basis%eps_eig = basis_ref%eps_eig
180 basis%geometrical = .true.
181 basis%aval = aval
182 basis%cval = cval
183 basis%start = 0
184
185 ! initialize basis function on a radial grid
186 nr = basis%grid%nr
187 m = maxval(basis%nbas)
188 ALLOCATE (basis%bf(nr, m, 0:lmat))
189 ALLOCATE (basis%dbf(nr, m, 0:lmat))
190 ALLOCATE (basis%ddbf(nr, m, 0:lmat))
191 basis%bf = 0._dp
192 basis%dbf = 0._dp
193 basis%ddbf = 0._dp
194 DO l = 0, lmat
195 DO i = 1, basis%nbas(l)
196 al = basis%am(i, l)
197 DO k = 1, nr
198 rk = basis%grid%rad(k)
199 ear = exp(-al*basis%grid%rad(k)**2)
200 basis%bf(k, i, l) = rk**l*ear
201 basis%dbf(k, i, l) = (real(l, dp)*rk**(l - 1) - 2._dp*al*rk**(l + 1))*ear
202 basis%ddbf(k, i, l) = (real(l*(l - 1), dp)*rk**(l - 2) - &
203 2._dp*al*real(2*l + 1, dp)*rk**(l) + 4._dp*al*rk**(l + 2))*ear
204 END DO
205 END DO
206 END DO
207
208 NULLIFY (orbitals)
209 mo = maxval(atom%state%maxn_calc)
210 mb = maxval(basis%nbas)
211 CALL create_atom_orbs(orbitals, mb, mo)
212 CALL set_atom(atom, orbitals=orbitals)
213
214 powell_section => section_vals_get_subs_vals(atom_section, "POWELL")
215 CALL atom_fit_grb(atom, basis, iw, powell_section)
216 CALL set_atom(atom, basis=basis)
217
218 ! generate response contractions
219 CALL section_vals_val_get(grb_section, "DELTA_CHARGE", r_val=delta)
220 CALL section_vals_val_get(grb_section, "DERIVATIVES", i_val=nder)
221 IF (iw > 0) THEN
222 WRITE (iw, '(/,A,T76,I5)') " Generate Response Basis Sets with Order ", nder
223 END IF
224
225 state => atom%state
226 ! find HOMO
227 lhomo = -1
228 nhomo = -1
229 emax = -huge(1._dp)
230 DO l = 0, state%maxl_occ
231 DO i = 1, state%maxn_occ(l)
232 IF (atom%orbitals%ener(i, l) > emax) THEN
233 lhomo = l
234 nhomo = i
235 emax = atom%orbitals%ener(i, l)
236 fhomo = state%occupation(l, i)
237 END IF
238 END DO
239 END DO
240
241 s1 = SIZE(atom%orbitals%wfn, 1)
242 s2 = SIZE(atom%orbitals%wfn, 2)
243 ALLOCATE (wfn(s1, s2, 0:lmat, -nder:nder))
244 s2 = maxval(state%maxn_occ) + nder
245 ALLOCATE (rbasis(s1, s2, 0:lmat), qbasis(s1, s2, 0:lmat))
246 rbasis = 0._dp
247 qbasis = 0._dp
248
249 ! calculate integrals
250 ALLOCATE (atint)
251 CALL atom_int_setup(atint, basis, potential=atom%potential, eri_coulomb=.false., eri_exchange=.false.)
252 CALL atom_ppint_setup(atint, basis, potential=atom%potential)
253 IF (atom%pp_calc) THEN
254 NULLIFY (atint%tzora, atint%hdkh)
255 ELSE
256 ! relativistic correction terms
257 CALL atom_relint_setup(atint, basis, atom%relativistic, zcore=real(atom%z, dp))
258 END IF
259 CALL set_atom(atom, integrals=atint)
260
261 CALL calculate_atom(atom, iw=0)
262 DO ider = -nder, nder
263 dene = real(ider, kind=dp)*delta
264 cpassert(fhomo > abs(dene))
265 state%occupation(lhomo, nhomo) = fhomo + dene
266 CALL calculate_atom(atom, iw=0, noguess=.true.)
267 wfn(:, :, :, ider) = atom%orbitals%wfn
268 state%occupation(lhomo, nhomo) = fhomo
269 END DO
270 IF (iw > 0) THEN
271 WRITE (iw, '(A,T76,I5)') " Total number of electronic structure calculations ", 2*nder + 1
272 END IF
273
274 ovlp => atom%integrals%ovlp
275
276 DO l = 0, state%maxl_occ
277 IF (iw > 0) THEN
278 WRITE (iw, '(A,T76,I5)') " Response derivatives for l quantum number ", l
279 END IF
280 ! occupied states
281 DO i = 1, max(state%maxn_occ(l), 1)
282 rbasis(:, i, l) = wfn(:, i, l, 0)
283 END DO
284 ! differentiation
285 DO ider = 1, nder
286 i = max(state%maxn_occ(l), 1)
287 SELECT CASE (ider)
288 CASE (1)
289 rbasis(:, i + 1, l) = 0.5_dp*(wfn(:, i, l, 1) - wfn(:, i, l, -1))/delta
290 CASE (2)
291 rbasis(:, i + 2, l) = 0.25_dp*(wfn(:, i, l, 2) - 2._dp*wfn(:, i, l, 0) + wfn(:, i, l, -2))/delta**2
292 CASE (3)
293 rbasis(:, i + 3, l) = 0.125_dp*(wfn(:, i, l, 3) - 3._dp*wfn(:, i, l, 1) &
294 + 3._dp*wfn(:, i, l, -1) - wfn(:, i, l, -3))/delta**3
295 CASE DEFAULT
296 cpabort("")
297 END SELECT
298 END DO
299
300 ! orthogonalization, use gram-schmidt in order to keep the natural order (semi-core, valence, response) of the wfn.
301 n = state%maxn_occ(l) + nder
302 m = atom%basis%nbas(l)
303 DO i = 1, n
304 DO j = 1, i - 1
305 o = dot_product(rbasis(1:m, j, l), reshape(matmul(ovlp(1:m, 1:m, l), rbasis(1:m, i:i, l)), (/m/)))
306 rbasis(1:m, i, l) = rbasis(1:m, i, l) - o*rbasis(1:m, j, l)
307 END DO
308 o = dot_product(rbasis(1:m, i, l), reshape(matmul(ovlp(1:m, 1:m, l), rbasis(1:m, i:i, l)), (/m/)))
309 rbasis(1:m, i, l) = rbasis(1:m, i, l)/sqrt(o)
310 END DO
311
312 ! check
313 ALLOCATE (amat(n, n))
314 amat(1:n, 1:n) = matmul(transpose(rbasis(1:m, 1:n, l)), matmul(ovlp(1:m, 1:m, l), rbasis(1:m, 1:n, l)))
315 DO i = 1, n
316 amat(i, i) = amat(i, i) - 1._dp
317 END DO
318 IF (maxval(abs(amat)) > 1.e-12) THEN
319 IF (iw > 0) WRITE (iw, '(A,G20.10)') " Orthogonality error ", maxval(abs(amat))
320 END IF
321 DEALLOCATE (amat)
322
323 ! Quickstep normalization
324 expzet = 0.25_dp*real(2*l + 3, dp)
325 prefac = sqrt(rootpi/2._dp**(l + 2)*dfac(2*l + 1))
326 DO i = 1, m
327 zeta = (2._dp*atom%basis%am(i, l))**expzet
328 qbasis(i, 1:n, l) = rbasis(i, 1:n, l)*prefac/zeta
329 END DO
330
331 END DO
332
333 ! check for condition numbers
334 IF (iw > 0) WRITE (iw, '(/,A)') " Condition Number of Valence Response Basis Sets"
337 DO ider = 0, nder
338 NULLIFY (basis_vrb)
339 ALLOCATE (basis_vrb)
340 NULLIFY (basis_vrb%am, basis_vrb%cm, basis_vrb%as, basis_vrb%ns, basis_vrb%bf, &
341 basis_vrb%dbf, basis_vrb%ddbf)
342 ! allocate and initialize the atomic grid
343 NULLIFY (basis_vrb%grid)
344 CALL allocate_grid_atom(basis_vrb%grid)
345 CALL create_grid_atom(basis_vrb%grid, ngp, 1, 1, 0, quadtype)
346 basis_vrb%grid%nr = ngp
347 !
348 basis_vrb%eps_eig = basis_ref%eps_eig
349 basis_vrb%geometrical = .false.
350 basis_vrb%basis_type = cgto_basis
351 basis_vrb%nprim = basis%nprim
352 basis_vrb%nbas = 0
353 DO l = 0, state%maxl_occ
354 basis_vrb%nbas(l) = state%maxn_occ(l) + ider
355 END DO
356 m = maxval(basis_vrb%nprim)
357 n = maxval(basis_vrb%nbas)
358 ALLOCATE (basis_vrb%am(m, 0:lmat))
359 basis_vrb%am = basis%am
360 ! contractions
361 ALLOCATE (basis_vrb%cm(m, n, 0:lmat))
362 DO l = 0, state%maxl_occ
363 m = basis_vrb%nprim(l)
364 n = basis_vrb%nbas(l)
365 basis_vrb%cm(1:m, 1:n, l) = rbasis(1:m, 1:n, l)
366 END DO
367
368 ! initialize basis function on a radial grid
369 nr = basis_vrb%grid%nr
370 m = maxval(basis_vrb%nbas)
371 ALLOCATE (basis_vrb%bf(nr, m, 0:lmat))
372 ALLOCATE (basis_vrb%dbf(nr, m, 0:lmat))
373 ALLOCATE (basis_vrb%ddbf(nr, m, 0:lmat))
374 basis_vrb%bf = 0._dp
375 basis_vrb%dbf = 0._dp
376 basis_vrb%ddbf = 0._dp
377 DO l = 0, lmat
378 DO i = 1, basis_vrb%nprim(l)
379 al = basis_vrb%am(i, l)
380 DO k = 1, nr
381 rk = basis_vrb%grid%rad(k)
382 ear = exp(-al*basis_vrb%grid%rad(k)**2)
383 DO j = 1, basis_vrb%nbas(l)
384 basis_vrb%bf(k, j, l) = basis_vrb%bf(k, j, l) + rk**l*ear*basis_vrb%cm(i, j, l)
385 basis_vrb%dbf(k, j, l) = basis_vrb%dbf(k, j, l) &
386 + (real(l, dp)*rk**(l - 1) - 2._dp*al*rk**(l + 1))*ear*basis_vrb%cm(i, j, l)
387 basis_vrb%ddbf(k, j, l) = basis_vrb%ddbf(k, j, l) + &
388 (real(l*(l - 1), dp)*rk**(l - 2) - 2._dp*al*real(2*l + 1, dp)*rk**(l) + &
389 4._dp*al*rk**(l + 2))*ear*basis_vrb%cm(i, j, l)
390 END DO
391 END DO
392 END DO
393 END DO
394
395 IF (iw > 0) THEN
396 CALL basis_label(abas, basis_vrb%nprim, basis_vrb%nbas)
397 WRITE (iw, '(A,A)') " Basis set ", trim(abas)
398 END IF
399 crad = 2.0_dp*ptable(atom%z)%covalent_radius*bohr
400 cradx = crad*1.00_dp
401 CALL atom_basis_condnum(basis_vrb, cradx, cnum)
402 IF (iw > 0) WRITE (iw, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
403 cradx = crad*1.10_dp
404 CALL atom_basis_condnum(basis_vrb, cradx, cnum)
405 IF (iw > 0) WRITE (iw, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
406 cradx = crad*1.20_dp
407 CALL atom_basis_condnum(basis_vrb, cradx, cnum)
408 IF (iw > 0) WRITE (iw, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
409 vbasis(ider)%basis => basis_vrb
410 END DO
413
414 ! get density maximum
415 ALLOCATE (rho(basis%grid%nr))
416 CALL calculate_atom(atom, iw=0, noguess=.true.)
417 CALL atom_density(rho(:), atom%orbitals%pmat, atom%basis, maxl, typ="RHO")
418 n = sum(maxloc(rho(:)))
419 rmax = basis%grid%rad(n)
420 IF (rmax < 0.1_dp) rmax = 1.0_dp
421 DEALLOCATE (rho)
422
423 ! generate polarization sets
424 maxl = atom%state%maxl_occ
425 CALL section_vals_val_get(grb_section, "NUM_GTO_POLARIZATION", i_val=num_gto)
426 num_pol = num_gto
427 IF (num_gto > 0) THEN
428 IF (iw > 0) THEN
429 WRITE (iw, '(/,A)') " Polarization basis set "
430 END IF
431 ALLOCATE (pbasis(num_gto, num_gto, 0:7), alp(num_gto))
432 pbasis = 0.0_dp
433 ! optimize exponents
434 lval = maxl + 1
435 zval = sqrt(real(2*lval + 2, dp))*real(lval + 1, dp)/(2._dp*rmax)
436 aval = atom%basis%am(1, 0)
437 cval = 2.5_dp
438 rconf = atom%potential%scon
439 CALL atom_fit_pol(zval, rconf, lval, aval, cval, num_gto, iw, powell_section)
440 ! calculate contractions
441 DO i = 1, num_gto
442 alp(i) = aval*cval**(i - 1)
443 END DO
444 ALLOCATE (rho(num_gto))
445 DO l = maxl + 1, min(maxl + num_gto, 7)
446 zval = sqrt(real(2*l + 2, dp))*real(l + 1, dp)/(2._dp*rmax)
447 CALL hydrogenic(zval, rconf, l, alp, num_gto, rho, pbasis(:, :, l))
448 IF (iw > 0) WRITE (iw, '(T5,A,i5,T66,A,F10.4)') &
449 " Polarization basis set contraction for lval=", l, "zval=", zval
450 END DO
451 DEALLOCATE (rho)
452 END IF
453
454 ! generate valence expansion sets
455 maxl = atom%state%maxl_occ
456 CALL section_vals_val_get(grb_section, "NUM_GTO_EXTENDED", i_val=num_gto)
457 CALL section_vals_val_get(grb_section, "EXTENSION_BASIS", i_vals=num_bas)
458 next_bas(0:lmat) = 0
459 IF (num_bas(1) == -1) THEN
460 DO l = 0, maxl
461 next_bas(l) = maxl - l + 1
462 END DO
463 ELSE
464 n = min(SIZE(num_bas, 1), 4)
465 next_bas(0:n - 1) = num_bas(1:n)
466 END IF
467 next_prim = 0
468 DO l = 0, lmat
469 IF (next_bas(l) > 0) next_prim(l) = num_gto
470 END DO
471 IF (iw > 0) THEN
472 CALL basis_label(abas, next_prim, next_bas)
473 WRITE (iw, '(/,A,A)') " Extension basis set ", trim(abas)
474 END IF
475 n = maxval(next_prim)
476 m = maxval(next_bas)
477 ALLOCATE (ebasis(n, n, 0:lmat), ale(n))
478 basis_vrb => vbasis(0)%basis
479 amin = atom%basis%aval/atom%basis%cval**1.5_dp
480 DO i = 1, n
481 ale(i) = amin*atom%basis%cval**(i - 1)
482 END DO
483 ebasis = 0._dp
484 ALLOCATE (rho(n))
485 rconf = 2.0_dp*atom%potential%scon
486 DO l = 0, lmat
487 IF (next_bas(l) < 1) cycle
488 zval = sqrt(real(2*l + 2, dp))*real(l + 1, dp)/(2._dp*rmax)
489 CALL hydrogenic(zval, rconf, l, ale, n, rho, ebasis(:, :, l))
490 IF (iw > 0) WRITE (iw, '(T5,A,i5,T66,A,F10.4)') &
491 " Extension basis set contraction for lval=", l, "zval=", zval
492 END DO
493 DEALLOCATE (rho)
494 ! check for condition numbers
495 IF (iw > 0) WRITE (iw, '(/,A)') " Condition Number of Extended Basis Sets"
498 DO ider = 0, nder
499 NULLIFY (basis_vrb)
500 ALLOCATE (basis_vrb)
501 NULLIFY (basis_vrb%am, basis_vrb%cm, basis_vrb%as, basis_vrb%ns, basis_vrb%bf, &
502 basis_vrb%dbf, basis_vrb%ddbf)
503 ! allocate and initialize the atomic grid
504 NULLIFY (basis_vrb%grid)
505 CALL allocate_grid_atom(basis_vrb%grid)
506 CALL create_grid_atom(basis_vrb%grid, ngp, 1, 1, 0, quadtype)
507 basis_vrb%grid%nr = ngp
508 !
509 basis_vrb%eps_eig = basis_ref%eps_eig
510 basis_vrb%geometrical = .false.
511 basis_vrb%basis_type = cgto_basis
512 basis_vrb%nprim = basis%nprim + next_prim
513 basis_vrb%nbas = 0
514 DO l = 0, state%maxl_occ
515 basis_vrb%nbas(l) = state%maxn_occ(l) + ider + next_bas(l)
516 END DO
517 m = maxval(basis_vrb%nprim)
518 ALLOCATE (basis_vrb%am(m, 0:lmat))
519 ! exponents
520 m = SIZE(basis%am, 1)
521 basis_vrb%am(1:m, :) = basis%am(1:m, :)
522 n = SIZE(ale, 1)
523 DO l = 0, state%maxl_occ
524 basis_vrb%am(m + 1:m + n, l) = ale(1:n)
525 END DO
526 ! contractions
527 m = maxval(basis_vrb%nprim)
528 n = maxval(basis_vrb%nbas)
529 ALLOCATE (basis_vrb%cm(m, n, 0:lmat))
530 basis_vrb%cm = 0.0_dp
531 DO l = 0, state%maxl_occ
532 m = basis%nprim(l)
533 n = state%maxn_occ(l) + ider
534 basis_vrb%cm(1:m, 1:n, l) = rbasis(1:m, 1:n, l)
535 basis_vrb%cm(m + 1:m + next_prim(l), n + 1:n + next_bas(l), l) = ebasis(1:next_prim(l), 1:next_bas(l), l)
536 END DO
537
538 ! initialize basis function on a radial grid
539 nr = basis_vrb%grid%nr
540 m = maxval(basis_vrb%nbas)
541 ALLOCATE (basis_vrb%bf(nr, m, 0:lmat))
542 ALLOCATE (basis_vrb%dbf(nr, m, 0:lmat))
543 ALLOCATE (basis_vrb%ddbf(nr, m, 0:lmat))
544 basis_vrb%bf = 0._dp
545 basis_vrb%dbf = 0._dp
546 basis_vrb%ddbf = 0._dp
547 DO l = 0, lmat
548 DO i = 1, basis_vrb%nprim(l)
549 al = basis_vrb%am(i, l)
550 DO k = 1, nr
551 rk = basis_vrb%grid%rad(k)
552 ear = exp(-al*basis_vrb%grid%rad(k)**2)
553 DO j = 1, basis_vrb%nbas(l)
554 basis_vrb%bf(k, j, l) = basis_vrb%bf(k, j, l) + rk**l*ear*basis_vrb%cm(i, j, l)
555 basis_vrb%dbf(k, j, l) = basis_vrb%dbf(k, j, l) &
556 + (real(l, dp)*rk**(l - 1) - 2._dp*al*rk**(l + 1))*ear*basis_vrb%cm(i, j, l)
557 basis_vrb%ddbf(k, j, l) = basis_vrb%ddbf(k, j, l) + &
558 (real(l*(l - 1), dp)*rk**(l - 2) - 2._dp*al*real(2*l + 1, dp)*rk**(l) + &
559 4._dp*al*rk**(l + 2))*ear*basis_vrb%cm(i, j, l)
560 END DO
561 END DO
562 END DO
563 END DO
564
565 IF (iw > 0) THEN
566 CALL basis_label(abas, basis_vrb%nprim, basis_vrb%nbas)
567 WRITE (iw, '(A,A)') " Basis set ", trim(abas)
568 END IF
569 crad = 2.0_dp*ptable(atom%z)%covalent_radius*bohr
570 cradx = crad*1.00_dp
571 CALL atom_basis_condnum(basis_vrb, cradx, cnum)
572 IF (iw > 0) WRITE (iw, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
573 cradx = crad*1.10_dp
574 CALL atom_basis_condnum(basis_vrb, cradx, cnum)
575 IF (iw > 0) WRITE (iw, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
576 cradx = crad*1.20_dp
577 CALL atom_basis_condnum(basis_vrb, cradx, cnum)
578 IF (iw > 0) WRITE (iw, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
579 vbasis(nder + 1 + ider)%basis => basis_vrb
580 END DO
583
584 ! Tests for energy
585 energy_ref = atom_ref%energy%etot
586 IF (iw > 0) WRITE (iw, '(/,A,A)') " Basis set tests "
587 IF (iw > 0) WRITE (iw, '(T10,A,T59,F22.9)') " Reference Energy [a.u.] ", energy_ref
588 DO ider = 0, 2*nder + 1
589 ! generate an atom type
590 NULLIFY (atom_test)
591 CALL create_atom_type(atom_test)
592 CALL copy_atom_basics(atom_ref, atom_test, state=.true., potential=.true., &
593 optimization=.true., xc=.true.)
594 basis_grb => vbasis(ider)%basis
595 NULLIFY (orbitals)
596 mo = maxval(atom_test%state%maxn_calc)
597 mb = maxval(basis_grb%nbas)
598 CALL create_atom_orbs(orbitals, mb, mo)
599 CALL set_atom(atom_test, orbitals=orbitals, basis=basis_grb)
600 ! calculate integrals
601 ALLOCATE (atint)
602 CALL atom_int_setup(atint, basis_grb, potential=atom_test%potential, eri_coulomb=.false., eri_exchange=.false.)
603 CALL atom_ppint_setup(atint, basis_grb, potential=atom_test%potential)
604 IF (atom_test%pp_calc) THEN
605 NULLIFY (atint%tzora, atint%hdkh)
606 ELSE
607 ! relativistic correction terms
608 CALL atom_relint_setup(atint, basis_grb, atom_test%relativistic, zcore=real(atom_test%z, dp))
609 END IF
610 CALL set_atom(atom_test, integrals=atint)
611 !
612 CALL calculate_atom(atom_test, iw=0)
613 IF (ider <= nder) THEN
614 energy_vb(ider) = atom_test%energy%etot
615 IF (iw > 0) WRITE (iw, '(T10,A,i1,A,T40,F13.9,T59,F22.9)') " GRB (VB)", ider, " Energy [a.u.] ", &
616 energy_ref - energy_vb(ider), energy_vb(ider)
617 ELSE
618 i = ider - nder - 1
619 energy_ex(i) = atom_test%energy%etot
620 IF (iw > 0) WRITE (iw, '(T10,A,i1,A,T40,F13.9,T59,F22.9)') " GRB (EX)", i, " Energy [a.u.] ", &
621 energy_ref - energy_ex(i), energy_ex(i)
622 END IF
623 CALL atom_int_release(atint)
624 CALL atom_ppint_release(atint)
625 CALL atom_relint_release(atint)
626 DEALLOCATE (atom_test%state, atom_test%potential, atint)
627 CALL release_atom_type(atom_test)
628 END DO
629
630 ! Quickstep normalization polarization basis
631 DO l = 0, 7
632 expzet = 0.25_dp*real(2*l + 3, dp)
633 prefac = sqrt(rootpi/2._dp**(l + 2)*dfac(2*l + 1))
634 DO i = 1, num_pol
635 zeta = (2._dp*alp(i))**expzet
636 pbasis(i, 1:num_pol, l) = pbasis(i, 1:num_pol, l)*prefac/zeta
637 END DO
638 END DO
639 ! Quickstep normalization extended basis
640 DO l = 0, lmat
641 expzet = 0.25_dp*real(2*l + 3, dp)
642 prefac = sqrt(rootpi/2._dp**(l + 2)*dfac(2*l + 1))
643 DO i = 1, next_prim(l)
644 zeta = (2._dp*ale(i))**expzet
645 ebasis(i, 1:next_bas(l), l) = ebasis(i, 1:next_bas(l), l)*prefac/zeta
646 END DO
647 END DO
648
649 ! Print basis sets
650 CALL section_vals_val_get(grb_section, "NAME_BODY", c_val=basname)
651 CALL open_file(file_name="GRB_BASIS", file_status="UNKNOWN", file_action="WRITE", unit_number=iunit)
652 ! header info
653 headline = ""
654 headline(1) = "#"
655 headline(2) = "# Generated with CP2K Atom Code"
656 headline(3) = "#"
657 CALL grb_print_basis(header=headline, iunit=iunit)
658 ! valence basis
659 basline(1) = ""
660 WRITE (basline(1), "(T2,A)") adjustl(ptable(atom_ref%z)%symbol)
661 DO ider = 0, nder
662 basline(1) = ""
663 WRITE (basline(1), "(T2,A,T5,A,I1)") adjustl(ptable(atom_ref%z)%symbol), trim(adjustl(basname))//"-VAL-", ider
664 CALL grb_print_basis(header=basline, nprim=vbasis(ider)%basis%nprim(0), nbas=vbasis(ider)%basis%nbas, &
665 al=vbasis(ider)%basis%am(:, 0), gcc=qbasis, iunit=iunit)
666 END DO
667 ! polarization basis
668 maxl = atom_ref%state%maxl_occ
669 DO l = maxl + 1, min(maxl + num_pol, 7)
670 nbas = 0
671 DO i = maxl + 1, l
672 nbas(i) = l - i + 1
673 END DO
674 i = l - maxl
675 basline(1) = ""
676 WRITE (basline(1), "(T2,A,T5,A,I1)") adjustl(ptable(atom_ref%z)%symbol), trim(adjustl(basname))//"-POL-", i
677 CALL grb_print_basis(header=basline, nprim=num_pol, nbas=nbas, al=alp, gcc=pbasis, iunit=iunit)
678 END DO
679 ! extension set
680 IF (sum(next_bas) > 0) THEN
681 basline(1) = ""
682 WRITE (basline(1), "(T2,A,T5,A)") adjustl(ptable(atom_ref%z)%symbol), trim(adjustl(basname))//"-EXT"
683 CALL grb_print_basis(header=basline, nprim=next_prim(0), nbas=next_bas, al=ale, gcc=ebasis, iunit=iunit)
684 END IF
685 !
686 CALL close_file(unit_number=iunit)
687
688 ! clean up
689 IF (ALLOCATED(pbasis)) DEALLOCATE (pbasis)
690 IF (ALLOCATED(alp)) DEALLOCATE (alp)
691 IF (ALLOCATED(ebasis)) DEALLOCATE (ebasis)
692 DEALLOCATE (wfn, rbasis, qbasis, ale)
693
694 DO ider = 0, 10
695 IF (ASSOCIATED(vbasis(ider)%basis)) THEN
696 CALL release_atom_basis(vbasis(ider)%basis)
697 DEALLOCATE (vbasis(ider)%basis)
698 END IF
699 END DO
700
701 CALL atom_int_release(atom%integrals)
702 CALL atom_ppint_release(atom%integrals)
703 CALL atom_relint_release(atom%integrals)
704 CALL release_atom_basis(basis)
705 DEALLOCATE (atom%potential, atom%state, atom%integrals, basis)
707
708 IF (iw > 0) WRITE (iw, '(" ",79("*"))')
709
710 END SUBROUTINE atom_grb_construction
711
712! **************************************************************************************************
713!> \brief Print geometrical response basis set.
714!> \param header banner to print on top of the basis set
715!> \param nprim number of primitive exponents
716!> \param nbas number of basis functions for the given angular momentum
717!> \param al list of the primitive exponents
718!> \param gcc array of contraction coefficients of size
719!> (index-of-the-primitive-exponent, index-of-the-contraction-set, angular-momentum)
720!> \param iunit output file unit
721!> \par History
722!> * 11.2016 created [Juerg Hutter]
723! **************************************************************************************************
724 SUBROUTINE grb_print_basis(header, nprim, nbas, al, gcc, iunit)
725 CHARACTER(len=*), DIMENSION(:), INTENT(IN), &
726 OPTIONAL :: header
727 INTEGER, INTENT(IN), OPTIONAL :: nprim
728 INTEGER, DIMENSION(0:), INTENT(IN), OPTIONAL :: nbas
729 REAL(kind=dp), DIMENSION(:), INTENT(IN), OPTIONAL :: al
730 REAL(kind=dp), DIMENSION(:, :, 0:), INTENT(IN), &
731 OPTIONAL :: gcc
732 INTEGER, INTENT(IN) :: iunit
733
734 INTEGER :: i, j, l, lmax, lmin, nval
735
736 IF (PRESENT(header)) THEN
737 DO i = 1, SIZE(header, 1)
738 IF (header(i) .NE. "") THEN
739 WRITE (iunit, "(A)") trim(header(i))
740 END IF
741 END DO
742 END IF
743
744 IF (PRESENT(nprim)) THEN
745 IF (nprim > 0) THEN
746 cpassert(PRESENT(nbas))
747 cpassert(PRESENT(al))
748 cpassert(PRESENT(gcc))
749
750 DO i = lbound(nbas, 1), ubound(nbas, 1)
751 IF (nbas(i) > 0) THEN
752 lmin = i
753 EXIT
754 END IF
755 END DO
756 DO i = ubound(nbas, 1), lbound(nbas, 1), -1
757 IF (nbas(i) > 0) THEN
758 lmax = i
759 EXIT
760 END IF
761 END DO
762
763 nval = lmax
764 WRITE (iunit, *) " 1"
765 WRITE (iunit, "(40I3)") nval, lmin, lmax, nprim, (nbas(l), l=lmin, lmax)
766 DO i = nprim, 1, -1
767 WRITE (iunit, "(G20.12)", advance="no") al(i)
768 DO l = lmin, lmax
769 DO j = 1, nbas(l)
770 WRITE (iunit, "(F16.10)", advance="no") gcc(i, j, l)
771 END DO
772 END DO
773 WRITE (iunit, *)
774 END DO
775 WRITE (iunit, *)
776 END IF
777 END IF
778
779 END SUBROUTINE grb_print_basis
780
781! **************************************************************************************************
782!> \brief Compose the basis set label:
783!> (np(0)'s'np(1)'p'...) -> [nb(0)'s'nb(1)'p'...] .
784!> \param label basis set label
785!> \param np number of primitive basis functions per angular momentum
786!> \param nb number of contracted basis functions per angular momentum
787!> \par History
788!> * 11.2016 created [Juerg Hutter]
789! **************************************************************************************************
790 SUBROUTINE basis_label(label, np, nb)
791 CHARACTER(len=*), INTENT(out) :: label
792 INTEGER, DIMENSION(0:), INTENT(in) :: np, nb
793
794 INTEGER :: i, l, lmax
795 CHARACTER(len=1), DIMENSION(0:7), PARAMETER :: &
796 lq = (/"s", "p", "d", "f", "g", "h", "i", "k"/)
797
798 label = ""
799 lmax = min(ubound(np, 1), ubound(nb, 1), 7)
800 i = 1
801 label(i:i) = "("
802 DO l = 0, lmax
803 IF (np(l) > 0) THEN
804 i = i + 1
805 IF (np(l) > 9) THEN
806 WRITE (label(i:i + 1), "(I2)") np(l)
807 i = i + 2
808 ELSE
809 WRITE (label(i:i), "(I1)") np(l)
810 i = i + 1
811 END IF
812 label(i:i) = lq(l)
813 END IF
814 END DO
815 i = i + 1
816 label(i:i + 6) = ") --> ["
817 i = i + 6
818 DO l = 0, lmax
819 IF (nb(l) > 0) THEN
820 i = i + 1
821 IF (nb(l) > 9) THEN
822 WRITE (label(i:i + 1), "(I2)") nb(l)
823 i = i + 2
824 ELSE
825 WRITE (label(i:i), "(I1)") nb(l)
826 i = i + 1
827 END IF
828 label(i:i) = lq(l)
829 END IF
830 END DO
831 i = i + 1
832 label(i:i) = "]"
833
834 END SUBROUTINE basis_label
835
836! **************************************************************************************************
837!> \brief Compute the total energy for the given atomic kind and basis set.
838!> \param atom information about the atomic kind
839!> \param basis basis set to fit
840!> \param afun (output) atomic total energy
841!> \param iw output file unit
842!> \par History
843!> * 11.2016 created [Juerg Hutter]
844! **************************************************************************************************
845 SUBROUTINE grb_fit(atom, basis, afun, iw)
846 TYPE(atom_type), POINTER :: atom
847 TYPE(atom_basis_type), POINTER :: basis
848 REAL(dp), INTENT(OUT) :: afun
849 INTEGER, INTENT(IN) :: iw
850
851 INTEGER :: do_eric, do_erie, reltyp, zval
852 LOGICAL :: eri_c, eri_e
853 TYPE(atom_integrals), POINTER :: atint
854 TYPE(atom_potential_type), POINTER :: pot
855
856 ALLOCATE (atint)
857 ! calculate integrals
858 NULLIFY (pot)
859 eri_c = .false.
860 eri_e = .false.
861 pot => atom%potential
862 zval = atom%z
863 reltyp = atom%relativistic
864 do_eric = atom%coulomb_integral_type
865 do_erie = atom%exchange_integral_type
866 IF (do_eric == do_analytic) eri_c = .true.
867 IF (do_erie == do_analytic) eri_e = .true.
868 ! general integrals
869 CALL atom_int_setup(atint, basis, potential=pot, eri_coulomb=eri_c, eri_exchange=eri_e)
870 ! potential
871 CALL atom_ppint_setup(atint, basis, potential=pot)
872 IF (atom%pp_calc) THEN
873 NULLIFY (atint%tzora, atint%hdkh)
874 ELSE
875 ! relativistic correction terms
876 CALL atom_relint_setup(atint, basis, reltyp, zcore=real(zval, dp))
877 END IF
878 CALL set_atom(atom, basis=basis)
879 CALL set_atom(atom, integrals=atint)
880 CALL calculate_atom(atom, iw)
881 afun = atom%energy%etot
882 CALL atom_int_release(atint)
883 CALL atom_ppint_release(atint)
884 CALL atom_relint_release(atint)
885 DEALLOCATE (atint)
886 END SUBROUTINE grb_fit
887
888! **************************************************************************************************
889!> \brief Copy basic information about the atomic kind.
890!> \param atom_ref atom to copy
891!> \param atom new atom to create
892!> \param state also copy electronic state and occupation numbers
893!> \param potential also copy pseudo-potential
894!> \param optimization also copy optimization procedure
895!> \param xc also copy the XC input section
896!> \par History
897!> * 11.2016 created [Juerg Hutter]
898! **************************************************************************************************
899 SUBROUTINE copy_atom_basics(atom_ref, atom, state, potential, optimization, xc)
900 TYPE(atom_type), POINTER :: atom_ref, atom
901 LOGICAL, INTENT(IN), OPTIONAL :: state, potential, optimization, xc
902
903 atom%z = atom_ref%z
904 atom%zcore = atom_ref%zcore
905 atom%pp_calc = atom_ref%pp_calc
906 atom%method_type = atom_ref%method_type
907 atom%relativistic = atom_ref%relativistic
908 atom%coulomb_integral_type = atom_ref%coulomb_integral_type
909 atom%exchange_integral_type = atom_ref%exchange_integral_type
910
911 NULLIFY (atom%potential, atom%state, atom%xc_section)
912 NULLIFY (atom%basis, atom%integrals, atom%orbitals, atom%fmat)
913
914 IF (PRESENT(state)) THEN
915 IF (state) THEN
916 ALLOCATE (atom%state)
917 atom%state = atom_ref%state
918 END IF
919 END IF
920
921 IF (PRESENT(potential)) THEN
922 IF (potential) THEN
923 ALLOCATE (atom%potential)
924 atom%potential = atom_ref%potential
925 END IF
926 END IF
927
928 IF (PRESENT(optimization)) THEN
929 IF (optimization) THEN
930 atom%optimization = atom_ref%optimization
931 END IF
932 END IF
933
934 IF (PRESENT(xc)) THEN
935 IF (xc) THEN
936 atom%xc_section => atom_ref%xc_section
937 END IF
938 END IF
939
940 END SUBROUTINE copy_atom_basics
941
942! **************************************************************************************************
943!> \brief Optimise a geometrical response basis set.
944!> \param atom information about the atomic kind
945!> \param basis basis set to fit
946!> \param iunit output file unit
947!> \param powell_section POWELL input section
948!> \par History
949!> * 11.2016 created [Juerg Hutter]
950! **************************************************************************************************
951 SUBROUTINE atom_fit_grb(atom, basis, iunit, powell_section)
952 TYPE(atom_type), POINTER :: atom
953 TYPE(atom_basis_type), POINTER :: basis
954 INTEGER, INTENT(IN) :: iunit
955 TYPE(section_vals_type), POINTER :: powell_section
956
957 INTEGER :: i, k, l, ll, n10, nr
958 REAL(kind=dp) :: al, cnum, crad, cradx, ear, fopt, rk
959 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: x
960 TYPE(opt_state_type) :: ostate
961
962 cpassert(basis%geometrical)
963
964 CALL section_vals_val_get(powell_section, "ACCURACY", r_val=ostate%rhoend)
965 CALL section_vals_val_get(powell_section, "STEP_SIZE", r_val=ostate%rhobeg)
966 CALL section_vals_val_get(powell_section, "MAX_FUN", i_val=ostate%maxfun)
967
968 ostate%nvar = 2
969 ALLOCATE (x(2))
970 x(1) = sqrt(basis%aval)
971 x(2) = sqrt(basis%cval)
972
973 ostate%nf = 0
974 ostate%iprint = 1
975 ostate%unit = iunit
976
977 ostate%state = 0
978 IF (iunit > 0) THEN
979 WRITE (iunit, '(/," POWELL| Start optimization procedure")')
980 WRITE (iunit, '(" POWELL| Total number of parameters in optimization",T71,I10)') ostate%nvar
981 END IF
982 n10 = max(ostate%maxfun/100, 1)
983
984 fopt = huge(0._dp)
985
986 DO
987
988 IF (ostate%state == 2) THEN
989 basis%am = 0._dp
990 DO l = 0, lmat
991 DO i = 1, basis%nbas(l)
992 ll = i - 1 + basis%start(l)
993 basis%am(i, l) = x(1)*x(1)*(x(2)*x(2))**(ll)
994 END DO
995 END DO
996 basis%aval = x(1)*x(1)
997 basis%cval = x(2)*x(2)
998 basis%bf = 0._dp
999 basis%dbf = 0._dp
1000 basis%ddbf = 0._dp
1001 nr = basis%grid%nr
1002 DO l = 0, lmat
1003 DO i = 1, basis%nbas(l)
1004 al = basis%am(i, l)
1005 DO k = 1, nr
1006 rk = basis%grid%rad(k)
1007 ear = exp(-al*basis%grid%rad(k)**2)
1008 basis%bf(k, i, l) = rk**l*ear
1009 basis%dbf(k, i, l) = (real(l, dp)*rk**(l - 1) - 2._dp*al*rk**(l + 1))*ear
1010 basis%ddbf(k, i, l) = (real(l*(l - 1), dp)*rk**(l - 2) - &
1011 2._dp*al*real(2*l + 1, dp)*rk**(l) + 4._dp*al*rk**(l + 2))*ear
1012 END DO
1013 END DO
1014 END DO
1015 CALL grb_fit(atom, basis, ostate%f, 0)
1016 fopt = min(fopt, ostate%f)
1017 END IF
1018
1019 IF (ostate%state == -1) EXIT
1020
1021 CALL powell_optimize(ostate%nvar, x, ostate)
1022
1023 IF (ostate%nf == 2 .AND. iunit > 0) THEN
1024 WRITE (iunit, '(" POWELL| Initial value of function",T61,F20.10)') ostate%f
1025 END IF
1026 IF (mod(ostate%nf, n10) == 0 .AND. iunit > 0) THEN
1027 WRITE (iunit, '(" POWELL| Reached",i4,"% of maximal function calls",T61,F20.10)') &
1028 int(real(ostate%nf, dp)/real(ostate%maxfun, dp)*100._dp), fopt
1029 END IF
1030
1031 END DO
1032
1033 ostate%state = 8
1034 CALL powell_optimize(ostate%nvar, x, ostate)
1035
1036 IF (iunit > 0) THEN
1037 WRITE (iunit, '(" POWELL| Number of function evaluations",T71,I10)') ostate%nf
1038 WRITE (iunit, '(" POWELL| Final value of function",T61,F20.10)') ostate%fopt
1039 END IF
1040 ! x->basis
1041 basis%am = 0._dp
1042 DO l = 0, lmat
1043 DO i = 1, basis%nbas(l)
1044 ll = i - 1 + basis%start(l)
1045 basis%am(i, l) = x(1)*x(1)*(x(2)*x(2))**(ll)
1046 END DO
1047 END DO
1048 basis%aval = x(1)*x(1)
1049 basis%cval = x(2)*x(2)
1050 basis%bf = 0._dp
1051 basis%dbf = 0._dp
1052 basis%ddbf = 0._dp
1053 nr = basis%grid%nr
1054 DO l = 0, lmat
1055 DO i = 1, basis%nbas(l)
1056 al = basis%am(i, l)
1057 DO k = 1, nr
1058 rk = basis%grid%rad(k)
1059 ear = exp(-al*basis%grid%rad(k)**2)
1060 basis%bf(k, i, l) = rk**l*ear
1061 basis%dbf(k, i, l) = (real(l, dp)*rk**(l - 1) - 2._dp*al*rk**(l + 1))*ear
1062 basis%ddbf(k, i, l) = (real(l*(l - 1), dp)*rk**(l - 2) - &
1063 2._dp*al*real(2*l + 1, dp)*rk**(l) + 4._dp*al*rk**(l + 2))*ear
1064 END DO
1065 END DO
1066 END DO
1067
1068 DEALLOCATE (x)
1069
1070 ! final result
1071 IF (iunit > 0) THEN
1072 WRITE (iunit, '(/,A)') " Optimized Geometrical GTO basis set"
1073 WRITE (iunit, '(A,F15.8,T41,A,F15.8)') " Initial exponent: ", basis%aval, &
1074 " Proportionality factor: ", basis%cval
1075 DO l = 0, lmat
1076 WRITE (iunit, '(T41,A,I2,T76,I5)') " Number of exponents for l=", l, basis%nbas(l)
1077 END DO
1078 END IF
1079
1080 IF (iunit > 0) WRITE (iunit, '(/,A)') " Condition number of uncontracted basis set"
1081 crad = 2.0_dp*ptable(atom%z)%covalent_radius*bohr
1084 cradx = crad*1.00_dp
1085 CALL atom_basis_condnum(basis, cradx, cnum)
1086 IF (iunit > 0) WRITE (iunit, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
1087 cradx = crad*1.10_dp
1088 CALL atom_basis_condnum(basis, cradx, cnum)
1089 IF (iunit > 0) WRITE (iunit, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
1090 cradx = crad*1.20_dp
1091 CALL atom_basis_condnum(basis, cradx, cnum)
1092 IF (iunit > 0) WRITE (iunit, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
1095
1096 END SUBROUTINE atom_fit_grb
1097
1098! **************************************************************************************************
1099!> \brief Optimize 'aval' and 'cval' parameters which define the geometrical response basis set.
1100!> \param zval nuclear charge
1101!> \param rconf confinement radius
1102!> \param lval angular momentum
1103!> \param aval (input/output) exponent of the first Gaussian basis function in the series
1104!> \param cval (input/output) factor of geometrical series
1105!> \param nbas number of basis functions
1106!> \param iunit output file unit
1107!> \param powell_section POWELL input section
1108!> \par History
1109!> * 11.2016 created [Juerg Hutter]
1110! **************************************************************************************************
1111 SUBROUTINE atom_fit_pol(zval, rconf, lval, aval, cval, nbas, iunit, powell_section)
1112 REAL(kind=dp), INTENT(IN) :: zval, rconf
1113 INTEGER, INTENT(IN) :: lval
1114 REAL(kind=dp), INTENT(INOUT) :: aval, cval
1115 INTEGER, INTENT(IN) :: nbas, iunit
1116 TYPE(section_vals_type), POINTER :: powell_section
1117
1118 INTEGER :: i, n10
1119 REAL(kind=dp) :: fopt, x(2)
1120 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: am, ener
1121 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: orb
1122 TYPE(opt_state_type) :: ostate
1123
1124 ALLOCATE (am(nbas), ener(nbas), orb(nbas, nbas))
1125
1126 CALL section_vals_val_get(powell_section, "ACCURACY", r_val=ostate%rhoend)
1127 CALL section_vals_val_get(powell_section, "STEP_SIZE", r_val=ostate%rhobeg)
1128 CALL section_vals_val_get(powell_section, "MAX_FUN", i_val=ostate%maxfun)
1129
1130 ostate%nvar = 2
1131 x(1) = sqrt(aval)
1132 x(2) = sqrt(cval)
1133
1134 ostate%nf = 0
1135 ostate%iprint = 1
1136 ostate%unit = iunit
1137
1138 ostate%state = 0
1139 IF (iunit > 0) THEN
1140 WRITE (iunit, '(/," POWELL| Start optimization procedure")')
1141 WRITE (iunit, '(" POWELL| Total number of parameters in optimization",T71,I10)') ostate%nvar
1142 END IF
1143 n10 = max(ostate%maxfun/100, 1)
1144
1145 fopt = huge(0._dp)
1146
1147 DO
1148
1149 IF (ostate%state == 2) THEN
1150 aval = x(1)*x(1)
1151 cval = x(2)*x(2)
1152 DO i = 1, nbas
1153 am(i) = aval*cval**(i - 1)
1154 END DO
1155 CALL hydrogenic(zval, rconf, lval, am, nbas, ener, orb)
1156 ostate%f = ener(1)
1157 fopt = min(fopt, ostate%f)
1158 END IF
1159
1160 IF (ostate%state == -1) EXIT
1161
1162 CALL powell_optimize(ostate%nvar, x, ostate)
1163
1164 IF (ostate%nf == 2 .AND. iunit > 0) THEN
1165 WRITE (iunit, '(" POWELL| Initial value of function",T61,F20.10)') ostate%f
1166 END IF
1167 IF (mod(ostate%nf, n10) == 0 .AND. iunit > 0) THEN
1168 WRITE (iunit, '(" POWELL| Reached",i4,"% of maximal function calls",T61,F20.10)') &
1169 int(real(ostate%nf, dp)/real(ostate%maxfun, dp)*100._dp), fopt
1170 END IF
1171
1172 END DO
1173
1174 ostate%state = 8
1175 CALL powell_optimize(ostate%nvar, x, ostate)
1176
1177 IF (iunit > 0) THEN
1178 WRITE (iunit, '(" POWELL| Number of function evaluations",T71,I10)') ostate%nf
1179 WRITE (iunit, '(" POWELL| Final value of function",T61,F20.10)') ostate%fopt
1180 END IF
1181 ! x->basis
1182 aval = x(1)*x(1)
1183 cval = x(2)*x(2)
1184
1185 ! final result
1186 IF (iunit > 0) THEN
1187 WRITE (iunit, '(/,A,T51,A,T76,I5)') " Optimized Polarization basis set", &
1188 " Number of exponents:", nbas
1189 WRITE (iunit, '(A,F15.8,T41,A,F15.8)') " Initial exponent: ", aval, &
1190 " Proportionality factor: ", cval
1191 END IF
1192
1193 DEALLOCATE (am, ener, orb)
1194
1195 END SUBROUTINE atom_fit_pol
1196
1197! **************************************************************************************************
1198!> \brief Calculate orbitals of a hydrogen-like atom.
1199!> \param zval nuclear charge
1200!> \param rconf confinement radius
1201!> \param lval angular momentum
1202!> \param am list of basis functions' exponents
1203!> \param nbas number of basis functions
1204!> \param ener orbital energies
1205!> \param orb expansion coefficients of atomic wavefunctions
1206!> \par History
1207!> * 11.2016 created [Juerg Hutter]
1208! **************************************************************************************************
1209 SUBROUTINE hydrogenic(zval, rconf, lval, am, nbas, ener, orb)
1210 REAL(kind=dp), INTENT(IN) :: zval, rconf
1211 INTEGER, INTENT(IN) :: lval
1212 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: am
1213 INTEGER, INTENT(IN) :: nbas
1214 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: ener
1215 REAL(kind=dp), DIMENSION(:, :), INTENT(OUT) :: orb
1216
1217 INTEGER :: info, k, lwork, n
1218 REAL(kind=dp) :: cf
1219 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: w, work
1220 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: confmat, hmat, potmat, smat, tmat
1221
1222 n = nbas
1223 ALLOCATE (smat(n, n), tmat(n, n), potmat(n, n), confmat(n, n), hmat(n, n))
1224 ! calclulate overlap matrix
1225 CALL sg_overlap(smat(1:n, 1:n), lval, am(1:n), am(1:n))
1226 ! calclulate kinetic energy matrix
1227 CALL sg_kinetic(tmat(1:n, 1:n), lval, am(1:n), am(1:n))
1228 ! calclulate core potential matrix
1229 CALL sg_nuclear(potmat(1:n, 1:n), lval, am(1:n), am(1:n))
1230 ! calclulate confinement potential matrix
1231 cf = 0.1_dp
1232 k = 10
1233 CALL sg_conf(confmat, rconf, k, lval, am(1:n), am(1:n))
1234 ! Hamiltionian
1235 hmat(1:n, 1:n) = tmat(1:n, 1:n) - zval*potmat(1:n, 1:n) + cf*confmat(1:n, 1:n)
1236 ! solve
1237 lwork = 100*n
1238 ALLOCATE (w(n), work(lwork))
1239 CALL lapack_ssygv(1, "V", "U", n, hmat, n, smat, n, w, work, lwork, info)
1240 cpassert(info == 0)
1241 orb(1:n, 1:n) = hmat(1:n, 1:n)
1242 ener(1:n) = w(1:n)
1243 DEALLOCATE (w, work)
1244 DEALLOCATE (smat, tmat, potmat, confmat, hmat)
1245
1246 END SUBROUTINE hydrogenic
1247
1248END MODULE atom_grb
subroutine, public sg_nuclear(umat, l, pa, pb)
...
subroutine, public sg_kinetic(kmat, l, pa, pb)
...
subroutine, public sg_conf(gmat, rc, k, l, pa, pb)
...
subroutine, public sg_overlap(smat, l, pa, pb)
...
subroutine, public calculate_atom(atom, iw, noguess, converged)
General routine to perform electronic structure atomic calculations.
subroutine, public atom_grb_construction(atom_info, atom_section, iw)
Construct geometrical response basis set.
Definition atom_grb.F:78
Calculate the atomic operator matrices.
subroutine, public atom_ppint_release(integrals)
Release memory allocated for atomic integrals (core electrons).
subroutine, public atom_int_setup(integrals, basis, potential, eri_coulomb, eri_exchange, all_nu)
Set up atomic integrals.
subroutine, public atom_relint_setup(integrals, basis, reltyp, zcore, alpha)
...
subroutine, public atom_relint_release(integrals)
Release memory allocated for atomic integrals (relativistic effects).
subroutine, public atom_ppint_setup(integrals, basis, potential)
...
subroutine, public atom_int_release(integrals)
Release memory allocated for atomic integrals (valence electrons).
Define the atom type and its sub types.
Definition atom_types.F:15
subroutine, public create_atom_type(atom)
...
Definition atom_types.F:944
integer, parameter, public cgto_basis
Definition atom_types.F:69
integer, parameter, public gto_basis
Definition atom_types.F:69
subroutine, public release_atom_type(atom)
...
Definition atom_types.F:968
integer, parameter, public lmat
Definition atom_types.F:67
subroutine, public set_atom(atom, basis, state, integrals, orbitals, potential, zcore, pp_calc, do_zmp, doread, read_vxc, method_type, relativistic, coulomb_integral_type, exchange_integral_type, fmat)
...
subroutine, public release_atom_basis(basis)
...
Definition atom_types.F:910
subroutine, public create_atom_orbs(orbs, mbas, mo)
...
Some basic routines for atomic calculations.
Definition atom_utils.F:15
subroutine, public atom_density(density, pmat, basis, maxl, typ, rr)
Map the electron density on an atomic radial grid.
Definition atom_utils.F:367
subroutine, public atom_basis_condnum(basis, rad, cnum)
Calculate the condition number of the given atomic basis set.
Definition atom.F:9
Utility routines to open and close files. Tracking of preconnections.
Definition cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition cp_files.F:308
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Definition cp_files.F:119
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_rhf_atom
integer, parameter, public do_rks_atom
integer, parameter, public do_analytic
integer, parameter, public do_uhf_atom
integer, parameter, public do_uks_atom
integer, parameter, public barrier_conf
integer, parameter, public do_rohf_atom
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
Interface to the LAPACK F77 library.
Definition lapack.F:17
Definition of mathematical constants and functions.
real(kind=dp), dimension(-1:2 *maxfac+1), parameter, public dfac
real(kind=dp), parameter, public rootpi
Provides Cartesian and spherical orbital pointers and indices.
subroutine, public init_orbital_pointers(maxl)
Initialize or update the orbital pointers.
subroutine, public deallocate_orbital_pointers()
Deallocate the orbital pointers.
Calculation of the spherical harmonics and the corresponding orbital transformation matrices.
subroutine, public init_spherical_harmonics(maxl, output_unit)
Initialize or update the orbital transformation matrices.
subroutine, public deallocate_spherical_harmonics()
Deallocate the orbital transformation matrices.
Periodic Table related data definitions.
type(atom), dimension(0:nelem), public ptable
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public bohr
Definition physcon.F:147
Definition powell.F:9
subroutine, public powell_optimize(n, x, optstate)
...
Definition powell.F:55
subroutine, public allocate_grid_atom(grid_atom)
Initialize components of the grid_atom_type structure.
subroutine, public create_grid_atom(grid_atom, nr, na, llmax, ll, quadrature)
...
Exchange and Correlation functional calculations.
Definition xc.F:17
Provides all information about a basis set.
Definition atom_types.F:78
Holds atomic orbitals and energies.
Definition atom_types.F:234
Provides all information on states and occupation.
Definition atom_types.F:195
Provides all information about an atomic kind.
Definition atom_types.F:290