29 use,
intrinsic :: iso_fortran_env
59 integer,
public,
parameter :: &
60 POISSON_FFT_KERNEL_NONE = -1, &
70 type(fourier_space_op_t) :: coulb
72 real(real64) :: soft_coulb_param
75 real(real64),
parameter :: TOL_VANISHING_Q = 1e-6_real64
78 subroutine poisson_fft_init(this, namespace, space, cube, kernel, soft_coulb_param, fullcube)
79 type(poisson_fft_t),
intent(out) :: this
80 type(namespace_t),
intent(in) :: namespace
81 class(space_t),
intent(in) :: space
82 type(cube_t),
intent(inout) :: cube
83 integer,
intent(in) :: kernel
84 real(real64),
optional,
intent(in) :: soft_coulb_param
85 type(cube_t),
optional,
intent(in) :: fullcube
87 real(real64) :: qvector(1:space%dim)
94 call this%coulb%init(space, qvector,
cam_null)
102 type(namespace_t),
intent(in) :: namespace
103 class(space_t),
intent(in) :: space
104 type(cube_t),
intent(in) :: cube
105 type(fourier_space_op_t),
intent(inout) :: coulb
106 integer,
intent(in) :: kernel
107 real(real64),
optional,
intent(in) :: soft_coulb_param
108 type(cube_t),
optional,
intent(in) :: fullcube
114 message(1) =
"The screened Coulomb potential is only implemented in 3D for PoissonFFTKernel=fft_nocut."
121 if (.not.
present(fullcube))
then
122 message(1) =
"Hockney's FFT-kernel needs cube of full unit cell "
125 if (.not.
allocated(fullcube%fft))
then
126 message(1) =
"Hockney's FFT-kernel needs PoissonSolver=fft"
133 select case (space%dim)
135 assert(
present(soft_coulb_param))
142 message(1) =
"Invalid Poisson FFT kernel for 1D."
155 message(1) =
"Invalid Poisson FFT kernel for 2D."
177 message(1) =
"Invalid Poisson FFT kernel for 3D."
187 subroutine get_cutoff(namespace, default_r_c, r_c)
189 real(real64),
intent(in) :: default_r_c
190 real(real64),
intent(out) :: r_c
201 call messages_write(
'Poisson cutoff radius is larger than cell size.', new_line = .
true.)
202 call messages_write(
'You can see electrons in neighboring cell(s).')
214 real(real64) :: singularity_term
216 real(real64) :: inv_four_mu2
229 singularity_term =
m_four *
m_pi * inv_four_mu2 * coulb%beta
233 singularity_term = coulb%singularity*coulb%alpha +
m_four *
m_pi * inv_four_mu2 * coulb%beta
235 singularity_term = coulb%singularity
269 type(
cube_t),
intent(in) :: cube
272 integer :: n1, n2, n3, lx, ly, lz, i
273 real(real64) :: modg2, modgyz, beta, modg2_cutoff, inv_four_mu2, ecut
274 real(real64) :: temp(3), diag_temp(3, 3), metric(3, 3), a(3, 3)
275 real(real64) :: q1, q2, q3, ux, uy, uz, a11, two_a12, two_a13, a22, two_a23, a33, four_a11
276 real(real64) :: singularity_term
277 real(real64),
allocatable :: fft_coulb_fs(:,:,:)
287 n1 = max(1, cube%fs_n(1))
288 n2 = max(1, cube%fs_n(2))
289 n3 = max(1, cube%fs_n(3))
295 safe_allocate(fft_coulb_fs(1:n1, 1:n2, 1:n3))
302 metric = matmul(transpose(cube%latt%klattice_primitive), cube%latt%klattice_primitive)
307 diag_temp(i, i) = temp(i)
309 a = matmul(diag_temp, matmul(metric, diag_temp))
313 two_a12 =
m_two * a(1, 2)
314 two_a13 =
m_two * a(1, 3)
315 two_a23 =
m_two * a(2, 3)
322 modg2_cutoff =
m_two * ecut * 1.001_real64
326 uz = real(cube%fs_ifz(lz), real64) + q3
329 uy = real(cube%fs_ify(ly), real64) + q2
330 modgyz = a22*uy*uy + two_a23*uy*uz + a33*uz*uz
331 beta = two_a12*uy + two_a13*uz
332 if (modgyz - beta * beta / four_a11 > modg2_cutoff)
then
333 fft_coulb_fs(1:n1, ly, lz) =
m_zero
338 ux = real(cube%fs_ifx(lx), real64) + q1
340 modg2 = (a11*ux + beta)*ux + modgyz
342 if (modg2 > modg2_cutoff)
then
343 fft_coulb_fs(lx, ly, lz) =
m_zero
344 else if (modg2 > tol_vanishing_q)
then
348 fft_coulb_fs(lx, ly, lz) =
m_four *
m_pi / modg2 * (coulb%alpha + coulb%beta *
exp(-modg2*inv_four_mu2))
350 fft_coulb_fs(lx, ly, lz) =
m_four *
m_pi / modg2 * coulb%beta * (-
expm1(-modg2 * inv_four_mu2))
354 fft_coulb_fs(lx, ly, lz) =
m_four *
m_pi / modg2 * coulb%alpha
356 fft_coulb_fs(lx, ly, lz) =
m_four *
m_pi / modg2
360 fft_coulb_fs(lx, ly, lz) = singularity_term
367 call coulb%dset_op(cube, op_move = fft_coulb_fs)
369 safe_deallocate_a(fft_coulb_fs)
381 type(
cube_t),
intent(in) :: cube
383 type(
cube_t),
intent(in) :: fullcube
385 integer :: ix, iy, iz, ixx(3), db(3), nfs(3), nrs(3), nfs_s(3), nrs_s(3), dnrs(3)
386 real(real64) :: temp(3), modg2, weight
387 real(real64) :: gg(3)
388 real(real64),
allocatable :: fft_Coulb_small_RS(:,:,:,:)
389 real(real64),
allocatable :: fft_Coulb_RS(:,:,:,:)
390 complex(real64),
allocatable :: fft_Coulb_small_FS(:,:,:,:)
391 complex(real64),
allocatable :: fft_Coulb_FS(:,:,:,:)
392 integer,
parameter :: howmany = 1
397 assert(cube%batch_capacity == 1)
398 assert(fullcube%batch_capacity == 1)
401 nfs(1:3) = fullcube%fs_n_global(1:3)
402 nrs(1:3) = fullcube%rs_n_global(1:3)
404 safe_allocate(fft_coulb_fs(1:nfs(1),1:nfs(2),1:nfs(3), 1:howmany))
405 safe_allocate(fft_coulb_rs(1:nrs(1),1:nrs(2),1:nrs(3), 1:howmany))
408 nfs_s(1:3) = cube%fs_n_global(1:3)
409 nrs_s(1:3) = cube%rs_n_global(1:3)
411 safe_allocate(fft_coulb_small_fs(1:nfs_s(1),1:nfs_s(2),1:nfs_s(3), 1:howmany))
412 safe_allocate(fft_coulb_small_rs(1:nrs_s(1),1:nrs_s(2),1:nrs_s(3), 1:howmany))
417 db(1:3) = fullcube%rs_n_global(1:3)
418 temp(1:3) =
m_two*
m_pi/(db(1:3)*cube%spacing(1:3))
429 if (abs(modg2) > tol_vanishing_q)
then
430 fft_coulb_fs(ix, iy, iz, 1) =
m_one/modg2
432 fft_coulb_fs(ix, iy, iz, 1) =
m_zero
440 if(coulb%alpha >
m_epsilon) weight = weight * coulb%alpha
445 fft_coulb_fs(ix, iy, iz, 1) = weight*fft_coulb_fs(ix, iy, iz, 1)
460 if (iz > nrs_s(3)/2+1) ixx(3) = ixx(3) + dnrs(3)
463 if (iy > nrs_s(2)/2+1) ixx(2) = ixx(2) + dnrs(2)
466 if (ix > nrs_s(1)/2+1) ixx(1) = ixx(1) + dnrs(1)
467 fft_coulb_small_rs(ix, iy, iz, 1) = fft_coulb_rs(ixx(1),ixx(2),ixx(3), 1)
472 call dfft_forward(cube%fft, fft_coulb_small_rs, fft_coulb_small_fs)
474 fft_coulb_small_rs(1:nfs_s(1),1:nfs_s(2),1:nfs_s(3),1:howmany) = &
475 real( fft_Coulb_small_FS(1:nfs_s(1),1:nfs_s(2),1:nfs_s(3),1:howmany), real64)
480 call coulb%dset_op(cube, &
481 fft_coulb_small_rs(cube%fs_istart(1):cube%fs_istart(1)+cube%fs_n(1), &
482 cube%fs_istart(2):cube%fs_istart(2)+cube%fs_n(2), &
483 cube%fs_istart(3):cube%fs_istart(3)+cube%fs_n(3), 1))
485 safe_deallocate_a(fft_coulb_fs)
486 safe_deallocate_a(fft_coulb_rs)
487 safe_deallocate_a(fft_coulb_small_fs)
488 safe_deallocate_a(fft_coulb_small_rs)
498 type(
cube_t),
intent(in) :: cube
501 integer :: ix, iy, iz, ixx(3), db(3)
502 integer :: lx, ly, lz, n1, n2, n3
503 real(real64) :: temp(3), modg2, ecut, weight
504 real(real64) :: gpar, gz, r_c, gg(3), default_r_c
505 real(real64),
allocatable :: fft_coulb_FS(:,:,:)
509 db(1:3) = cube%rs_n_global(1:3)
514 if(coulb%alpha >
m_epsilon) weight = weight * coulb%alpha
528 default_r_c = db(3)*cube%spacing(3)/
m_two
531 n1 = max(1, cube%fs_n(1))
532 n2 = max(1, cube%fs_n(2))
533 n3 = max(1, cube%fs_n(3))
535 safe_allocate(fft_coulb_fs(1:n1, 1:n2, 1:n3))
538 temp(1:3) =
m_two*
m_pi/(db(1:3)*cube%spacing(1:3))
543 iz = cube%fs_istart(3) + lz - 1
546 iy = cube%fs_istart(2) + ly - 1
549 ix = cube%fs_istart(1) + lx - 1
554 if(sum(gg(1:2)**2) >
m_two*ecut*1.001_real64) cycle
556 if (abs(modg2) > tol_vanishing_q)
then
558 gpar =
hypot(gg(1), gg(2))
562 fft_coulb_fs(lx, ly, lz) = -
m_half*r_c**2
564 fft_coulb_fs(lx, ly, lz) = weight*fft_coulb_fs(lx, ly, lz)
570 call coulb%dset_op(cube, op_move = fft_coulb_fs)
572 safe_deallocate_a(fft_coulb_fs)
582 class(
space_t),
intent(in) :: space
583 type(
cube_t),
intent(in) :: cube
587 real(real64),
allocatable :: x(:), y(:)
588 integer :: ix, iy, iz, ixx(3), db(3), k, ngp
589 integer :: lx, ly, lz, n1, n2, n3, lxx(3)
590 real(real64) :: temp(3), modg2, xmax, weight
591 real(real64) :: gperp, gx, gy, gz, r_c, gg(3), default_r_c
592 real(real64),
allocatable :: fft_coulb_FS(:,:,:)
599 if(coulb%alpha >
m_epsilon) weight = weight * coulb%alpha
602 db(1:3) = cube%rs_n_global(1:3)
604 default_r_c = maxval(db(2:3)*cube%spacing(2:3)/
m_two)
607 n1 = max(1, cube%fs_n(1))
608 n2 = max(1, cube%fs_n(2))
609 n3 = max(1, cube%fs_n(3))
611 safe_allocate(fft_coulb_fs(1:n1, 1:n2, 1:n3))
614 temp(1:3) =
m_two*
m_pi/(db(1:3)*cube%spacing(1:3))
616 if (.not. space%is_periodic())
then
618 safe_allocate(x(1:ngp))
619 safe_allocate(y(1:ngp))
625 ix = cube%fs_istart(1) + lx - 1
627 lxx(1) = ixx(1) - cube%fs_istart(1) + 1
630 if (.not. space%is_periodic())
then
632 xmax = norm2(temp(2:3)*db(2:3))/2
634 x(k) = (k-1)*(xmax/(ngp-1))
636 maxval(norm2(cube%latt%rlattice_primitive(:, 2:3), dim=1)))
642 iy = cube%fs_istart(2) + ly - 1
644 lxx(2) = ixx(2) - cube%fs_istart(2) + 1
646 iz = cube%fs_istart(3) + lz - 1
648 lxx(3) = ixx(3) - cube%fs_istart(3) + 1
652 if (abs(modg2) > tol_vanishing_q)
then
653 gperp =
hypot(gg(2), gg(3))
654 if (space%periodic_dim == 1)
then
655 if (gperp > r_c)
then
656 fft_coulb_fs(lx, ly, lz) =
m_zero
660 else if (.not. space%is_periodic())
then
664 fft_coulb_fs(lx, ly, lz) =
spline_eval(cylinder_cutoff_f, gperp)
667 fft_coulb_fs(lx, ly, lz) = fft_coulb_fs(lx, -lxx(2) + 1, lz)
670 fft_coulb_fs(lx, ly, lz) = fft_coulb_fs(lx, ly, -lxx(3) + 1)
673 fft_coulb_fs(lx, ly, lz) = fft_coulb_fs(lx, -lxx(2) + 1, -lxx(3) + 1)
678 if (space%periodic_dim == 1)
then
680 else if (.not. space%is_periodic())
then
682 norm2(cube%latt%rlattice_primitive(:, 1)), maxval(norm2(cube%latt%rlattice_primitive(:, 2:3), dim=1)))
686 fft_coulb_fs(lx, ly, lz) = weight*fft_coulb_fs(lx, ly, lz)
690 if (.not. space%is_periodic())
then
695 call coulb%dset_op(cube, op_move = fft_coulb_fs)
697 safe_deallocate_a(fft_coulb_fs)
709 type(
cube_t),
intent(in) :: cube
710 integer,
intent(in) :: kernel
712 logical,
intent(in) :: is_periodic
714 integer :: ix, iy, iz, ixx(3), db(3), lx, ly, lz, n1, n2, n3
715 real(real64) :: temp(3), modg2, ecut, weight
716 real(real64) :: r_c, gg(3), default_r_c
717 real(real64),
allocatable :: fft_coulb_FS(:,:,:)
718 real(real64) :: axis(3,3)
725 if(coulb%alpha >
m_epsilon) weight = weight * coulb%alpha
728 db(1:3) = cube%rs_n_global(1:3)
734 axis(:,ix) = cube%latt%rlattice_primitive(:, ix) * cube%spacing(ix) * db(ix) /
m_two
743 if (.not. cube%latt%nonorthogonal)
then
744 temp(1:3) = axis(:, ix)
745 default_r_c = min(default_r_c, norm2(temp(1:3)))
754 temp = temp / norm2(temp)
755 default_r_c = min(default_r_c, dot_product(temp, axis(:, ix)-axis(:, iy)))
761 n1 = max(1, cube%fs_n(1))
762 n2 = max(1, cube%fs_n(2))
763 n3 = max(1, cube%fs_n(3))
767 safe_allocate(fft_coulb_fs(1:n1,1:n2,1:n3))
770 temp(1:3) =
m_two*
m_pi/(db(1:3)*cube%spacing(1:3))
775 iz = cube%fs_istart(3) + lz - 1
778 iy = cube%fs_istart(2) + ly - 1
781 ix = cube%fs_istart(1) + lx - 1
787 if(modg2 >
m_two*ecut*1.001_real64 .and. is_periodic) cycle
789 if (abs(modg2) > tol_vanishing_q)
then
794 fft_coulb_fs(lx, ly, lz) = weight/modg2
799 fft_coulb_fs(lx, ly, lz) = weight*r_c**2/
m_two
801 fft_coulb_fs(lx, ly, lz) =
m_zero
810 safe_deallocate_a(fft_coulb_fs)
820 type(
cube_t),
intent(in) :: cube
824 integer :: i, ix, iy, ixx(2), db(2), npoints
825 real(real64) :: temp(2), vec, r_c, maxf, dk, default_r_c, weight
826 real(real64),
allocatable :: x(:), y(:)
827 real(real64),
allocatable :: fft_coulb_FS(:,:,:)
834 if(coulb%alpha >
m_epsilon) weight = weight * coulb%alpha
836 db(1:2) = cube%rs_n_global(1:2)
838 default_r_c = maxval(db(1:2)*cube%spacing(1:2)/
m_two)
844 safe_allocate(fft_coulb_fs(1:cube%fs_n_global(1), 1:cube%fs_n_global(2), 1:cube%fs_n_global(3)))
846 temp(1:2) =
m_two*
m_pi/(db(1:2)*cube%spacing(1:2))
848 maxf = r_c * norm2(temp(1:2)*db(1:2))/2
850 npoints = nint(maxf/dk)
851 safe_allocate(x(1:npoints))
852 safe_allocate(y(1:npoints))
856 x(i) = (i-1) * maxf / (npoints-1)
861 do iy = 1, cube%fs_n_global(2)
863 do ix = 1, cube%fs_n_global(1)
865 vec = norm2(temp(1:2)*ixx(1:2))
867 if (vec*r_c >= x(npoints))
then
868 fft_coulb_fs(ix, iy, 1) = weight * y(npoints)
869 else if (vec >
m_zero)
then
872 fft_coulb_fs(ix, iy, 1) = weight *
m_two *
m_pi * r_c
877 call coulb%dset_op(cube, op_move = fft_coulb_fs)
879 safe_deallocate_a(fft_coulb_fs)
892 type(
cube_t),
intent(in) :: cube
895 integer :: ix, iy, ixx(2), db(2)
896 real(real64) :: temp(2), r_c, gx, gy, default_r_c, weight
897 real(real64),
allocatable :: fft_coulb_FS(:,:,:)
904 if(coulb%alpha >
m_epsilon) weight = weight * coulb%alpha
907 db(1:2) = cube%rs_n_global(1:2)
909 default_r_c = db(2)*cube%spacing(2)/
m_two
913 safe_allocate(fft_coulb_fs(1:cube%fs_n_global(1), 1:cube%fs_n_global(2), 1:cube%fs_n_global(3)))
915 temp(1:2) =
m_two*
m_pi/(db(1:2)*cube%spacing(1:2))
919 do iy = 2, cube%fs_n_global(2)
925 do ix = 2, cube%fs_n_global(1)
928 do iy = 1, cube%fs_n_global(2)
935 call coulb%dset_op(cube, op_move = fft_coulb_fs)
937 safe_deallocate_a(fft_coulb_fs)
947 type(
cube_t),
intent(in) :: cube
950 integer :: ix, iy, ixx(2), db(2)
951 real(real64) :: temp(2), vec, weight
952 real(real64),
allocatable :: fft_coulb_FS(:,:,:)
959 if(coulb%alpha >
m_epsilon) weight = weight * coulb%alpha
961 db(1:2) = cube%rs_n_global(1:2)
964 safe_allocate(fft_coulb_fs(1:cube%fs_n_global(1), 1:cube%fs_n_global(2), 1:cube%fs_n_global(3)))
966 temp(1:2) =
m_two*
m_pi/(db(1:2)*cube%spacing(1:2))
968 do iy = 1, cube%fs_n_global(2)
970 do ix = 1, cube%fs_n_global(1)
972 vec =
sqrt((temp(1) * ixx(1))**2 + (temp(2) * ixx(2))**2)
973 if (vec >
m_zero) fft_coulb_fs(ix, iy, 1) =
m_two *
m_pi / vec * weight
977 call coulb%dset_op(cube, op_move = fft_coulb_fs)
979 safe_deallocate_a(fft_coulb_fs)
987 type(
cube_t),
intent(in) :: cube
989 real(real64),
intent(in) :: poisson_soft_coulomb_param
992 real(real64) :: g, weight
993 real(real64),
allocatable :: fft_coulb_fs(:, :, :)
1000 if(coulb%alpha >
m_epsilon) weight = weight * coulb%alpha
1002 safe_allocate(fft_coulb_fs(1:cube%fs_n_global(1), 1:cube%fs_n_global(2), 1:cube%fs_n_global(3)))
1006 do ix = 1, cube%fs_n_global(1)
1008 g = (ixx + coulb%qq(1))*
m_two*
m_pi/abs(cube%latt%rlattice(1,1))
1009 if (abs(g) > tol_vanishing_q)
then
1010 fft_coulb_fs(ix, 1, 1) =
m_two *
loct_bessel_k0(poisson_soft_coulomb_param*abs(g)) * weight
1012 fft_coulb_fs(ix, 1, 1) = coulb%singularity *
m_two * weight
1016 call coulb%dset_op(cube, op_move = fft_coulb_fs)
1017 safe_deallocate_a(fft_coulb_fs)
1027 type(
cube_t),
intent(in) :: cube
1029 real(real64),
intent(in) :: poisson_soft_coulomb_param
1031 integer :: box(1), ixx(1), ix
1032 real(real64) :: temp(1), g, r_c, default_r_c, weight
1033 real(real64),
allocatable :: fft_coulb_fs(:, :, :)
1040 if(coulb%alpha >
m_epsilon) weight = weight * coulb%alpha
1042 box(1:1) = cube%rs_n_global(1:1)
1044 default_r_c = box(1)*cube%spacing(1)/
m_two
1047 safe_allocate(fft_coulb_fs(1:cube%fs_n_global(1), 1:cube%fs_n_global(2), 1:cube%fs_n_global(3)))
1049 temp(1:1) =
m_two*
m_pi/(box(1:1)*cube%spacing(1:1))
1052 do ix = 1, cube%fs_n_global(1)
1058 call coulb%dset_op(cube, op_move = fft_coulb_fs)
1059 safe_deallocate_a(fft_coulb_fs)
1072 call this%coulb%end()
1079#include "poisson_fft_inc.F90"
1081#include "complex.F90"
1082#include "poisson_fft_inc.F90"
Some operations may be done for one spline-function, or for an array of them.
double hypot(double __x, double __y) __attribute__((__nothrow__
double log(double __x) __attribute__((__nothrow__
double exp(double __x) __attribute__((__nothrow__
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
real(real64) function, public fft_get_ecut_from_box(box_dim, fs_istart, latt, gspacing, periodic_dim, qq)
Given an fft box (fixed by the real-space grid), it returns the cutoff energy of the sphere that fits...
pure integer function, public pad_feq(ii, nn, mode)
convert between array index and G-vector
pure subroutine, public fft_gg_transform(gg_in, temp, periodic_dim, latt, qq, gg, modg2)
Convert FFT grid index into the Cartesian reciprocal-space vector .
real(real64), parameter, public m_two
real(real64), parameter, public m_huge
real(real64), parameter, public m_zero
real(real64), parameter, public m_four
real(real64), parameter, public m_pi
some mathematical constants
real(real64), parameter, public m_fourth
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_half
real(real64), parameter, public m_one
This module is intended to contain "only mathematical" functions and procedures.
pure real(real64) function, dimension(1:3), public dcross_product(a, b)
This module defines the meshes, which are used in Octopus.
subroutine, public messages_warning(no_lines, all_nodes, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
real(real64) function, public poisson_cutoff_3d_2d(p, z, r)
real(real64) function, public poisson_cutoff_3d_1d(x, p, rmax)
real(real64) function, public poisson_cutoff_3d_0d(x, r)
integer, parameter, public poisson_fft_kernel_hockney
subroutine poisson_fft_build_2d_0d(namespace, cube, coulb)
A. Castro et al., Phys. Rev. B 80, 033102 (2009)
subroutine poisson_fft_build_3d_1d(namespace, space, cube, coulb)
C. A. Rozzi et al., Phys. Rev. B 73, 205119 (2006), Table I.
subroutine, public dpoisson_fft_solve_batch(this, mesh, cube, pot, rho, mesh_cube_map, average_to_zero, kernel, sm, pot_buffer, rho_buffer, count)
subroutine poisson_fft_build_3d_2d(namespace, cube, coulb)
C. A. Rozzi et al., Phys. Rev. B 73, 205119 (2006), Table I.
real(real64) function poisson_fft_singularity_3d(coulb)
Define the singularity correction for |q+G| = 0, for the 3D Coulomb kernel.
integer, parameter, public poisson_fft_kernel_nocut
integer, parameter, public poisson_fft_kernel_cyl
subroutine poisson_fft_build_2d_1d(namespace, cube, coulb)
A. Castro et al., Phys. Rev. B 80, 033102 (2009)
subroutine poisson_fft_build_1d_0d(namespace, cube, coulb, poisson_soft_coulomb_param)
subroutine, public zpoisson_fft_solve(this, mesh, cube, pot, rho, mesh_cube_map, average_to_zero, kernel, sm)
subroutine poisson_fft_build_3d_0d(namespace, cube, kernel, coulb, is_periodic)
C. A. Rozzi et al., Phys. Rev. B 73, 205119 (2006), Table I.
subroutine get_cutoff(namespace, default_r_c, r_c)
subroutine poisson_fft_build_3d_3d(cube, coulb)
Compute the Coulomb kernel in reciprocal space, for a 3D FFT grid.
subroutine poisson_fft_build_1d_1d(cube, coulb, poisson_soft_coulomb_param)
subroutine, public poisson_fft_get_kernel(namespace, space, cube, coulb, kernel, soft_coulb_param, fullcube)
subroutine, public poisson_fft_end(this)
subroutine poisson_fft_build_2d_2d(cube, coulb)
A. Castro et al., Phys. Rev. B 80, 033102 (2009)
subroutine, public poisson_fft_init(this, namespace, space, cube, kernel, soft_coulb_param, fullcube)
integer, parameter, public poisson_fft_kernel_pla
subroutine, public zpoisson_fft_solve_batch(this, mesh, cube, pot, rho, mesh_cube_map, average_to_zero, kernel, sm, pot_buffer, rho_buffer, count)
integer, parameter, public poisson_fft_kernel_corrected
integer, parameter, public poisson_fft_kernel_sph
subroutine, public dpoisson_fft_solve(this, mesh, cube, pot, rho, mesh_cube_map, average_to_zero, kernel, sm)
subroutine poisson_fft_build_3d_3d_hockney(cube, coulb, fullcube)
Kernel for Hockneys algorithm that solves the poisson equation in a small box while respecting the pe...
subroutine, public spline_fit(nrc, rofi, ffit, spl, threshold)
real(real64) function, public spline_eval(spl, x)
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
type(unit_system_t), public units_inp
the units systems for reading and writing
type(xc_cam_t), parameter, public cam_null
All CAM parameters set to zero.
Definition of a Fourier Space Coulomb Kernel.
the basic spline datatype