26 use,
intrinsic :: iso_fortran_env
46 real(real64) :: ekin_cutoff
47 integer,
allocatable :: coords(:, :)
48 integer,
allocatable :: red_gvec(:, :)
53 real(real64) function fourier_shell_cutoff(space, cube, mesh, is_wfn, dg)
54 class(space_t),
intent(in) :: space
55 type(cube_t),
intent(in) :: cube
56 class(mesh_t),
intent(in) :: mesh
57 logical,
intent(in) :: is_wfn
58 real(real64),
optional,
intent(out) :: dg(:)
60 real(real64) :: dg_(3)
62 push_sub(fourier_shell_cutoff)
65 dg_(1:3) =
m_pi/(cube%rs_n_global(1:3)/2*mesh%spacing(1:3))
66 if (
present(dg)) dg(1:3) = dg_(1:3)
67 if (is_wfn .and. space%is_periodic())
then
68 fourier_shell_cutoff = (dg_(1)*(cube%rs_n_global(1)/2-2))**2/
m_two
70 fourier_shell_cutoff = (dg_(1)*(cube%rs_n_global(1)/2))**2/
m_two
73 pop_sub(fourier_shell_cutoff)
77 type(fourier_shell_t),
intent(inout) :: this
78 type(namespace_t),
intent(in) :: namespace
79 class(space_t),
intent(in) :: space
80 type(cube_t),
intent(in) :: cube
81 class(mesh_t),
intent(in) :: mesh
82 real(real64),
optional,
intent(in) :: kk(:)
84 integer :: ig, ix, iy, iz, ixx(1:3), imap
85 real(real64) :: dg(1:3), gvec(1:3)
86 real(real64),
allocatable :: modg2(:)
87 integer,
allocatable :: map(:), ucoords(:, :), ured_gvec(:, :)
88 integer(int64) :: number_points
95 number_points = cube%rs_n_global(1) * cube%rs_n_global(2)
96 number_points = number_points * cube%rs_n_global(3)
97 if (number_points >= huge(0))
then
98 message(1) =
"Error: too many points for the normal cube. Please try to use a distributed FFT."
99 call messages_fatal(1, namespace=namespace)
101 safe_allocate(modg2(1:product(cube%rs_n_global(1:3))))
102 safe_allocate(ucoords(1:3, 1:product(cube%rs_n_global(1:3))))
103 safe_allocate(ured_gvec(1:3, 1:product(cube%rs_n_global(1:3))))
109 do ix = 1, cube%rs_n_global(1)
110 ixx(1) = pad_feq(ix, cube%rs_n_global(1), .
true.)
111 if (2 * ixx(1) == cube%rs_n_global(1)) cycle
112 do iy = 1, cube%rs_n_global(2)
113 ixx(2) = pad_feq(iy, cube%rs_n_global(2), .
true.)
114 if (2 * ixx(2) == cube%rs_n_global(2)) cycle
115 do iz = 1, cube%rs_n_global(3)
116 ixx(3) = pad_feq(iz, cube%rs_n_global(3), .
true.)
117 if (2 * ixx(3) == cube%rs_n_global(3)) cycle
119 if (
present(kk))
then
120 gvec(1:3) = dg(1:3)*(ixx(1:3) + kk(1:3))
122 gvec(1:3) = dg(1:3)*ixx(1:3)
125 if (sum(gvec(1:3)**2)/m_two <= this%ekin_cutoff + 1e-10_real64)
then
127 ucoords(1:3, ig) = (/ ix, iy, iz /)
128 ured_gvec(1:3, ig) = ixx(1:3)
129 modg2(ig) = sum(gvec(1:3)**2)
138 safe_allocate(this%coords(1:3, 1:this%ngvectors))
139 safe_allocate(this%red_gvec(1:3, 1:this%ngvectors))
140 safe_allocate(map(1:this%ngvectors))
142 do ig = 1, this%ngvectors
146 call sort(modg2(1:this%ngvectors), map)
148 do ig = 1, this%ngvectors
150 this%coords(1:3, ig) = ucoords(1:3, imap)
151 this%red_gvec(1:3, ig) = ured_gvec(1:3, imap)
154 safe_deallocate_a(ucoords)
155 safe_deallocate_a(ured_gvec)
156 safe_deallocate_a(modg2)
157 safe_deallocate_a(map)
169 safe_deallocate_a(this%coords)
170 safe_deallocate_a(this%red_gvec)
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
real(real64) function, public fourier_shell_cutoff(space, cube, mesh, is_wfn, dg)
subroutine, public fourier_shell_init(this, namespace, space, cube, mesh, kk)
subroutine, public fourier_shell_end(this)
real(real64), parameter, public m_two
real(real64), parameter, public m_pi
some mathematical constants
This module defines the meshes, which are used in Octopus.
This module is intended to contain "only mathematical" functions and procedures.