(git:6344619)
Loading...
Searching...
No Matches
gapw_unittest.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
16 USE kinds, ONLY: dp
17 USE libcp2k, ONLY: cp2k_finalize,&
19 USE mathconstants, ONLY: fourpi,&
20 pi
23
24 IMPLICIT NONE
25
26 INTEGER, PARAMETER :: nr = 1601, ng = 32
27 REAL(dp), PARAMETER :: alpha = 1.4_dp, beta = 0.55_dp, box = 12.0_dp, dr = 0.00625_dp
28 REAL(dp), PARAMETER :: charges(2) = [-1.0_dp, 0.3_dp]
29 REAL(dp) :: rad2(nr), weights(nr), delta_rho(nr), potential(nr), shifted(nr)
30 REAL(dp) :: q, g2, periodic_difference, local_difference, correction, error, h, eplus, eminus
31 INTEGER :: i, ix, iy, iz, io_unit
32
33 CALL cp2k_init()
35 CALL check_1c_basis()
36 DO i = 1, nr
37 rad2(i) = ((i - 1)*dr)**2
38 END DO
39 weights = 2.0_dp*dr/3.0_dp
40 weights(2:nr - 1:2) = 4.0_dp*dr/3.0_dp
41 weights(1) = dr/3.0_dp
42 weights(nr) = dr/3.0_dp
43 weights = weights*rad2
44
45 DO i = 1, SIZE(charges)
46 q = charges(i)
47 ! Electron-minus-nuclear l=0 density. Both normalized Gaussians carry q,
48 ! so their difference has zero monopole and a nonzero second moment.
49 delta_rho = q*sqrt(fourpi)*((alpha/pi)**1.5_dp*exp(-alpha*rad2) - &
50 (beta/pi)**1.5_dp*exp(-beta*rad2))
51 potential = gapw_background_potential(-q, box**3, rad2)
52 correction = sum(potential*delta_rho*weights)
53
54 ! Independent reference: exact reciprocal-space Coulomb energies of the
55 ! two periodic Gaussians with G=0 omitted, minus their free-space energies.
56 periodic_difference = 0.0_dp
57 DO iz = -ng, ng
58 DO iy = -ng, ng
59 DO ix = -ng, ng
60 IF (ix == 0 .AND. iy == 0 .AND. iz == 0) cycle
61 g2 = (2.0_dp*pi/box)**2*real(ix*ix + iy*iy + iz*iz, dp)
62 periodic_difference = periodic_difference + &
63 2.0_dp*pi*q*q/box**3/g2*(exp(-g2/(2.0_dp*alpha)) - exp(-g2/(2.0_dp*beta)))
64 END DO
65 END DO
66 END DO
67 local_difference = q*q*(sqrt(alpha) - sqrt(beta))/sqrt(2.0_dp*pi)
68 error = abs(periodic_difference - local_difference - correction)
69 IF (io_unit > 0) WRITE (io_unit, '(A,F8.3,ES16.7)') "GAPW periodic Gaussian background:", q, error
70 IF (error > 1.e-12_dp) error stop "GAPW background disagrees with periodic Gaussian electrostatics"
71
72 ! The explicit volume derivative contributes E_background to each
73 ! diagonal component of -dE/dstrain (local radial functions held fixed).
74 h = 1.e-5_dp
75 shifted = gapw_background_potential(-q, box**3*(1.0_dp + h), rad2)
76 eplus = sum(shifted*delta_rho*weights)
77 shifted = gapw_background_potential(-q, box**3*(1.0_dp - h), rad2)
78 eminus = sum(shifted*delta_rho*weights)
79 IF (abs(-(eplus - eminus)/(2.0_dp*h) - correction) > 1.e-11_dp) THEN
80 error stop "GAPW background volume derivative failed"
81 END IF
82 END DO
83 potential = gapw_background_potential(0.0_dp, box**3, rad2)
84 IF (any(potential /= 0.0_dp)) error stop "Neutral cell has a background potential"
85 CALL cp2k_finalize()
86CONTAINS
87
88! **************************************************************************************************
89!> \brief Check that one-centre basis extension retains diffuse exponents without duplicates.
90! **************************************************************************************************
91 SUBROUTINE check_1c_basis()
92 INTEGER, PARAMETER :: expected(4) = [3, 4, 5, 7]
93 REAL(KIND=dp), PARAMETER :: spacing(4) = [2.5_dp, 2.0_dp, 1.75_dp, 1.5_dp]
94
95 INTEGER :: level
96 REAL(KIND=dp) :: diffuse, ratio
97 TYPE(gto_basis_set_type), POINTER :: extended, orbitals, seed
98
99 NULLIFY (extended, orbitals, seed)
101 CALL init_spherical_harmonics(5, 0)
102 DO level = 1, 4
103 ratio = spacing(level)
104 CALL allocate_gto_basis_set(seed)
105 seed%name = 'two-s-primitives'
106 seed%norm_type = 2
107 seed%nset = 1
108 ALLOCATE (seed%lmin(1), seed%lmax(1), seed%npgf(1), seed%zet(2, 1))
109 seed%lmin = 0
110 seed%lmax = 0
111 seed%npgf = 2
112 ! The second extension candidate duplicates the second soft exponent.
113 ! More diffuse, well-separated candidates must still be admitted.
114 seed%zet(:, 1) = [1.0_dp, 1.0_dp/sqrt(ratio)]
115 CALL create_primitive_basis_set(seed, orbitals)
116 orbitals%set_radius = 0.0_dp
117 CALL create_1c_basis(orbitals, orbitals, extended, level)
118 diffuse = 1.0_dp/(ratio*sqrt(ratio))
119 IF (io_unit > 0) WRITE (io_unit, '(A,I2,A,I3)') &
120 'GAPW extension level ', level, ': added s primitives ', extended%npgf(2)
121 IF (extended%npgf(2) /= expected(level)) error stop 'GAPW extension lost admissible diffuse exponents'
122 IF (minval(abs(extended%zet(:extended%npgf(2), 2) - diffuse)) > 1.e-12_dp) THEN
123 error stop 'GAPW extension is missing the first admissible diffuse exponent'
124 END IF
125 IF (minval(abs(extended%zet(:extended%npgf(2), 2) - seed%zet(2, 1))) < 1.e-12_dp) THEN
126 error stop 'GAPW extension duplicated an existing soft exponent'
127 END IF
128 CALL deallocate_gto_basis_set(extended)
129 CALL deallocate_gto_basis_set(orbitals)
130 CALL deallocate_gto_basis_set(seed)
131 END DO
132 END SUBROUTINE check_1c_basis
133END PROGRAM gapw_unittest
program gapw_unittest
subroutine check_1c_basis()
Check that one-centre basis extension retains diffuse exponents without duplicates.
subroutine, public deallocate_gto_basis_set(gto_basis_set)
...
subroutine, public allocate_gto_basis_set(gto_basis_set)
...
subroutine, public create_primitive_basis_set(basis_set, pbasis, lmax)
...
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
subroutine, public create_1c_basis(orb_basis, soft_basis, gapw_1c_basis, basis_1c_level)
create the one center basis from the orbital basis
pure real(dp) function, dimension(size(rad2)), public gapw_background_potential(net_charge, volume, rad2)
l=0 potential for the periodic mean-potential correction. For a neutral localized difference delta_rh...
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
CP2K C/C++ interface.
Definition libcp2k.F:20
subroutine, public cp2k_finalize()
...
Definition libcp2k.F:139
subroutine, public cp2k_init()
...
Definition libcp2k.F:104
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
real(kind=dp), parameter, public fourpi
Provides Cartesian and spherical orbital pointers and indices.
subroutine, public init_orbital_pointers(maxl)
Initialize or update 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.