The Elk Code
genkpakq.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2017 T. Mueller, J. K. Dewhurst, S. Sharma and E. K. U. Gross.
3 ! This file is distributed under the terms of the GNU General Public License.
4 ! See the file COPYING for license details.
5 
6 subroutine genkpakq
7 use modmain
8 use modulr
9 implicit none
10 ! local variables
11 integer i1,i2,i3,j1,j2,j3
12 integer ik0,ik,ikpa,nk,i
13 integer n1,iq,ifq,ir
14 real(8) v(3)
15 ! allocatable arrays
16 real(8), allocatable :: vkl0(:,:),vkc0(:,:),wkpt0(:)
17 ! find next largest FFT-compatible Q-point grid size
18 call nfftifc(npfftq,3,ngridq)
19 ! total number of Q-points
20 nqpt=ngridq(1)*ngridq(2)*ngridq(3)
21 ! number of complex FFT elements for real-complex transforms
22 n1=ngridq(1)/2+1
23 nfqrz=n1*ngridq(2)*ngridq(3)
24 ! integer grid intervals for the Q-points
25 intq(1,1:3)=ngridq(1:3)/2-ngridq(1:3)+1
26 intq(2,1:3)=ngridq(1:3)/2
27 ! κ-point grid should be half the Q-point grid unless specified
28 do i=1,3
29  nk=(ngridq(i)+1)/2
30  if (ngridkpa(i) > 0) then
31  ngridkpa(i)=min(ngridkpa(i),nk)
32  else
33  ngridkpa(i)=nk
34  end if
35 end do
36 ! number of κ-points
38 ! integer grid intervals for the κ-points
39 intkpa(1,1:3)=ngridkpa(1:3)/2-ngridkpa(1:3)+1
40 intkpa(2,1:3)=ngridkpa(1:3)/2
41 ! allocate global Q-point arrays
42 if (allocated(ivq)) deallocate(ivq)
43 allocate(ivq(3,nqpt))
44 if (allocated(ivqiq)) deallocate(ivqiq)
45 allocate(ivqiq(intq(1,1):intq(2,1),intq(1,2):intq(2,2),intq(1,3):intq(2,3)))
46 if (allocated(iqfft)) deallocate(iqfft)
47 allocate(iqfft(nqpt))
48 if (allocated(ifqrz)) deallocate(ifqrz)
49 allocate(ifqrz(nqpt))
50 if (allocated(iqrzf)) deallocate(iqrzf)
51 allocate(iqrzf(nfqrz))
52 if (allocated(vql)) deallocate(vql)
53 allocate(vql(3,nqpt))
54 if (allocated(vqc)) deallocate(vqc)
55 allocate(vqc(3,nqpt))
56 if (allocated(qc)) deallocate(qc)
57 allocate(qc(nqpt))
58 if (allocated(wqpt)) deallocate(wqpt)
59 allocate(wqpt(nqpt))
60 wqpt(:)=0.d0
61 ! store the κ-points as the first nkpa entries in the Q-point arrays
62 iq=0
63 do i1=intkpa(1,1),intkpa(2,1)
64  do i2=intkpa(1,2),intkpa(2,2)
65  do i3=intkpa(1,3),intkpa(2,3)
66  iq=iq+1
67  ivq(1,iq)=i1
68  ivq(2,iq)=i2
69  ivq(3,iq)=i3
70  end do
71  end do
72 end do
73 ! store the remaining Q-points
74 do i1=intq(1,1),intq(2,1)
75  do i2=intq(1,2),intq(2,2)
76  do i3=intq(1,3),intq(2,3)
77  if ((i1 < intkpa(1,1)).or.(i1 > intkpa(2,1)).or. &
78  (i2 < intkpa(1,2)).or.(i2 > intkpa(2,2)).or. &
79  (i3 < intkpa(1,3)).or.(i3 > intkpa(2,3))) then
80  iq=iq+1
81  ivq(1,iq)=i1
82  ivq(2,iq)=i2
83  ivq(3,iq)=i3
84  end if
85  end do
86  end do
87 end do
88 ! ensure the first point is the zero vector
89 do iq=1,nkpa
90  if ((ivq(1,iq) == 0).and.(ivq(2,iq) == 0).and.(ivq(3,iq) == 0)) then
91  ivq(1:3,iq)=ivq(1:3,1)
92  ivq(1:3,1)=0
93  exit
94  end if
95 end do
96 do iq=1,nqpt
97  i1=ivq(1,iq); i2=ivq(2,iq); i3=ivq(3,iq)
98 ! map from (i1,i2,i3) to Q-vector index
99  ivqiq(i1,i2,i3)=iq
100 ! Q-vector in Cartesian coordinates
101  vqc(1:3,iq)=dble(i1)*bvecu(1:3,1) &
102  +dble(i2)*bvecu(1:3,2) &
103  +dble(i3)*bvecu(1:3,3)
104 ! Q-vector length
105  qc(iq)=norm2(vqc(1:3,iq))
106 ! Q-vector in (unit cell) lattice coordinates
107  call r3mv(binv,vqc(:,iq),vql(:,iq))
108  where(abs(vql(1:3,iq)) < epslat) vql(1:3,iq)=0.d0
109 end do
110 ! set up Fourier transform index
111 do iq=1,nqpt
112  i1=ivq(1,iq); i2=ivq(2,iq); i3=ivq(3,iq)
113  if (i1 >= 0) then
114  j1=i1
115  else
116  j1=ngridq(1)+i1
117  end if
118  if (i2 >= 0) then
119  j2=i2
120  else
121  j2=ngridq(2)+i2
122  end if
123  if (i3 >= 0) then
124  j3=i3
125  else
126  j3=ngridq(3)+i3
127  end if
128  iqfft(iq)=j3*ngridq(2)*ngridq(1)+j2*ngridq(1)+j1+1
129 ! map from q-point index to real-complex FFT index and vice versa
130  if (i1 >= 0) then
131  ifq=j3*ngridq(2)*n1+j2*n1+j1+1
132  ifqrz(iq)=ifq
133  iqrzf(ifq)=iq
134  end if
135 end do
136 ! store the R-vectors in Cartesian coordinates spanning the ultracell
137 if (allocated(vrcu)) deallocate(vrcu)
138 allocate(vrcu(3,nqpt))
139 ir=0
140 do i3=0,ngridq(3)-1
141  v(3)=dble(i3)/dble(ngridq(3))
142  do i2=0,ngridq(2)-1
143  v(2)=dble(i2)/dble(ngridq(2))
144  do i1=0,ngridq(1)-1
145  v(1)=dble(i1)/dble(ngridq(1))
146  ir=ir+1
147  call r3mv(avecu,v,vrcu(:,ir))
148  end do
149  end do
150 end do
151 ! allocate the k-point weight array for band structure calculation
152 if (any(task == [720,725])) then
153  if (allocated(wkpt)) deallocate(wkpt)
154  allocate(wkpt(nkpt))
155  wkpt(1:nkpt)=1.d0
156 end if
157 ! store the existing k-point and weight arrays
158 allocate(vkl0(3,nkpt),vkc0(3,nkpt),wkpt0(nkpt))
159 vkl0(1:3,1:nkpt)=vkl(1:3,1:nkpt)
160 vkc0(1:3,1:nkpt)=vkc(1:3,1:nkpt)
161 wkpt0(1:nkpt)=wkpt(1:nkpt)
162 ! number of k+κ-points
163 nkpt0=nkpt
165 ! deallocate and reallocate k-point and weight arrays
166 deallocate(vkl,vkc,wkpt)
167 allocate(vkl(3,nkpt),vkc(3,nkpt),wkpt(nkpt))
168 ik=0
169 do ik0=1,nkpt0
170  do ikpa=1,nkpa
171  ik=ik+1
172  vkl(1:3,ik)=vkl0(1:3,ik0)+vql(1:3,ikpa)
173  vkc(1:3,ik)=vkc0(1:3,ik0)+vqc(1:3,ikpa)
174  wkpt(ik)=wkpt0(ik0)/dble(nkpa)
175  end do
176 end do
177 deallocate(vkl0,vkc0,wkpt0)
178 end subroutine
179 
real(8), dimension(:), allocatable qc
Definition: modmain.f90:552
integer task
Definition: modmain.f90:1299
integer nqpt
Definition: modmain.f90:528
integer nkpt
Definition: modmain.f90:464
integer, dimension(:,:), allocatable ivq
Definition: modmain.f90:532
integer nkpt0
Definition: modulr.f90:18
integer, dimension(3) ngridkpa
Definition: modulr.f90:20
integer, dimension(:), allocatable iqrzf
Definition: modmain.f90:546
real(8), dimension(3, 3) bvecu
Definition: modulr.f90:14
integer, dimension(:), allocatable iqfft
Definition: modmain.f90:540
real(8), dimension(:,:), allocatable vkc
Definition: modmain.f90:476
subroutine genkpakq
Definition: genkpakq.f90:7
real(8), dimension(:,:), allocatable vqc
Definition: modmain.f90:550
real(8), dimension(:), allocatable wkpt
Definition: modmain.f90:478
real(8), dimension(:,:), allocatable vql
Definition: modmain.f90:548
real(8), dimension(3, 3) avecu
Definition: modulr.f90:12
integer, dimension(:,:,:), allocatable ivqiq
Definition: modmain.f90:534
integer npfftq
Definition: modmain.f90:538
integer, dimension(3) ngridq
Definition: modmain.f90:518
real(8), dimension(:,:), allocatable vkl
Definition: modmain.f90:474
real(8), dimension(3, 3) binv
Definition: modmain.f90:18
integer nfqrz
Definition: modmain.f90:542
integer, dimension(2, 3) intq
Definition: modmain.f90:520
real(8) epslat
Definition: modmain.f90:24
real(8), dimension(:,:), allocatable vrcu
Definition: modulr.f90:26
integer, dimension(:), allocatable ifqrz
Definition: modmain.f90:544
real(8), dimension(:), allocatable wqpt
Definition: modmain.f90:554
pure subroutine r3mv(a, x, y)
Definition: r3mv.f90:10
integer, dimension(2, 3) intkpa
Definition: modulr.f90:22
Definition: modulr.f90:6
integer nkpa
Definition: modulr.f90:24
subroutine nfftifc(np, nd, n)
Definition: nfftifc.f90:10