(git:34ef472)
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 
8 MODULE atom_grb
9  USE ai_onecenter, ONLY: sg_conf,&
10  sg_kinetic,&
11  sg_nuclear,&
14  USE atom_operators, ONLY: atom_int_release,&
20  USE atom_types, ONLY: &
21  cgto_basis, gto_basis, atom_basis_type, atom_integrals, atom_orbitals, atom_p_type, &
22  atom_potential_type, atom_state, atom_type, create_atom_orbs, create_atom_type, lmat, &
24  USE atom_utils, ONLY: atom_basis_condnum,&
26  USE cp_files, ONLY: close_file,&
27  open_file
28  USE input_constants, ONLY: barrier_conf,&
29  do_analytic,&
30  do_rhf_atom,&
31  do_rks_atom,&
32  do_rohf_atom,&
33  do_uhf_atom,&
36  section_vals_type,&
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,&
51  USE qs_grid_atom, ONLY: allocate_grid_atom,&
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 
66 CONTAINS
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)
124  CASE (do_rks_atom, do_rhf_atom)
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)
137  CALL create_atom_type(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)
706  CALL release_atom_type(atom)
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 
1248 END MODULE atom_grb
subroutine, public sg_nuclear(umat, l, pa, pb)
...
Definition: ai_onecenter.F:137
subroutine, public sg_kinetic(kmat, l, pa, pb)
...
Definition: ai_onecenter.F:102
subroutine, public sg_conf(gmat, rc, k, l, pa, pb)
...
Definition: ai_onecenter.F:414
subroutine, public sg_overlap(smat, l, pa, pb)
...
Definition: ai_onecenter.F:65
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)
...
Definition: atom_types.F:1009
subroutine, public release_atom_basis(basis)
...
Definition: atom_types.F:910
subroutine, public create_atom_orbs(orbs, mbas, mo)
...
Definition: atom_types.F:1055
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_utils.F:2480
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
Definition: header.F:13
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.
Definition: mathconstants.F:16
real(kind=dp), dimension(-1:2 *maxfac+1), parameter, public dfac
Definition: mathconstants.F:61
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.
Definition: qs_grid_atom.F:73
subroutine, public create_grid_atom(grid_atom, nr, na, llmax, ll, quadrature)
...
Definition: qs_grid_atom.F:183
Exchange and Correlation functional calculations.
Definition: xc.F:17