(git:08825b9)
Loading...
Searching...
No Matches
mt_util.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
8! **************************************************************************************************
9MODULE mt_util
10 USE bibliography, ONLY: martyna1999,&
11 cite_reference
12 USE kinds, ONLY: dp
13 USE mathconstants, ONLY: fourpi,&
14 oorootpi,&
15 pi
17 USE pw_methods, ONLY: pw_axpy,&
20 USE pw_pool_types, ONLY: pw_pool_create,&
23 USE pw_types, ONLY: pw_c1d_gs_type,&
25#include "../base/base_uses.f90"
26
27 IMPLICIT NONE
28
29 PRIVATE
30 LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
31 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mt_util'
32
33 INTEGER, PARAMETER, PUBLIC :: mt2d = 1101, &
34 mt1d = 1102, &
35 mt0d = 1103
36
38CONTAINS
39
40! **************************************************************************************************
41!> \brief MT2D Coulomb kernel and its affine strain derivative in the periodic plane.
42!> \param g Cartesian reciprocal vector, transformed by the inverse transpose of the strain.
43!> \param special_dimension Cartesian direction normal to the slab.
44!> \param slab_size Cell thickness in the nonperiodic direction, fixed for in-plane strain.
45!> \param kernel Reciprocal Coulomb kernel, including the existing MT2D G=0 convention.
46!> \param strain Kernel derivative with respect to in-plane affine strain.
47! **************************************************************************************************
48 SUBROUTINE mt2d_kernel_strain(g, special_dimension, slab_size, kernel, strain)
49 REAL(kind=dp), INTENT(IN) :: g(3)
50 INTEGER, INTENT(IN) :: special_dimension
51 REAL(kind=dp), INTENT(IN) :: slab_size
52 REAL(kind=dp), INTENT(OUT) :: kernel, strain(3, 3)
53
54 INTEGER :: alpha, beta
55 REAL(kind=dp) :: f, g2, k, parallel(3), q, radius
56
57 cpassert(special_dimension >= 1 .AND. special_dimension <= 3)
58 cpassert(slab_size > 0.0_dp)
59 strain = 0.0_dp
60 g2 = sum(g**2)
61 IF (g2 == 0.0_dp) THEN
62 ! This kernel is independent of in-plane strain. Its volume term is
63 ! already included in the Hartree energy contribution to the virial.
64 kernel = pi*slab_size**2/2.0_dp
65 RETURN
66 END IF
67 parallel = g
68 parallel(special_dimension) = 0.0_dp
69 k = norm2(parallel)
70 radius = slab_size/2.0_dp
71 q = cos(g(special_dimension)*radius)*exp(-k*radius)
72 f = 1.0_dp - q
73 kernel = fourpi/g2*f
74 ! For k=0 the reciprocal vector is unchanged by every in-plane strain.
75 ! This also avoids dividing by k at the even-normal modes where K=0.
76 IF (k == 0.0_dp) RETURN
77 DO alpha = 1, 3
78 IF (alpha == special_dimension) cycle
79 DO beta = alpha, 3
80 IF (beta == special_dimension) cycle
81 strain(alpha, beta) = fourpi/g2*g(alpha)*g(beta)*(2.0_dp*f/g2 - q*radius/k)
82 strain(beta, alpha) = strain(alpha, beta)
83 END DO
84 END DO
85 END SUBROUTINE mt2d_kernel_strain
86
87! **************************************************************************************************
88!> \brief Initialize the Martyna && Tuckerman Poisson Solver
89!> \param screen_function ...
90!> \param pw_pool ...
91!> \param method ...
92!> \param alpha ...
93!> \param special_dimension ...
94!> \param slab_size ...
95!> \param super_ref_pw_grid ...
96!> \author Teodoro Laino (16.06.2004)
97! **************************************************************************************************
98 SUBROUTINE mtin_create_screen_fn(screen_function, pw_pool, method, alpha, &
99 special_dimension, slab_size, super_ref_pw_grid)
100 TYPE(pw_c1d_gs_type), POINTER :: screen_function
101 TYPE(pw_pool_type), POINTER :: pw_pool
102 INTEGER, INTENT(IN) :: method
103 REAL(kind=dp), INTENT(in) :: alpha
104 INTEGER, INTENT(IN) :: special_dimension
105 REAL(kind=dp), INTENT(in) :: slab_size
106 TYPE(pw_grid_type), POINTER :: super_ref_pw_grid
107
108 CHARACTER(len=*), PARAMETER :: routinen = 'MTin_create_screen_fn'
109
110 INTEGER :: handle, ig, iz
111 REAL(kind=dp) :: alpha2, g2, g3d, gxy, gz, zlength
112 TYPE(pw_c1d_gs_type), POINTER :: vlocg
113 TYPE(pw_pool_type), POINTER :: pw_pool_aux
114 TYPE(pw_r3d_rs_type), POINTER :: vloc
115
116 CALL timeset(routinen, handle)
117 NULLIFY (vloc, vlocg, pw_pool_aux)
118 !
119 ! For Martyna-Tuckerman we set up an auxiliary pw_pool at an higher cutoff
120 !
121 CALL cite_reference(martyna1999)
122 IF (ASSOCIATED(super_ref_pw_grid)) THEN
123 CALL pw_pool_create(pw_pool_aux, pw_grid=super_ref_pw_grid)
124 END IF
125 NULLIFY (screen_function)
126 ALLOCATE (screen_function)
127 CALL pw_pool%create_pw(screen_function)
128 CALL pw_zero(screen_function)
129 SELECT CASE (method)
130 CASE (mt0d)
131 NULLIFY (vloc, vlocg)
132 ALLOCATE (vloc, vlocg)
133 IF (ASSOCIATED(pw_pool_aux)) THEN
134 CALL pw_pool_aux%create_pw(vloc)
135 CALL pw_pool_aux%create_pw(vlocg)
136 ELSE
137 CALL pw_pool%create_pw(vloc)
138 CALL pw_pool%create_pw(vlocg)
139 END IF
140 CALL mt0din(vloc, alpha)
141 CALL pw_transfer(vloc, vlocg)
142 CALL pw_axpy(vlocg, screen_function)
143 IF (ASSOCIATED(pw_pool_aux)) THEN
144 CALL pw_pool_aux%give_back_pw(vloc)
145 CALL pw_pool_aux%give_back_pw(vlocg)
146 ELSE
147 CALL pw_pool%give_back_pw(vloc)
148 CALL pw_pool%give_back_pw(vlocg)
149 END IF
150 DEALLOCATE (vloc, vlocg)
151 !
152 ! Get rid of the analytical FT of the erf(a*r)/r
153 !
154 alpha2 = alpha*alpha
155 DO ig = screen_function%pw_grid%first_gne0, screen_function%pw_grid%ngpts_cut_local
156 g2 = screen_function%pw_grid%gsq(ig)
157 g3d = fourpi/g2
158 screen_function%array(ig) = screen_function%array(ig) - g3d*exp(-g2/(4.0e0_dp*alpha2))
159 END DO
160 IF (screen_function%pw_grid%have_g0) THEN
161 screen_function%array(1) = screen_function%array(1) + fourpi/(4.0e0_dp*alpha2)
162 END IF
163 CASE (mt2d)
164 iz = special_dimension ! iz is the direction with NO PBC
165 zlength = slab_size ! zlength is the thickness of the cell
166 DO ig = screen_function%pw_grid%first_gne0, screen_function%pw_grid%ngpts_cut_local
167 gz = screen_function%pw_grid%g(iz, ig)
168 g2 = screen_function%pw_grid%gsq(ig)
169 gxy = sqrt(abs(g2 - gz*gz))
170 g3d = fourpi/g2
171 screen_function%array(ig) = -g3d*cos(gz*zlength/2.0_dp)*exp(-gxy*zlength/2.0_dp)
172 END DO
173 IF (screen_function%pw_grid%have_g0) screen_function%array(1) = pi*zlength*zlength/2.0_dp
174 CASE (mt1d)
175 iz = special_dimension ! iz is the direction with PBC
176 CALL mt1din(screen_function)
177 cpabort("MT1D unimplemented")
178 END SELECT
179 CALL pw_pool_release(pw_pool_aux)
180 CALL timestop(handle)
181 END SUBROUTINE mtin_create_screen_fn
182
183! **************************************************************************************************
184!> \brief Calculates the Tuckerman Green's function in reciprocal space
185!> according the scheme published on:
186!> Martyna and Tuckerman, J. Chem. Phys. Vol. 110, No. 6, 2810-2821
187!> \param Vloc ...
188!> \param alpha ...
189!> \author Teodoro Laino (09.03.2005)
190! **************************************************************************************************
191 SUBROUTINE mt0din(Vloc, alpha)
192 TYPE(pw_r3d_rs_type), POINTER :: vloc
193 REAL(kind=dp), INTENT(in) :: alpha
194
195 CHARACTER(len=*), PARAMETER :: routinen = 'mt0din'
196
197 INTEGER :: handle, i, ii, j, jj, k, kk
198 INTEGER, DIMENSION(:), POINTER :: glb
199 INTEGER, DIMENSION(:, :), POINTER :: bo
200 REAL(kind=dp) :: dx, dy, dz, fact, omega, r, r2, x, y, &
201 y2, z, z2
202 REAL(kind=dp), DIMENSION(3) :: box, box2
203 TYPE(pw_grid_type), POINTER :: grid
204
205 CALL timeset(routinen, handle)
206
207 grid => vloc%pw_grid
208 bo => grid%bounds_local
209 glb => grid%bounds(1, :)
210 vloc%array = 0.0_dp
211 box = real(grid%npts, kind=dp)*grid%dr
212 box2 = box/2.0_dp
213 omega = product(box)
214 fact = omega
215 dx = grid%dr(1)
216 dy = grid%dr(2)
217 dz = grid%dr(3)
218 kk = bo(1, 3)
219 DO k = bo(1, 3), bo(2, 3)
220 z = real(k - glb(3), dp)*dz; IF (z > box2(3)) z = box(3) - z
221 z2 = z*z
222 jj = bo(1, 2)
223 DO j = bo(1, 2), bo(2, 2)
224 y = real(j - glb(2), dp)*dy; IF (y > box2(2)) y = box(2) - y
225 y2 = y*y
226 ii = bo(1, 1)
227 DO i = bo(1, 1), bo(2, 1)
228 x = real(i - glb(1), dp)*dx; IF (x > box2(1)) x = box(1) - x
229 r2 = x*x + y2 + z2
230 r = sqrt(r2)
231 IF (r > 1.0e-10_dp) THEN
232 vloc%array(ii, jj, kk) = erf(alpha*r)/r*fact
233 ELSE
234 vloc%array(ii, jj, kk) = 2.0_dp*alpha*oorootpi*fact
235 END IF
236 ii = ii + 1
237 END DO
238 jj = jj + 1
239 END DO
240 kk = kk + 1
241 END DO
242 CALL timestop(handle)
243 END SUBROUTINE mt0din
244
245! **************************************************************************************************
246!> \brief Calculates the Tuckerman Green's function in reciprocal space
247!> according the scheme published on:
248!> Martyna and Tuckerman, J. Chem. Phys. Vol. 121, No. 23, 11949
249!> \param screen_function ...
250!> \author Teodoro Laino (11.2005)
251! **************************************************************************************************
252 SUBROUTINE mt1din(screen_function)
253 TYPE(pw_c1d_gs_type), POINTER :: screen_function
254
255 CHARACTER(len=*), PARAMETER :: routinen = 'mt1din'
256
257 INTEGER :: handle
258 REAL(kind=dp) :: dx, dy, dz, omega
259 REAL(kind=dp), DIMENSION(3) :: box, box2
260 TYPE(pw_grid_type), POINTER :: grid
261
262 CALL timeset(routinen, handle)
263 grid => screen_function%pw_grid
264 box = real(grid%npts, kind=dp)*grid%dr
265 box2 = box/2.0_dp
266 omega = product(box)
267 dx = grid%dr(1)
268 dy = grid%dr(2)
269 dz = grid%dr(3)
270
271 CALL timestop(handle)
272 END SUBROUTINE mt1din
273
274END MODULE mt_util
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public martyna1999
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
real(kind=dp), parameter, public oorootpi
real(kind=dp), parameter, public pi
real(kind=dp), parameter, public fourpi
subroutine, public mt2d_kernel_strain(g, special_dimension, slab_size, kernel, strain)
MT2D Coulomb kernel and its affine strain derivative in the periodic plane.
Definition mt_util.F:49
integer, parameter, public mt0d
Definition mt_util.F:33
integer, parameter, public mt2d
Definition mt_util.F:33
subroutine, public mtin_create_screen_fn(screen_function, pw_pool, method, alpha, special_dimension, slab_size, super_ref_pw_grid)
Initialize the Martyna && Tuckerman Poisson Solver.
Definition mt_util.F:100
integer, parameter, public mt1d
Definition mt_util.F:33
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
subroutine, public pw_pool_release(pool)
releases the given pool (see cp2k/doc/ReferenceCounting.html)
subroutine, public pw_pool_create(pool, pw_grid, max_cache)
creates a pool for pw
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...