78 TYPE(
atom_p_type),
DIMENSION(:, :),
POINTER :: atom_info
80 INTEGER,
INTENT(IN) :: iw
82 CHARACTER(len=default_string_length) :: abas, basname
83 CHARACTER(len=default_string_length),
DIMENSION(1) :: basline
84 CHARACTER(len=default_string_length),
DIMENSION(3) :: headline
85 INTEGER :: i, ider, is, iunit, j, k, l, lhomo, ll, &
86 lval, m, maxl, mb, method, mo, n, &
87 nder, ngp, nhomo, nr, num_gto, &
88 num_pol, quadtype, s1, s2
89 INTEGER,
DIMENSION(0:7) :: nbas
90 INTEGER,
DIMENSION(0:lmat) :: next_bas, next_prim
91 INTEGER,
DIMENSION(:),
POINTER :: num_bas
92 REAL(kind=
dp) :: al, amin, aval, cnum, crad, cradx, cval, delta, dene, ear, emax, &
93 energy_ex(0:
lmat), energy_ref, energy_vb(0:
lmat), expzet, fhomo, o, prefac, rconf, rk, &
94 rmax, scon, zeta, zval
95 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: ale, alp, rho
96 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: amat
97 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ebasis, pbasis, qbasis, rbasis
98 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :, :) :: wfn
99 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: ovlp
100 TYPE(
atom_basis_type),
POINTER :: basis, basis_grb, basis_ref, basis_vrb
108 IF (iw > 0)
WRITE (iw,
'(/," ",79("*"),/,T28,A,/," ",79("*"))')
"GEOMETRICAL RESPONSE BASIS"
111 NULLIFY (vbasis(i)%basis)
115 IF (iw > 0 .AND. is > 1)
THEN
116 WRITE (iw,
'(/,A,/)')
" WARNING: Only use first electronic structure/method for basis set generation"
118 atom_ref => atom_info(1, 1)%atom
121 method = atom_ref%method_type
126 cpabort(
"Unrestricted methods not allowed for GRB generation")
137 CALL copy_atom_basics(atom_ref,
atom, state=.true., potential=.true., optimization=.true.,
xc=.true.)
139 atom%potential%confinement = .true.
141 atom%potential%acon = 200._dp
142 atom%potential%rcon = 4._dp
144 atom%potential%scon = scon
146 basis_ref => atom_ref%basis
148 NULLIFY (basis%am, basis%cm, basis%as, basis%ns, basis%bf, basis%dbf, basis%ddbf)
156 cpabort(
"# point radial grid < 0")
160 maxl =
atom%state%maxl_occ
164 basis%nbas(0:maxl) = num_gto
165 basis%nprim = basis%nbas
168 m = maxval(basis%nbas)
169 ALLOCATE (basis%am(m, 0:
lmat))
172 DO i = 1, basis%nbas(l)
174 basis%am(i, l) = aval*cval**(ll)
178 basis%eps_eig = basis_ref%eps_eig
179 basis%geometrical = .true.
186 m = maxval(basis%nbas)
187 ALLOCATE (basis%bf(nr, m, 0:
lmat))
188 ALLOCATE (basis%dbf(nr, m, 0:
lmat))
189 ALLOCATE (basis%ddbf(nr, m, 0:
lmat))
194 DO i = 1, basis%nbas(l)
197 rk = basis%grid%rad(k)
198 ear = exp(-al*basis%grid%rad(k)**2)
199 basis%bf(k, i, l) = rk**l*ear
200 basis%dbf(k, i, l) = (real(l,
dp)*rk**(l - 1) - 2._dp*al*rk**(l + 1))*ear
201 basis%ddbf(k, i, l) = (real(l*(l - 1),
dp)*rk**(l - 2) - &
202 2._dp*al*real(2*l + 1,
dp)*rk**(l) + 4._dp*al*rk**(l + 2))*ear
208 mo = maxval(
atom%state%maxn_calc)
209 mb = maxval(basis%nbas)
214 CALL atom_fit_grb(
atom, basis, iw, powell_section)
221 WRITE (iw,
'(/,A,T76,I5)')
" Generate Response Basis Sets with Order ", nder
229 DO l = 0, state%maxl_occ
230 DO i = 1, state%maxn_occ(l)
231 IF (
atom%orbitals%ener(i, l) > emax)
THEN
234 emax =
atom%orbitals%ener(i, l)
235 fhomo = state%occupation(l, i)
240 s1 =
SIZE(
atom%orbitals%wfn, 1)
241 s2 =
SIZE(
atom%orbitals%wfn, 2)
242 ALLOCATE (wfn(s1, s2, 0:
lmat, -nder:nder))
243 s2 = maxval(state%maxn_occ) + nder
244 ALLOCATE (rbasis(s1, s2, 0:
lmat), qbasis(s1, s2, 0:
lmat))
250 CALL atom_int_setup(atint, basis, potential=
atom%potential, eri_coulomb=.false., eri_exchange=.false.)
252 IF (
atom%pp_calc)
THEN
253 NULLIFY (atint%tzora, atint%hdkh)
261 DO ider = -nder, nder
262 dene = real(ider, kind=
dp)*delta
263 cpassert(fhomo > abs(dene))
264 state%occupation(lhomo, nhomo) = fhomo + dene
266 wfn(:, :, :, ider) =
atom%orbitals%wfn
267 state%occupation(lhomo, nhomo) = fhomo
270 WRITE (iw,
'(A,T76,I5)')
" Total number of electronic structure calculations ", 2*nder + 1
273 ovlp =>
atom%integrals%ovlp
275 DO l = 0, state%maxl_occ
277 WRITE (iw,
'(A,T76,I5)')
" Response derivatives for l quantum number ", l
280 DO i = 1, max(state%maxn_occ(l), 1)
281 rbasis(:, i, l) = wfn(:, i, l, 0)
285 i = max(state%maxn_occ(l), 1)
288 rbasis(:, i + 1, l) = 0.5_dp*(wfn(:, i, l, 1) - wfn(:, i, l, -1))/delta
290 rbasis(:, i + 2, l) = 0.25_dp*(wfn(:, i, l, 2) - 2._dp*wfn(:, i, l, 0) + wfn(:, i, l, -2))/delta**2
292 rbasis(:, i + 3, l) = 0.125_dp*(wfn(:, i, l, 3) - 3._dp*wfn(:, i, l, 1) &
293 + 3._dp*wfn(:, i, l, -1) - wfn(:, i, l, -3))/delta**3
300 n = state%maxn_occ(l) + nder
301 m =
atom%basis%nbas(l)
304 o = dot_product(rbasis(1:m, j, l), reshape(matmul(ovlp(1:m, 1:m, l), rbasis(1:m, i:i, l)), (/m/)))
305 rbasis(1:m, i, l) = rbasis(1:m, i, l) - o*rbasis(1:m, j, l)
307 o = dot_product(rbasis(1:m, i, l), reshape(matmul(ovlp(1:m, 1:m, l), rbasis(1:m, i:i, l)), (/m/)))
308 rbasis(1:m, i, l) = rbasis(1:m, i, l)/sqrt(o)
312 ALLOCATE (amat(n, n))
313 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 amat(i, i) = amat(i, i) - 1._dp
317 IF (maxval(abs(amat)) > 1.e-12)
THEN
318 IF (iw > 0)
WRITE (iw,
'(A,G20.10)')
" Orthogonality error ", maxval(abs(amat))
323 expzet = 0.25_dp*real(2*l + 3,
dp)
324 prefac = sqrt(
rootpi/2._dp**(l + 2)*
dfac(2*l + 1))
326 zeta = (2._dp*
atom%basis%am(i, l))**expzet
327 qbasis(i, 1:n, l) = rbasis(i, 1:n, l)*prefac/zeta
333 IF (iw > 0)
WRITE (iw,
'(/,A)')
" Condition Number of Valence Response Basis Sets"
339 NULLIFY (basis_vrb%am, basis_vrb%cm, basis_vrb%as, basis_vrb%ns, basis_vrb%bf, &
340 basis_vrb%dbf, basis_vrb%ddbf)
342 NULLIFY (basis_vrb%grid)
345 basis_vrb%grid%nr = ngp
347 basis_vrb%eps_eig = basis_ref%eps_eig
348 basis_vrb%geometrical = .false.
350 basis_vrb%nprim = basis%nprim
352 DO l = 0, state%maxl_occ
353 basis_vrb%nbas(l) = state%maxn_occ(l) + ider
355 m = maxval(basis_vrb%nprim)
356 n = maxval(basis_vrb%nbas)
357 ALLOCATE (basis_vrb%am(m, 0:
lmat))
358 basis_vrb%am = basis%am
360 ALLOCATE (basis_vrb%cm(m, n, 0:
lmat))
361 DO l = 0, state%maxl_occ
362 m = basis_vrb%nprim(l)
363 n = basis_vrb%nbas(l)
364 basis_vrb%cm(1:m, 1:n, l) = rbasis(1:m, 1:n, l)
368 nr = basis_vrb%grid%nr
369 m = maxval(basis_vrb%nbas)
370 ALLOCATE (basis_vrb%bf(nr, m, 0:
lmat))
371 ALLOCATE (basis_vrb%dbf(nr, m, 0:
lmat))
372 ALLOCATE (basis_vrb%ddbf(nr, m, 0:
lmat))
374 basis_vrb%dbf = 0._dp
375 basis_vrb%ddbf = 0._dp
377 DO i = 1, basis_vrb%nprim(l)
378 al = basis_vrb%am(i, l)
380 rk = basis_vrb%grid%rad(k)
381 ear = exp(-al*basis_vrb%grid%rad(k)**2)
382 DO j = 1, basis_vrb%nbas(l)
383 basis_vrb%bf(k, j, l) = basis_vrb%bf(k, j, l) + rk**l*ear*basis_vrb%cm(i, j, l)
384 basis_vrb%dbf(k, j, l) = basis_vrb%dbf(k, j, l) &
385 + (real(l,
dp)*rk**(l - 1) - 2._dp*al*rk**(l + 1))*ear*basis_vrb%cm(i, j, l)
386 basis_vrb%ddbf(k, j, l) = basis_vrb%ddbf(k, j, l) + &
387 (real(l*(l - 1),
dp)*rk**(l - 2) - 2._dp*al*real(2*l + 1,
dp)*rk**(l) + &
388 4._dp*al*rk**(l + 2))*ear*basis_vrb%cm(i, j, l)
395 CALL basis_label(abas, basis_vrb%nprim, basis_vrb%nbas)
396 WRITE (iw,
'(A,A)')
" Basis set ", trim(abas)
401 IF (iw > 0)
WRITE (iw,
'(T5,A,F15.3,T50,A,F14.4)')
" Lattice constant:", cradx,
"Condition number:", cnum
404 IF (iw > 0)
WRITE (iw,
'(T5,A,F15.3,T50,A,F14.4)')
" Lattice constant:", cradx,
"Condition number:", cnum
407 IF (iw > 0)
WRITE (iw,
'(T5,A,F15.3,T50,A,F14.4)')
" Lattice constant:", cradx,
"Condition number:", cnum
408 vbasis(ider)%basis => basis_vrb
414 ALLOCATE (rho(basis%grid%nr))
417 n = sum(maxloc(rho(:)))
418 rmax = basis%grid%rad(n)
419 IF (rmax < 0.1_dp) rmax = 1.0_dp
423 maxl =
atom%state%maxl_occ
426 IF (num_gto > 0)
THEN
428 WRITE (iw,
'(/,A)')
" Polarization basis set "
430 ALLOCATE (pbasis(num_gto, num_gto, 0:7), alp(num_gto))
434 zval = sqrt(real(2*lval + 2,
dp))*real(lval + 1,
dp)/(2._dp*rmax)
435 aval =
atom%basis%am(1, 0)
437 rconf =
atom%potential%scon
438 CALL atom_fit_pol(zval, rconf, lval, aval, cval, num_gto, iw, powell_section)
441 alp(i) = aval*cval**(i - 1)
443 ALLOCATE (rho(num_gto))
444 DO l = maxl + 1, min(maxl + num_gto, 7)
445 zval = sqrt(real(2*l + 2,
dp))*real(l + 1,
dp)/(2._dp*rmax)
446 CALL hydrogenic(zval, rconf, l, alp, num_gto, rho, pbasis(:, :, l))
447 IF (iw > 0)
WRITE (iw,
'(T5,A,i5,T66,A,F10.4)') &
448 " Polarization basis set contraction for lval=", l,
"zval=", zval
454 maxl =
atom%state%maxl_occ
458 IF (num_bas(1) == -1)
THEN
460 next_bas(l) = maxl - l + 1
463 n = min(
SIZE(num_bas, 1), 4)
464 next_bas(0:n - 1) = num_bas(1:n)
468 IF (next_bas(l) > 0) next_prim(l) = num_gto
471 CALL basis_label(abas, next_prim, next_bas)
472 WRITE (iw,
'(/,A,A)')
" Extension basis set ", trim(abas)
474 n = maxval(next_prim)
476 ALLOCATE (ebasis(n, n, 0:
lmat), ale(n))
477 basis_vrb => vbasis(0)%basis
478 amin =
atom%basis%aval/
atom%basis%cval**1.5_dp
480 ale(i) = amin*
atom%basis%cval**(i - 1)
484 rconf = 2.0_dp*
atom%potential%scon
486 IF (next_bas(l) < 1) cycle
487 zval = sqrt(real(2*l + 2,
dp))*real(l + 1,
dp)/(2._dp*rmax)
488 CALL hydrogenic(zval, rconf, l, ale, n, rho, ebasis(:, :, l))
489 IF (iw > 0)
WRITE (iw,
'(T5,A,i5,T66,A,F10.4)') &
490 " Extension basis set contraction for lval=", l,
"zval=", zval
494 IF (iw > 0)
WRITE (iw,
'(/,A)')
" Condition Number of Extended Basis Sets"
500 NULLIFY (basis_vrb%am, basis_vrb%cm, basis_vrb%as, basis_vrb%ns, basis_vrb%bf, &
501 basis_vrb%dbf, basis_vrb%ddbf)
503 NULLIFY (basis_vrb%grid)
506 basis_vrb%grid%nr = ngp
508 basis_vrb%eps_eig = basis_ref%eps_eig
509 basis_vrb%geometrical = .false.
511 basis_vrb%nprim = basis%nprim + next_prim
513 DO l = 0, state%maxl_occ
514 basis_vrb%nbas(l) = state%maxn_occ(l) + ider + next_bas(l)
516 m = maxval(basis_vrb%nprim)
517 ALLOCATE (basis_vrb%am(m, 0:
lmat))
519 m =
SIZE(basis%am, 1)
520 basis_vrb%am(1:m, :) = basis%am(1:m, :)
522 DO l = 0, state%maxl_occ
523 basis_vrb%am(m + 1:m + n, l) = ale(1:n)
526 m = maxval(basis_vrb%nprim)
527 n = maxval(basis_vrb%nbas)
528 ALLOCATE (basis_vrb%cm(m, n, 0:
lmat))
529 basis_vrb%cm = 0.0_dp
530 DO l = 0, state%maxl_occ
532 n = state%maxn_occ(l) + ider
533 basis_vrb%cm(1:m, 1:n, l) = rbasis(1:m, 1:n, l)
534 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)
538 nr = basis_vrb%grid%nr
539 m = maxval(basis_vrb%nbas)
540 ALLOCATE (basis_vrb%bf(nr, m, 0:
lmat))
541 ALLOCATE (basis_vrb%dbf(nr, m, 0:
lmat))
542 ALLOCATE (basis_vrb%ddbf(nr, m, 0:
lmat))
544 basis_vrb%dbf = 0._dp
545 basis_vrb%ddbf = 0._dp
547 DO i = 1, basis_vrb%nprim(l)
548 al = basis_vrb%am(i, l)
550 rk = basis_vrb%grid%rad(k)
551 ear = exp(-al*basis_vrb%grid%rad(k)**2)
552 DO j = 1, basis_vrb%nbas(l)
553 basis_vrb%bf(k, j, l) = basis_vrb%bf(k, j, l) + rk**l*ear*basis_vrb%cm(i, j, l)
554 basis_vrb%dbf(k, j, l) = basis_vrb%dbf(k, j, l) &
555 + (real(l,
dp)*rk**(l - 1) - 2._dp*al*rk**(l + 1))*ear*basis_vrb%cm(i, j, l)
556 basis_vrb%ddbf(k, j, l) = basis_vrb%ddbf(k, j, l) + &
557 (real(l*(l - 1),
dp)*rk**(l - 2) - 2._dp*al*real(2*l + 1,
dp)*rk**(l) + &
558 4._dp*al*rk**(l + 2))*ear*basis_vrb%cm(i, j, l)
565 CALL basis_label(abas, basis_vrb%nprim, basis_vrb%nbas)
566 WRITE (iw,
'(A,A)')
" Basis set ", trim(abas)
571 IF (iw > 0)
WRITE (iw,
'(T5,A,F15.3,T50,A,F14.4)')
" Lattice constant:", cradx,
"Condition number:", cnum
574 IF (iw > 0)
WRITE (iw,
'(T5,A,F15.3,T50,A,F14.4)')
" Lattice constant:", cradx,
"Condition number:", cnum
577 IF (iw > 0)
WRITE (iw,
'(T5,A,F15.3,T50,A,F14.4)')
" Lattice constant:", cradx,
"Condition number:", cnum
578 vbasis(nder + 1 + ider)%basis => basis_vrb
584 energy_ref = atom_ref%energy%etot
585 IF (iw > 0)
WRITE (iw,
'(/,A,A)')
" Basis set tests "
586 IF (iw > 0)
WRITE (iw,
'(T10,A,T59,F22.9)')
" Reference Energy [a.u.] ", energy_ref
587 DO ider = 0, 2*nder + 1
591 CALL copy_atom_basics(atom_ref, atom_test, state=.true., potential=.true., &
592 optimization=.true.,
xc=.true.)
593 basis_grb => vbasis(ider)%basis
595 mo = maxval(atom_test%state%maxn_calc)
596 mb = maxval(basis_grb%nbas)
598 CALL set_atom(atom_test, orbitals=orbitals, basis=basis_grb)
601 CALL atom_int_setup(atint, basis_grb, potential=atom_test%potential, eri_coulomb=.false., eri_exchange=.false.)
603 IF (atom_test%pp_calc)
THEN
604 NULLIFY (atint%tzora, atint%hdkh)
607 CALL atom_relint_setup(atint, basis_grb, atom_test%relativistic, zcore=real(atom_test%z,
dp))
609 CALL set_atom(atom_test, integrals=atint)
612 IF (ider <= nder)
THEN
613 energy_vb(ider) = atom_test%energy%etot
614 IF (iw > 0)
WRITE (iw,
'(T10,A,i1,A,T40,F13.9,T59,F22.9)')
" GRB (VB)", ider,
" Energy [a.u.] ", &
615 energy_ref - energy_vb(ider), energy_vb(ider)
618 energy_ex(i) = atom_test%energy%etot
619 IF (iw > 0)
WRITE (iw,
'(T10,A,i1,A,T40,F13.9,T59,F22.9)')
" GRB (EX)", i,
" Energy [a.u.] ", &
620 energy_ref - energy_ex(i), energy_ex(i)
625 DEALLOCATE (atom_test%state, atom_test%potential, atint)
631 expzet = 0.25_dp*real(2*l + 3,
dp)
632 prefac = sqrt(
rootpi/2._dp**(l + 2)*
dfac(2*l + 1))
634 zeta = (2._dp*alp(i))**expzet
635 pbasis(i, 1:num_pol, l) = pbasis(i, 1:num_pol, l)*prefac/zeta
640 expzet = 0.25_dp*real(2*l + 3,
dp)
641 prefac = sqrt(
rootpi/2._dp**(l + 2)*
dfac(2*l + 1))
642 DO i = 1, next_prim(l)
643 zeta = (2._dp*ale(i))**expzet
644 ebasis(i, 1:next_bas(l), l) = ebasis(i, 1:next_bas(l), l)*prefac/zeta
650 CALL open_file(file_name=
"GRB_BASIS", file_status=
"UNKNOWN", file_action=
"WRITE", unit_number=iunit)
654 headline(2) =
"# Generated with CP2K Atom Code"
656 CALL grb_print_basis(
header=headline, iunit=iunit)
659 WRITE (basline(1),
"(T2,A)") adjustl(
ptable(atom_ref%z)%symbol)
662 WRITE (basline(1),
"(T2,A,T5,A,I1)") adjustl(
ptable(atom_ref%z)%symbol), trim(adjustl(basname))//
"-VAL-", ider
663 CALL grb_print_basis(
header=basline, nprim=vbasis(ider)%basis%nprim(0), nbas=vbasis(ider)%basis%nbas, &
664 al=vbasis(ider)%basis%am(:, 0), gcc=qbasis, iunit=iunit)
667 maxl = atom_ref%state%maxl_occ
668 DO l = maxl + 1, min(maxl + num_pol, 7)
675 WRITE (basline(1),
"(T2,A,T5,A,I1)") adjustl(
ptable(atom_ref%z)%symbol), trim(adjustl(basname))//
"-POL-", i
676 CALL grb_print_basis(
header=basline, nprim=num_pol, nbas=nbas, al=alp, gcc=pbasis, iunit=iunit)
679 IF (sum(next_bas) > 0)
THEN
681 WRITE (basline(1),
"(T2,A,T5,A)") adjustl(
ptable(atom_ref%z)%symbol), trim(adjustl(basname))//
"-EXT"
682 CALL grb_print_basis(
header=basline, nprim=next_prim(0), nbas=next_bas, al=ale, gcc=ebasis, iunit=iunit)
688 IF (
ALLOCATED(pbasis))
DEALLOCATE (pbasis)
689 IF (
ALLOCATED(alp))
DEALLOCATE (alp)
690 IF (
ALLOCATED(ebasis))
DEALLOCATE (ebasis)
691 DEALLOCATE (wfn, rbasis, qbasis, ale)
694 IF (
ASSOCIATED(vbasis(ider)%basis))
THEN
696 DEALLOCATE (vbasis(ider)%basis)
704 DEALLOCATE (
atom%potential,
atom%state,
atom%integrals, basis)
707 IF (iw > 0)
WRITE (iw,
'(" ",79("*"))')