pwdft  0.1
PW-DFT code for education
energy.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 energy
24  !
25  implicit none
26  !
27 contains
28  !
29  subroutine total_e()
30  !
31  use constant, only : htr2ev
32  !
33  real(8) :: Etot
34  !
35  etot = 0.0d0
36  !
37  write(*,*) " Energy per u.c. [eV]"
38  !
39  call kinetic(etot)
40  call hartree(etot)
41  call atomic(etot)
42  call ewald(etot)
43  call xc(etot)
44  !
45  write(*,*) " Total energy : ", etot*htr2ev
46  !
47  end subroutine total_e
48  !
49  subroutine kinetic(Etot)
50  !
51  use constant, only : htr2ev
52  use atm_spec, only : bvec
53  use k_point, only : nk, kvec, kgrd
54  use kohn_sham, only : nbnd, ef, eval, evec
55  use gvec, only : g_wf
56  use libtetrabz, only : libtetrabz_occ
57  !
58  real(8),intent(inout) :: Etot
59  !
60  integer :: ik, ibnd, ipw
61  real(8) :: occ(nbnd,nk), kgv(3), gg05(g_wf%npw), Ekin
62  !
63  eval(1:nbnd,1:nk) = eval(1:nbnd,1:nk) - ef
64  call libtetrabz_occ(2,bvec,nbnd,kgrd,eval,kgrd,occ)
65  eval(1:nbnd,1:nk) = eval(1:nbnd,1:nk) + ef
66  !
67  ekin = 0.0d0
68  do ik = 1, nk
69  !
70  do ipw = 1, g_wf%npw
71  kgv(1:3) = kvec(1:3,ik) + matmul(bvec(1:3,1:3), dble(g_wf%mill(1:3,g_wf%map(ipw))))
72  gg05(ipw) = 0.5d0 * dot_product(kgv,kgv)
73  end do
74  !
75  do ibnd = 1, nbnd
76  ekin = ekin + occ(ibnd,ik) &
77  & * dble(sum(conjg(evec(1:g_wf%npw,ibnd,ik)) &
78  & * evec(1:g_wf%npw,ibnd,ik) &
79  & * gg05(1:g_wf%npw ) ))
80  end do
81  end do
82  !
83  ! Spin
84  !
85  ekin = ekin * 2.0d0
86  !
87  write(*,*) " Kinetic energy : ", ekin*htr2ev
88  etot = etot + ekin
89  !
90  end subroutine kinetic
91  !
92  subroutine hartree(Etot)
93  !
94  use constant, only : pi, htr2ev
95  use gvec, only : g_rh
96  use atm_spec, only : bvec, vcell
97  use fftw_wrapper, only : fft_r2g
98  use rho_v, only : rho
99  !
100  real(8),intent(inout) :: Etot
101  !
102  integer :: ir
103  real(8) :: g3(3), EH
104  complex(8) :: rhog(g_rh%nr)
105  !
106  call fft_r2g(rho, rhog)
107  !
108  ! G = 0 : Compensation to the ionic potential
109  !
110  eh = 0.0d0
111  do ir = 2, g_rh%nr
112  g3(1:3) = matmul(bvec(1:3,1:3), dble(g_rh%mill(1:3,ir)))
113  eh = eh + 4.0d0 * pi * dble(conjg(rhog(ir))*rhog(ir)) &
114  & / dot_product(g3(1:3),g3(1:3))
115  end do
116  eh = eh * 0.5d0 * vcell
117  !
118  write(*,*) " Hartree energy : ", eh*htr2ev
119  etot = etot + eh
120  !
121  end subroutine hartree
122  !
123  subroutine atomic(Etot)
124  !
125  use constant, only : htr2ev
126  use rho_v, only : rho, vps
127  use gvec, only : g_rh
128  use atm_spec, only : vcell
129  !
130  real(8),intent(inout) :: Etot
131  !
132  real(8) :: Eps
133  !
134  eps = dot_product(rho(1:g_rh%nr), vps(1:g_rh%nr)) * vcell / dble(g_rh%nr)
135  !
136  write(*,*) " rho*V : ", eps*htr2ev
137  etot = etot + eps
138  !
139  end subroutine atomic
140  !
141  subroutine ewald(Etot)
142  !
143  use constant, only : htr2ev, pi
144  use atm_spec, only : avec, bvec, vcell, atm, spec, nat, nelec
145  !
146  real(8),intent(inout) :: Etot
147  !
148  integer :: nmax3(3), iat, jat, i1, i2, i3, ii
149  real(8) :: Eew, eta, cutoff, dtau(3), ZZ, gv(3), g2, phase, norm, rv(3)
150  !
151  eew = 0.0d0
152  !
153  eta = 0.0d0
154  do ii = 1, 3
155  norm = sqrt(dot_product(bvec(1:3,ii), bvec(1:3,ii)))
156  eta = eta + norm
157  end do
158  eta = eta / 3.0d0 / sqrt(2.0d0) / sqrt(2.0d0*pi)
159  write(*,*) " Ewald eta [Bohr^-1] : ", eta
160  !
161  ! Reciprocal space
162  !
163  cutoff = 10.0d0 * eta * 2.0d0
164  do ii = 1, 3
165  norm = sqrt(dot_product(avec(1:3,ii), avec(1:3,ii)))
166  nmax3(ii) = ceiling(cutoff*norm/(2.0d0*pi))
167  end do
168  !
169  write(*,*) " Ewald grid (G) : ", nmax3(1:3)
170  !
171  do iat = 1, nat
172  do jat = 1, nat
173  !
174  dtau(1:3) = atm(iat)%pos(1:3) - atm(jat)%pos(1:3)
175  zz = spec(atm(iat)%ityp)%Zion * spec(atm(jat)%ityp)%Zion
176  !
177  do i3 = -nmax3(3), nmax3(3)
178  do i2 = -nmax3(2), nmax3(2)
179  do i1 = -nmax3(1), nmax3(1)
180  !
181  if(all((/i1,i2,i3/)==0)) cycle
182  !
183  gv(1:3) = matmul(bvec(1:3,1:3), dble((/i1,i2,i3/)))
184  g2 = dot_product(gv,gv)
185  phase = 2.0d0*pi*dot_product(dtau(1:3), dble((/i1,i2,i3/)))
186  !
187  eew = eew &
188  & + 0.5d0 * zz * cos(phase) * 4.0d0 * pi * exp(-g2/(4.0d0*eta**2)) / (vcell*g2)
189  !
190  end do
191  end do
192  end do
193  end do
194  end do
195  !
196  eew = eew - 0.5d0 * pi * nelec**2 / (vcell*eta**2)
197  !
198  ! Real space
199  !
200  cutoff = 10.0d0 / eta
201  do ii = 1, 3
202  norm = sqrt(dot_product(bvec(1:3,ii), bvec(1:3,ii)))
203  nmax3(ii) = ceiling(cutoff*norm/(2.0d0*pi))
204  end do
205  !
206  write(*,*) " Ewald grid (R) : ", nmax3(1:3)
207  !
208  do iat = 1, nat
209  do jat = 1, nat
210  !
211  dtau(1:3) = atm(iat)%pos(1:3) - atm(jat)%pos(1:3)
212  zz = spec(atm(iat)%ityp)%Zion * spec(atm(jat)%ityp)%Zion
213  !
214  do i3 = -nmax3(3), nmax3(3)
215  do i2 = -nmax3(2), nmax3(2)
216  do i1 = -nmax3(1), nmax3(1)
217  !
218  if(all((/i1,i2,i3/)==0) .and. iat == jat) cycle
219  !
220  rv(1:3) = matmul(avec(1:3,1:3), dtau(1:3) + dble((/i1,i2,i3/)))
221  norm = sqrt(dot_product(rv(1:3), rv(1:3)))
222  !
223  eew = eew &
224  & + 0.5d0 * zz * erfc(norm*eta) / norm
225  !
226  end do
227  end do
228  end do
229  end do
230  !
231  eew = eew - eta * spec(atm(iat)%ityp)%Zion**2 / sqrt(pi)
232  !
233  end do
234  !
235  write(*,*) " Ewald energy : ", eew*htr2ev
236  etot = etot + eew
237  !
238  end subroutine ewald
239  !
240  subroutine xc(Etot)
241  !
242  use constant, only : htr2ev, pi
243  use gvec, only : g_rh
244  use rho_v, only : rho
245  use atm_spec, only : vcell
246  !
247  real(8),intent(inout) :: Etot
248  !
249  integer :: ir
250  real(8) :: rs, exc0, Exc
251  !
252  exc = 0.0d0
253  do ir = 1, g_rh%nr
254  !
255  if(rho(ir) > 1.0d-10) then
256  !
257  rs = (3.0d0 / (4.0d0 * pi * rho(ir)))**(1.0d0/3.0d0)
258  !
259  if(rs < 1.0d0) then
260  exc0 = -3.0d0 / (4.0d0*pi) * (9.0d0*pi/4)**(1.0d0/3.0d0) / rs &
261  & - 0.0480d0 + 0.031d0*log(rs) - 0.0116d0*rs + 0.0020d0*rs*log(rs)
262  else
263  exc0 = -3.0d0 / (4.0d0*pi) * (9.0d0*pi/4)**(1.0d0/3.0d0) / rs &
264  & - 0.1423d0 / (1.0d0 + 1.0529d0*sqrt(rs) + 0.3334d0*rs)
265  end if
266  !
267  exc = exc + exc0 * rho(ir)
268  !
269  end if
270  !
271  end do
272  exc = exc * vcell / dble(g_rh%nr)
273  !
274  write(*,*) " XC energy : ", exc*htr2ev
275  etot = etot + exc
276  !
277  end subroutine xc
278  !
279 end module energy
atm_spec::spec
type(spec_t), dimension(:), allocatable, save spec
(ntyp) Species
Definition: atm_spec.F90:57
atm_spec::vcell
real(8), save vcell
Unit cell volume [Bohr^3].
Definition: atm_spec.F90:50
atm_spec::avec
real(8), dimension(3, 3), save avec
Unit lattice vector [Bohr].
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
energy::ewald
subroutine ewald(Etot)
Definition: energy.F90:142
constant
Definition: constant.F90:23
energy::hartree
subroutine hartree(Etot)
Definition: energy.F90:93
libtetrabz
Definition: libtetrabz.F90:23
gvec::g_wf
type(fft), save g_wf
Definition: gvec.F90:38
rho_v::rho
real(8), dimension(:), allocatable rho
(g_rhnr) Charge density
Definition: rho_v.F90:27
kohn_sham::ef
real(8), save ef
Fermi energy [Htr].
Definition: kohn_sham.F90:31
rho_v
Definition: rho_v.F90:23
kohn_sham::evec
complex(8), dimension(:,:,:), allocatable, save evec
(g_wfnpw,nbnd,nk) Kohn-Sham eigenvector (orbital)
Definition: kohn_sham.F90:35
fftw_wrapper
Definition: fftw_wrapper.F90:23
constant::pi
real(8), parameter pi
Definition: constant.F90:25
rho_v::vps
real(8), dimension(:), allocatable vps
(g_rhnr) Pseudopotential [Htr]
Definition: rho_v.F90:27
energy::atomic
subroutine atomic(Etot)
Definition: energy.F90:124
k_point
Definition: k_point.F90:23
atm_spec::atm
type(atm_t), dimension(:), allocatable, save atm
(nat) Atom
Definition: atm_spec.F90:55
gvec
Definition: gvec.F90:23
kohn_sham::nbnd
integer, save nbnd
Number of bands.
Definition: kohn_sham.F90:29
energy::xc
subroutine xc(Etot)
Definition: energy.F90:241
k_point::nk
integer, save nk
Definition: k_point.F90:27
k_point::kgrd
integer, dimension(3), save kgrd
Definition: k_point.F90:28
kohn_sham::eval
real(8), dimension(:,:), allocatable, save eval
(nbnd,nk) Kohn-Sham eigenvalue (energy)
Definition: kohn_sham.F90:33
gvec::g_rh
type(fft), save g_rh
Definition: gvec.F90:37
atm_spec::nat
integer, save nat
Number of atoms.
Definition: atm_spec.F90:47
constant::htr2ev
real(8), parameter htr2ev
Definition: constant.F90:27
energy::kinetic
subroutine kinetic(Etot)
Definition: energy.F90:50
atm_spec::bvec
real(8), dimension(3, 3), save bvec
Unit reciplocal lattice vector [Bohr^-1].
Definition: atm_spec.F90:50
atm_spec::nelec
real(8), save nelec
Number of electrons per u.c.
Definition: atm_spec.F90:50
energy::total_e
subroutine total_e()
Definition: energy.F90:30
k_point::kvec
real(8), dimension(:,:), allocatable, save kvec
Definition: k_point.F90:30
atm_spec
Definition: atm_spec.F90:23
energy
Definition: energy.F90:23
kohn_sham
Definition: kohn_sham.F90:23