54#include "../base/base_uses.f90"
59 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
60 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'pw_poisson_types'
100 INTEGER,
DIMENSION(3) :: periodic = 0
102 INTEGER :: ewald_o_spline = 0
103 REAL(kind=
dp) :: ewald_alpha = 0.0_dp
105 REAL(kind=
dp) :: mt_rel_cutoff = 0.0_dp
106 REAL(kind=
dp) :: mt_alpha = 0.0_dp
108 INTEGER :: wavelet_scf_type = 0
110 INTEGER :: wavelet_special_dimension = 0
111 CHARACTER(LEN=1) :: wavelet_geocode =
"S"
113 LOGICAL :: has_dielectric = .false.
124 INTEGER :: pw_level = 0
126 INTEGER :: used_grid = 0
127 LOGICAL :: rebuild = .true.
131 REAL(kind=
dp),
DIMENSION(3, 3) :: cell_hmat = 0.0_dp
138 PROCEDURE,
PUBLIC, non_overridable :: create => pw_poisson_create
139 PROCEDURE,
PUBLIC, non_overridable :: release => pw_poisson_release
148 INTEGER :: special_dimension = 0
149 REAL(kind=
dp) :: radius = 0.0_dp
150 REAL(kind=
dp) :: mt_alpha = 1.0_dp
151 REAL(kind=
dp) :: mt_rel_cutoff = 1.0_dp
152 REAL(kind=
dp) :: slab_size = 0.0_dp
153 REAL(kind=
dp) :: alpha = 0.0_dp
154 LOGICAL :: p3m = .false.
155 INTEGER :: p3m_order = 0
156 REAL(kind=
dp) :: p3m_alpha = 0.0_dp
157 REAL(kind=
dp),
DIMENSION(:, :),
ALLOCATABLE :: p3m_coeff
158 REAL(kind=
dp),
DIMENSION(:, :),
ALLOCATABLE :: p3m_bm2
159 LOGICAL :: sr_screening = .false.
160 REAL(kind=
dp) :: sr_alpha = 1.0_dp
161 REAL(kind=
dp) :: sr_rc = 0.0_dp
182 mt_super_ref_pw_grid, dct_pw_grid)
185 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: cell_hmat
187 TYPE(
pw_grid_type),
POINTER :: mt_super_ref_pw_grid, dct_pw_grid
189 INTEGER :: dim, i, ig, iz, n, nz
190 REAL(kind=
dp) :: g2, g3d, gg, gxy, gz, j0g, j1g, k0g, &
191 k1g, rlength, zlength
192 REAL(kind=
dp),
DIMENSION(3) :: abc
199 abc(i) = cell_hmat(i, i)
201 dim = count(poisson_params%periodic == 1)
203 SELECT CASE (poisson_params%solver)
207 cpabort(
"Illegal combination of periodicity and Poisson solver periodic3d")
212 cpabort(
"Illegal combination of periodicity and Poisson solver mulipole0d")
218 green%radius = 0.5_dp*minval(abc)
221 green%special_dimension = maxloc(poisson_params%periodic(1:3), 1)
222 green%radius = maxval(abc(1:3))
224 IF (i == green%special_dimension) cycle
225 green%radius = min(green%radius, 0.5_dp*abc(i))
229 i = minloc(poisson_params%periodic, 1)
230 green%special_dimension = i
231 green%slab_size = abc(i)
238 green%MT_rel_cutoff = poisson_params%mt_rel_cutoff
239 green%MT_alpha = poisson_params%mt_alpha
240 green%MT_alpha = green%MT_alpha/minval(abc)
244 green%radius = 0.5_dp*minval(abc)
247 green%special_dimension = maxloc(poisson_params%periodic(1:3), 1)
248 green%radius = maxval(abc(1:3))
250 IF (i == green%special_dimension) cycle
251 green%radius = min(green%radius, 0.5_dp*abc(i))
255 i = minloc(poisson_params%periodic, 1)
256 green%special_dimension = i
257 green%slab_size = abc(i)
259 cpabort(
"Illegal combination of periodicity and Poisson solver (MT)")
266 cpabort(
"An unknown Poisson solver was specified")
270 SELECT CASE (green%method)
272 CALL pw_pool%create_pw(green%influence_fn)
276 green%p3m_order = poisson_params%ewald_o_spline
277 green%p3m_alpha = poisson_params%ewald_alpha
279 ALLOCATE (green%p3m_coeff(-(n - 1):n - 1, 0:n - 1))
280 CALL spme_coeff_calculate(n, green%p3m_coeff)
281 NULLIFY (green%p3m_charge)
282 ALLOCATE (green%p3m_charge)
283 CALL pw_pool%create_pw(green%p3m_charge)
284 CALL influence_factor(green)
285 CALL calc_p3m_charge(green)
290 SELECT CASE (green%method)
293 alpha=green%MT_alpha, &
294 special_dimension=green%special_dimension, slab_size=green%slab_size, &
295 super_ref_pw_grid=mt_super_ref_pw_grid)
297 IF ((poisson_params%ps_implicit_params%boundary_condition ==
mixed_bc) .OR. &
298 (poisson_params%ps_implicit_params%boundary_condition ==
neumann_bc))
THEN
300 NULLIFY (green%dct_influence_fn)
301 ALLOCATE (green%dct_influence_fn)
302 CALL pw_pool_xpndd%create_pw(green%dct_influence_fn)
312 associate(gf => green%influence_fn, grid => green%influence_fn%pw_grid)
313 SELECT CASE (green%method)
316 DO ig = grid%first_gne0, grid%ngpts_cut_local
320 IF (grid%have_g0) gf%array(1) = 0.0_dp
324 iz = green%special_dimension
325 zlength = green%slab_size
326 DO ig = grid%first_gne0, grid%ngpts_cut_local
327 nz = grid%g_hat(iz, ig)
330 gxy = max(0.0_dp, g2 - grid%g(iz, ig)*grid%g(iz, ig))
331 gg = 0.5_dp*sqrt(gxy)
332 gf%array(ig) = g3d*(1.0_dp - (-1.0_dp)**nz*exp(-gg*zlength))
334 IF (grid%have_g0) gf%array(1) = 0.0_dp
339 iz = green%special_dimension
341 rlength = green%radius
342 DO ig = grid%first_gne0, grid%ngpts_cut_local
345 gxy = sqrt(max(0.0_dp, g2 - grid%g(iz, ig)*grid%g(iz, ig)))
346 gz = abs(grid%g(iz, ig))
347 j0g = bessel_j0(rlength*gxy)
348 j1g = bessel_j1(rlength*gxy)
356 gf%array(ig) = g3d*(1.0_dp + rlength* &
357 (gxy*j1g*k0g - gz*j0g*k1g))
359 IF (grid%have_g0) gf%array(1) = 0.0_dp
363 rlength = green%radius
364 DO ig = grid%first_gne0, grid%ngpts_cut_local
368 gf%array(ig) = g3d*(1.0_dp - cos(rlength*gg))
371 gf%array(1) = 0.5_dp*
fourpi*rlength*rlength
375 DO ig = grid%first_gne0, grid%ngpts_cut_local
378 gf%array(ig) = g3d + green%screen_fn%array(ig)
381 gf%array(1) = green%screen_fn%array(1)
385 DO ig = grid%first_gne0, grid%ngpts_cut_local
389 IF (grid%have_g0) gf%array(1) = 0.0_dp
391 IF (
ASSOCIATED(green%dct_influence_fn))
THEN
392 dct_gf => green%dct_influence_fn
393 dct_grid => green%dct_influence_fn%pw_grid
395 DO ig = dct_grid%first_gne0, dct_grid%ngpts_cut_local
396 g2 = dct_grid%gsq(ig)
397 dct_gf%array(ig) =
fourpi/g2
399 IF (dct_grid%have_g0) dct_gf%array(1) = 0.0_dp
420 TYPE(pw_pool_type),
OPTIONAL,
POINTER :: pw_pool
422 LOGICAL :: can_give_back
424 can_give_back =
PRESENT(pw_pool)
425 IF (can_give_back) can_give_back =
ASSOCIATED(pw_pool)
426 IF (can_give_back)
THEN
427 CALL pw_pool%give_back_pw(gftype%influence_fn)
428 IF (
ASSOCIATED(gftype%dct_influence_fn))
THEN
429 CALL pw_pool%give_back_pw(gftype%dct_influence_fn)
430 DEALLOCATE (gftype%dct_influence_fn)
432 IF (
ASSOCIATED(gftype%screen_fn))
THEN
433 CALL pw_pool%give_back_pw(gftype%screen_fn)
434 DEALLOCATE (gftype%screen_fn)
436 IF (
ASSOCIATED(gftype%p3m_charge))
THEN
437 CALL pw_pool%give_back_pw(gftype%p3m_charge)
438 DEALLOCATE (gftype%p3m_charge)
441 CALL gftype%influence_fn%release()
442 IF (
ASSOCIATED(gftype%dct_influence_fn))
THEN
443 CALL gftype%dct_influence_fn%release()
444 DEALLOCATE (gftype%dct_influence_fn)
446 IF (
ASSOCIATED(gftype%screen_fn))
THEN
447 CALL gftype%screen_fn%release()
448 DEALLOCATE (gftype%screen_fn)
450 IF (
ASSOCIATED(gftype%p3m_charge))
THEN
451 CALL gftype%p3m_charge%release()
452 DEALLOCATE (gftype%p3m_charge)
455 IF (
ALLOCATED(gftype%p3m_bm2)) &
456 DEALLOCATE (gftype%p3m_bm2)
457 IF (
ALLOCATED(gftype%p3m_coeff)) &
458 DEALLOCATE (gftype%p3m_coeff)
469 SUBROUTINE influence_factor(gftype)
472 COMPLEX(KIND=dp) :: b_m, exp_m, sum_m
473 INTEGER :: dim, j, k, l, n, pt
474 INTEGER,
DIMENSION(3) :: npts
475 INTEGER,
DIMENSION(:),
POINTER :: lb, ub
476 REAL(kind=dp) :: l_arg, prod_arg, val
477 REAL(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: m_assign
483 lb => gftype%influence_fn%pw_grid%bounds(1, :)
484 ub => gftype%influence_fn%pw_grid%bounds(2, :)
485 IF (
ALLOCATED(gftype%p3m_bm2))
THEN
486 IF (lbound(gftype%p3m_bm2, 2) /= minval(lb(:)) .OR. &
487 ubound(gftype%p3m_bm2, 2) /= maxval(ub(:)))
THEN
488 DEALLOCATE (gftype%p3m_bm2)
491 IF (.NOT.
ALLOCATED(gftype%p3m_bm2))
THEN
492 ALLOCATE (gftype%p3m_bm2(3, minval(lb(:)):maxval(ub(:))))
495 ALLOCATE (m_assign(0:n - 2))
501 prod_arg = gftype%p3m_coeff(j, l)*l_arg
502 m_assign(k) = m_assign(k) + prod_arg
508 npts(:) = ub(:) - lb(:) + 1
510 DO pt = lb(dim), ub(dim)
511 val = twopi*(real(pt, kind=dp)/real(npts(dim), kind=dp))
512 exp_m = cmplx(cos(val), -sin(val), kind=dp)
515 sum_m = sum_m + m_assign(k)*exp_m**k
517 b_m = exp_m**(n - 1)/sum_m
518 gftype%p3m_bm2(dim, pt) = sqrt(real(b_m*conjg(b_m), kind=dp))
522 DEALLOCATE (m_assign)
523 END SUBROUTINE influence_factor
529 PURE SUBROUTINE calc_p3m_charge(gf)
533 INTEGER :: ig, l, m, n
534 REAL(kind=dp) :: arg, novol
538 associate(grid => gf%influence_fn%pw_grid, bm2 => gf%p3m_bm2)
539 arg = 1.0_dp/(8.0_dp*gf%p3m_alpha**2)
540 novol = real(grid%ngpts, kind=dp)/grid%vol
541 DO ig = 1, grid%ngpts_cut_local
542 l = grid%g_hat(1, ig)
543 m = grid%g_hat(2, ig)
544 n = grid%g_hat(3, ig)
545 gf%p3m_charge%array(ig) = novol*exp(-arg*grid%gsq(ig))* &
546 bm2(1, l)*bm2(2, m)*bm2(3, n)
550 END SUBROUTINE calc_p3m_charge
562 SUBROUTINE pw_poisson_create(poisson_env)
567 CALL poisson_env%release()
569 END SUBROUTINE pw_poisson_create
578 SUBROUTINE pw_poisson_release(poisson_env)
582 IF (
ASSOCIATED(poisson_env%pw_pools))
THEN
583 CALL pw_pools_dealloc(poisson_env%pw_pools)
586 IF (
ASSOCIATED(poisson_env%green_fft))
THEN
588 DEALLOCATE (poisson_env%green_fft)
590 CALL pw_grid_release(poisson_env%mt_super_ref_pw_grid)
591 CALL ps_wavelet_release(poisson_env%wavelet)
592 CALL ps_implicit_release(poisson_env%implicit_env, &
593 poisson_env%parameters%ps_implicit_params)
594 CALL pw_grid_release(poisson_env%dct_pw_grid)
595 IF (
ASSOCIATED(poisson_env%diel_rs_grid))
THEN
596 CALL rs_grid_release(poisson_env%diel_rs_grid)
597 DEALLOCATE (poisson_env%diel_rs_grid)
600 END SUBROUTINE pw_poisson_release
610 SUBROUTINE spme_coeff_calculate(n, coeff)
612 INTEGER,
INTENT(IN) :: n
613 REAL(kind=dp),
DIMENSION(-(n-1):n-1, 0:n-1), &
616 INTEGER :: i, j, l, m
618 REAL(kind=dp),
DIMENSION(n, -n:n, 0:n-1) :: a
627 b = (a(m, j - 1, l) + &
628 REAL((-1)**l, kind=dp)*a(m, j + 1, l))/ &
629 REAL((l + 1)*2**(l + 1), kind=dp)
630 a(i, j, 0) = a(i, j, 0) + b
633 a(i, j, l + 1) = (a(m, j + 1, l) - &
634 a(m, j - 1, l))/real(l + 1, kind=dp)
641 DO j = -(n - 1), n - 1, 2
642 coeff(j, i) = a(n, j, i)
646 END SUBROUTINE spme_coeff_calculate
Calculates Bessel functions.
elemental real(kind=dp) function, public bessk1(x)
...
elemental real(kind=dp) function, public bessk0(x)
...
dielectric constant data type
Dirichlet boundary condition data types.
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
real(kind=dp), parameter, public fourpi
real(kind=dp), parameter, public twopi
complex(kind=dp), parameter, public z_zero
integer, parameter, public mt0d
integer, parameter, public mt2d
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.
integer, parameter, public mt1d
Types containing essential information for running implicit (iterative) Poisson solver.
integer, parameter, public neumann_bc
subroutine, public ps_implicit_release(ps_implicit_env, ps_implicit_params, pw_pool)
Deallocates ps_implicit.
integer, parameter, public mixed_bc
Definition and initialisation of the ps_wavelet data type.
integer, parameter, public wavelet0d
subroutine, public ps_wavelet_release(wavelet)
...
This module defines the grid data type and some basic operations on it.
subroutine, public pw_grid_release(pw_grid)
releases the given pw grid
functions related to the poisson solver on regular grids
integer, parameter, public pw_poisson_wavelet
subroutine, public pw_green_create(green, poisson_params, cell_hmat, pw_pool, mt_super_ref_pw_grid, dct_pw_grid)
Allocates and sets up the green functions for the fft based poisson solvers.
integer, parameter, public pw_poisson_periodic
integer, parameter, public multipole1d
subroutine, public pw_green_release(gftype, pw_pool)
destroys the type (deallocates data)
integer, parameter, public pw_poisson_none
integer, parameter, public pw_poisson_mt
integer, parameter, public hockney0d
integer, parameter, public multipole2d
integer, parameter, public pw_poisson_hockney
integer, parameter, public hockney2d
integer, parameter, public do_ewald_pme
integer, parameter, public do_ewald_ewald
integer, parameter, public analytic2d
integer, parameter, public analytic1d
integer, parameter, public periodic3d
integer, parameter, public hockney1d
integer, parameter, public ps_implicit
integer, parameter, public analytic0d
integer, parameter, public multipole0d
integer, parameter, public pw_poisson_implicit
integer, parameter, public do_ewald_none
integer, parameter, public pw_poisson_analytic
integer, parameter, public do_ewald_spme
integer, parameter, public pw_poisson_multipole
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
subroutine, public pw_pools_dealloc(pools)
deallocates the given pools (releasing each of the underlying pools)
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
subroutine, public rs_grid_release(rs_grid)
releases the given rs grid (see doc/ReferenceCounting.html)
contains all the informations needed by the fft based poisson solvers
parameters for the poisson solver independet of input_section
environment for the poisson solver
to create arrays of pools
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...