pwdft  0.1
PW-DFT code for education
energy Module Reference

Functions/Subroutines

subroutine total_e ()
 
subroutine kinetic (Etot)
 
subroutine hartree (Etot)
 
subroutine atomic (Etot)
 
subroutine ewald (Etot)
 
subroutine xc (Etot)
 

Function/Subroutine Documentation

◆ total_e()

subroutine energy::total_e

Definition at line 30 of file energy.F90.

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  !

References atomic(), ewald(), hartree(), constant::htr2ev, kinetic(), and xc().

Referenced by pwdft().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ kinetic()

subroutine energy::kinetic ( real(8), intent(inout)  Etot)

Definition at line 50 of file energy.F90.

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  !

References atm_spec::bvec, kohn_sham::ef, kohn_sham::eval, kohn_sham::evec, gvec::g_wf, constant::htr2ev, k_point::kgrd, k_point::kvec, kohn_sham::nbnd, and k_point::nk.

Referenced by total_e().

Here is the caller graph for this function:

◆ hartree()

subroutine energy::hartree ( real(8), intent(inout)  Etot)

Definition at line 93 of file energy.F90.

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  !

References atm_spec::bvec, fftw_wrapper::fft_r2g(), gvec::g_rh, constant::htr2ev, constant::pi, rho_v::rho, and atm_spec::vcell.

Referenced by total_e().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ atomic()

subroutine energy::atomic ( real(8), intent(inout)  Etot)

Definition at line 124 of file energy.F90.

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  !

References gvec::g_rh, constant::htr2ev, rho_v::rho, atm_spec::vcell, and rho_v::vps.

Referenced by total_e().

Here is the caller graph for this function:

◆ ewald()

subroutine energy::ewald ( real(8), intent(inout)  Etot)

Definition at line 142 of file energy.F90.

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  !

References atm_spec::atm, atm_spec::avec, atm_spec::bvec, constant::htr2ev, atm_spec::nat, atm_spec::nelec, constant::pi, atm_spec::spec, and atm_spec::vcell.

Referenced by total_e().

Here is the caller graph for this function:

◆ xc()

subroutine energy::xc ( real(8), intent(inout)  Etot)

Definition at line 241 of file energy.F90.

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  !

References gvec::g_rh, constant::htr2ev, constant::pi, rho_v::rho, and atm_spec::vcell.

Referenced by total_e().

Here is the caller graph for this function:
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
constant
Definition: constant.F90:23
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
fftw_wrapper
Definition: fftw_wrapper.F90:23
rho_v::vps
real(8), dimension(:), allocatable vps
(g_rhnr) Pseudopotential [Htr]
Definition: rho_v.F90:27
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
k_point::nk
integer, save nk
Definition: k_point.F90:27
k_point::kgrd
integer, dimension(3), save kgrd
Definition: k_point.F90:28
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
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
atm_spec
Definition: atm_spec.F90:23
kohn_sham
Definition: kohn_sham.F90:23