pwdft  0.1
PW-DFT code for education
gvec.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 !
23 module gvec
24  !
25  implicit none
26  !
27  type fft
28  integer :: &
29  & nft(3), & !< FFT grid
30  & nr, & !< Number of r in whole grid, product(nft(1:3))
31  & npw !< Number of PW inside sphere
32  integer,allocatable :: &
33  & map(:), & !< (npw) npw(sphere) -> nr(grid) mapper
34  & mill(:,:) !< (3,npw) Miller index
35  end type fft
36  !
37  type(fft),save :: g_rh
38  type(fft),save :: g_wf
39  !
40 contains
41  !
42  subroutine setup_gvec(xfft,g2cut)
43  !
44  use constant, only : pi
45  use atm_spec, only : avec, bvec
46  !
47  real(8),intent(in) :: g2cut
48  type(fft),intent(out) :: xfft
49  !
50  integer :: ii, i1, i2, i3, nmax3(3), nmax
51  real(8) :: norm, gv0(3), g2
52  integer,allocatable :: mill0(:,:)
53  !
54  do ii = 1, 3
55  norm = sqrt(dot_product(avec(1:3,ii), avec(1:3,ii)))
56  nmax3(ii) = ceiling(sqrt(g2cut)*norm/(2.0d0*pi))
57  end do
58  !
59  nmax = product(nmax3(1:3)*2+1)
60  allocate(mill0(3,nmax))
61  !
62  xfft%npw = 0
63  do i3 = -nmax3(3), nmax3(3)
64  do i2 = -nmax3(2), nmax3(2)
65  do i1 = -nmax3(1), nmax3(1)
66  gv0(1:3) = matmul(bvec(1:3,1:3), dble((/i1,i2,i3/)))
67  g2 = dot_product(gv0,gv0)
68  if(g2 < g2cut) then
69  xfft%npw = xfft%npw + 1
70  mill0(1:3,xfft%npw) = (/i1,i2,i3/)
71  end if
72  end do
73  end do
74  end do
75  !
76  write(*,*) " Numver of PW inside sphere : ", xfft%npw
77  !
78  ! Find FFT grid
79  !
80  do ii = 1, 3
81  xfft%nft(ii) = maxval(mill0(ii,1:xfft%npw))*2 + 1
82  call base2357(xfft%nft(ii))
83  end do
84  !
85  write(*,*) " FFT grid : ", xfft%nft(1:3)
86  xfft%nr = product(xfft%nft(1:3))
87  write(*,*) " Numver of PW in grid : ", xfft%nr
88  allocate(xfft%mill(3,xfft%nr), xfft%map(xfft%npw))
89  !
90  ! Whole grid : Miller index
91  !
92  ii = 0
93  do i3 = 0, xfft%nft(3) - 1
94  do i2 = 0, xfft%nft(2) - 1
95  do i1 = 0, xfft%nft(1) - 1
96  ii = ii + 1
97  xfft%mill(1:3,ii) = modulo((/i1, i2, i3/) + xfft%nft(1:3)/2, xfft%nft(1:3)) &
98  & - xfft%nft(1:3)/2
99  end do
100  end do
101  end do
102  !
103  ! Mapper
104  !
105  do ii = 1, xfft%npw
106  mill0(1:3,ii) = modulo(mill0(1:3,ii), xfft%nft(1:3))
107  xfft%map(ii) = 1 + mill0(1,ii) + xfft%nft(1)*(mill0(2,ii) + xfft%nft(2)*mill0(3,ii))
108  end do
109  !
110  deallocate(mill0)
111  !
112  end subroutine setup_gvec
113  !
114  subroutine base2357(nfft)
115  !
116  integer,intent(inout) :: nfft
117  !
118  integer :: base(4) = (/2,3,5,7/), ibase, iexp, &
119  & start, last, nexp, nfft1, nfft2
120  !
121  start = nfft
122  last = 2 * nfft
123  !
124  do nfft1 = start, last
125  !
126  nfft2 = nfft1
127  !
128  do ibase = 1, 4
129  !
130  nexp = ceiling(log(dble(nfft2))/log(dble(base(ibase))))
131  !
132  do iexp = 1, nexp
133  if(mod(nfft2, base(ibase)) == 0) then
134  nfft2 = nfft2 / base(ibase)
135  else
136  exit
137  end if
138  end do
139  !
140  if(nfft2 == 1) then
141  nfft = nfft1
142  return
143  end if
144  !
145  end do
146  !
147  end do
148  !
149  end subroutine base2357
150  !
151 end module gvec
atm_spec::avec
real(8), dimension(3, 3), save avec
Unit lattice vector [Bohr].
Definition: atm_spec.F90:50
gvec::base2357
subroutine base2357(nfft)
Definition: gvec.F90:115
constant
Definition: constant.F90:23
gvec::fft
Definition: gvec.F90:27
gvec::g_wf
type(fft), save g_wf
Definition: gvec.F90:38
constant::pi
real(8), parameter pi
Definition: constant.F90:25
gvec
Definition: gvec.F90:23
gvec::setup_gvec
subroutine setup_gvec(xfft, g2cut)
Definition: gvec.F90:43
gvec::g_rh
type(fft), save g_rh
Definition: gvec.F90:37
atm_spec::bvec
real(8), dimension(3, 3), save bvec
Unit reciplocal lattice vector [Bohr^-1].
Definition: atm_spec.F90:50
atm_spec
Definition: atm_spec.F90:23