pwdft  0.1
PW-DFT code for education
fftw_wrapper.F90
Go to the documentation of this file.
1 !
2 ! Copyright (c) 2018 Mitsuaki Kawamura
3 !
4 ! Permission is hereby granted, free of charge, to any person obtaining a
5 ! copy of this software and associated documentation files (the
6 ! "Software"), to deal in the Software without restriction, including
7 ! without limitation the rights to use, copy, modify, merge, publish,
8 ! distribute, sublicense, and/or sell copies of the Software, and to
9 ! permit persons to whom the Software is furnished to do so, subject to
10 ! the following conditions:
11 !
12 ! The above copyright notice and this permission notice shall be included
13 ! in all copies or substantial portions of the Software.
14 !
15 ! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 ! OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 ! MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 ! IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 ! CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 ! TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 ! SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 !
24  !
25  use, intrinsic :: iso_c_binding
26  !
27  implicit none
28  !
29  include 'fftw3.f03'
30  !
31  type(c_ptr),save :: &
32  & plan_g2r, & !< FFTW plan for F(G)e^{iGr} -> f(r) (backward)
33  & plan_r2g !< FFTW plan for f(r)e^{-iGr} -> F(G) (forward)
34  !
35  integer,allocatable,save :: &
36  & w2r(:) !< (g_wf%npw) g_wf%npw -> g_rh%nr
37  !
38  complex(c_double_complex),allocatable,save :: &
39  & fft_in(:), & !< (g_rh%nr) FFT buffer
40  & fft_out(:) !< (g_rh%nr) FFT buffer
41  !
42  private plan_g2r, plan_r2g, fft_in, fft_out
43  !
44 contains
45  !
46  subroutine init_fft()
47  !
48  use gvec, only : g_rh, g_wf
49  !
50  integer :: ipw, igv(3)
51  integer(c_int) :: fftwdim(3)
52  !
53  fftwdim(1:3) = (/g_rh%nft(3), g_rh%nft(2), g_rh%nft(1)/)
54  !
55  allocate(fft_in(g_rh%nr), fft_out(g_rh%nr))
56  !
57  plan_g2r = fftw_plan_dft(3, fftwdim, fft_in, fft_out, &
58  & fftw_backward, fftw_estimate)
59  !
60  plan_r2g = fftw_plan_dft(3, fftwdim, fft_in, fft_out, &
61  & fftw_forward, fftw_estimate)
62  !
63  allocate(w2r(g_wf%npw))
64  do ipw = 1, g_wf%npw
65  igv(1:3) = g_wf%mill(1:3, g_wf%map(ipw))
66  igv(1:3) = modulo(igv(1:3), g_rh%nft(1:3))
67  w2r(ipw) = 1 + igv(1) + g_rh%nft(1)*(igv(2) + g_rh%nft(2)*igv(3))
68  end do
69  !
70  end subroutine init_fft
74  subroutine fft_r2g(VlocR, VlocG)
75  !
76  use gvec, only : g_rh
77  !
78  real(8),intent(in) :: VlocR(g_rh%nr)
79  complex(8),intent(out) :: VlocG(g_rh%nr)
80  !
81  fft_in(1:g_rh%nr) = vlocr(1:g_rh%nr)
82  call fftw_execute_dft(plan_r2g, fft_in, fft_out)
83  vlocg(1:g_rh%nr) = fft_out(1:g_rh%nr) / dble(g_rh%nr)
84  !
85  end subroutine fft_r2g
89  subroutine fft_g2r(VlocG, VlocR)
90  !
91  use gvec, only : g_rh
92  !
93  complex(8),intent(in) :: VlocG(g_rh%nr)
94  real(8),intent(out) :: VlocR(g_rh%nr)
95  !
96  fft_in(1:g_rh%nr) = vlocg(1:g_rh%nr)
97  call fftw_execute_dft(plan_g2r, fft_in, fft_out)
98  vlocr(1:g_rh%nr) = dble(fft_out(1:g_rh%nr))
99  !
100  end subroutine fft_g2r
104  subroutine fft_r2g_w(wfR, wfG)
105  !
106  use atm_spec, only : vcell
107  use gvec, only : g_rh, g_wf
108  !
109  complex(8),intent(in) :: wfR(g_rh%nr)
110  complex(8),intent(out) :: wfG(g_wf%npw)
111  !
112  fft_in(1:g_rh%nr) = wfr(1:g_rh%nr)
113  call fftw_execute_dft(plan_r2g, fft_in, fft_out)
114  wfg(1:g_wf%npw) = fft_out(w2r(1:g_wf%npw)) * sqrt(vcell) / dble(g_rh%nr)
115  !
116  end subroutine fft_r2g_w
120  subroutine fft_g2r_w(wfG, wfR)
121  !
122  use atm_spec, only : vcell
123  use gvec, only : g_rh, g_wf
124  !
125  complex(8),intent(in) :: wfG(g_wf%npw)
126  complex(8),intent(out) :: wfR(g_rh%nr)
127  !
128  fft_in(1:g_rh%nr) = 0.0d0
129  fft_in(w2r(1:g_wf%npw)) = wfg(1:g_wf%npw)
130  call fftw_execute_dft(plan_g2r, fft_in, fft_out)
131  wfr(1:g_rh%nr) = fft_out(1:g_rh%nr) / sqrt(vcell)
132  !
133  end subroutine fft_g2r_w
134  !
135 end module fftw_wrapper
atm_spec::vcell
real(8), save vcell
Unit cell volume [Bohr^3].
Definition: atm_spec.F90:50
fftw_wrapper::fft_r2g
subroutine fft_r2g(VlocR, VlocG)
v(r) e^{-iGr} -> V(G)
Definition: fftw_wrapper.F90:75
fftw_wrapper::fft_r2g_w
subroutine fft_r2g_w(wfR, wfG)
w(r) e^{-iGr} -> W(G) -> compress
Definition: fftw_wrapper.F90:105
gvec::g_wf
type(fft), save g_wf
Definition: gvec.F90:38
fftw_wrapper
Definition: fftw_wrapper.F90:23
fftw_wrapper::w2r
integer, dimension(:), allocatable, save w2r
(g_wfnpw) g_wfnpw -> g_rhnr
Definition: fftw_wrapper.F90:35
gvec
Definition: gvec.F90:23
fftw_wrapper::init_fft
subroutine init_fft()
Definition: fftw_wrapper.F90:47
gvec::g_rh
type(fft), save g_rh
Definition: gvec.F90:37
fftw_wrapper::fft_g2r
subroutine fft_g2r(VlocG, VlocR)
V(G) e^{iGr} -> v(r)
Definition: fftw_wrapper.F90:90
fftw_wrapper::fft_g2r_w
subroutine fft_g2r_w(wfG, wfR)
Uncompress -> W(G) e^{iGr} -> w(r)
Definition: fftw_wrapper.F90:121
atm_spec
Definition: atm_spec.F90:23