The Elk Code
fermisurf.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2002-2008 J. K. Dewhurst, S. Sharma and C. Ambrosch-Draxl.
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 fermisurf
7 use modmain
8 use modomp
9 implicit none
10 ! local variables
11 integer ik,ist,np,nfp,i
12 integer ist0,ist1,jst0,jst1
13 integer l,i1,i2,i3,nthd
14 real(8) e0,e1,v(3),x,fn
15 ! allocatable arrays
16 real(8), allocatable :: evalfv(:,:),vpc(:,:)
17 complex(8), allocatable :: evecfv(:,:,:),evecsv(:,:)
18 ! external functions
19 real(8), external :: sdelta
20 ! initialise universal variables
21 call init0
22 ! no k-point reduction for the collinear case
24 if (ndmag == 1) reducek=0
25 call init1
26 ! read density and potentials from file
27 call readstate
28 ! Fourier transform Kohn-Sham potential to G-space
29 call genvsig
30 ! find the new linearisation energies
31 call linengy
32 ! generate the APW and local-orbital radial functions and integrals
33 call genapwlofr
34 ! generate the spin-orbit coupling radial functions
35 call gensocfr
36 ! begin parallel loop over reduced k-points set
37 call holdthd(nkpt,nthd)
38 !$OMP PARALLEL DEFAULT(SHARED) &
39 !$OMP PRIVATE(evalfv,evecfv,evecsv) &
40 !$OMP NUM_THREADS(nthd)
41 allocate(evalfv(nstfv,nspnfv))
42 allocate(evecfv(nmatmax,nstfv,nspnfv),evecsv(nstsv,nstsv))
43 !$OMP DO SCHEDULE(DYNAMIC)
44 do ik=1,nkpt
45 !$OMP CRITICAL(fermisurf_)
46  write(*,'("Info(fermisurf): ",I6," of ",I6," k-points")') ik,nkpt
47 !$OMP END CRITICAL(fermisurf_)
48 ! solve the first- and second-variational eigenvalue equations
49  call eveqn(ik,evalfv,evecfv,evecsv)
50 ! end loop over reduced k-points set
51 end do
52 !$OMP END DO
53 deallocate(evalfv,evecfv,evecsv)
54 !$OMP END PARALLEL
55 call freethd(nthd)
56 ! if iterative diagonalisation is used the eigenvalues must be reordered
57 if (tefvit.and.(.not.spinpol)) then
58  do ik=1,nkpt
59  call sort(nstsv,evalsv(:,ik))
60  end do
61 end if
62 ! generate the plotting point grid in Cartesian coordinates (this has the same
63 ! arrangement as the k-point grid)
64 np=np3d(1)*np3d(2)*np3d(3)
65 allocate(vpc(3,np))
66 call plotpt3d(vpc)
67 do i=1,np
68  v(:)=vpc(:,i)
69  call r3mv(bvec,v,vpc(:,i))
70 end do
71 ! number of files to plot (2 for collinear magnetism, 1 otherwise)
72 if (ndmag == 1) then
73  nfp=2
74 else
75  nfp=1
76 end if
77 do l=1,nfp
78  if (nfp == 2) then
79  if (l == 1) then
80  open(50,file='FERMISURF_UP.OUT',form='FORMATTED',action='WRITE')
81  jst0=1; jst1=nstfv
82  else
83  open(50,file='FERMISURF_DN.OUT',form='FORMATTED',action='WRITE')
84  jst0=nstfv+1; jst1=2*nstfv
85  end if
86  else
87  open(50,file='FERMISURF.OUT',form='FORMATTED',action='WRITE')
88  jst0=1; jst1=nstsv
89  end if
90  if ((task == 100).or.(task == 101)) then
91 ! find the range of eigenvalues which contribute to the Fermi surface (Lars)
92  ist0=jst1; ist1=jst0
93  do ist=jst0,jst1
94  e0=minval(evalsv(ist,:)); e1=maxval(evalsv(ist,:))
95 ! determine if the band crosses the Fermi energy
96  if ((e0 < efermi).and.(e1 > efermi)) then
97  ist0=min(ist0,ist); ist1=max(ist1,ist)
98  end if
99  end do
100  else
101 ! use all eigenvalues
102  ist0=jst0; ist1=jst1
103  end if
104  if ((task == 100).or.(task == 103)) then
105  write(50,'(3I6," : grid size")') np3d(:)
106  i=0
107  do i3=0,ngridk(3)-1
108  do i2=0,ngridk(2)-1
109  do i1=0,ngridk(1)-1
110  i=i+1
111  ik=ivkik(i1,i2,i3)
112  if (task == 100) then
113 ! write product of eigenstates minus the Fermi energy
114  fn=product(evalsv(ist0:ist1,ik)-efermi)
115  else
116 ! write single smooth delta function at the Fermi energy
117  fn=0.d0
118  do ist=ist0,ist1
119  x=(evalsv(ist,ik)-efermi)/swidth
120  fn=fn+sdelta(stype,x)/swidth
121  end do
122  end if
123  write(50,'(4G18.10)') vpc(:,i),fn
124  end do
125  end do
126  end do
127  else
128  write(50,'(4I6," : grid size, number of states")') np3d(:),ist1-ist0+1
129  i=0
130  do i3=0,ngridk(3)-1
131  do i2=0,ngridk(2)-1
132  do i1=0,ngridk(1)-1
133  i=i+1
134  ik=ivkik(i1,i2,i3)
135  write(50,'(3G18.10)',advance='NO') vpc(:,i)
136  do ist=ist0,ist1
137  if (task == 101) then
138 ! write the eigenvalues minus the Fermi energy separately
139  write(50,'(F14.8)',advance='NO') evalsv(ist,ik)-efermi
140  else
141 ! write separate smooth delta functions at the Fermi energy
142  x=(evalsv(ist,ik)-efermi)/swidth
143  write(50,'(F14.8)',advance='NO') sdelta(stype,x)/swidth
144  end if
145  end do
146  write(50,*)
147  end do
148  end do
149  end do
150  end if
151  close(50)
152 end do
153 write(*,*)
154 write(*,'("Info(fermisurf):")')
155 if (ndmag == 1) then
156  write(*,'(" 3D Fermi surface data written to FERMISURF_UP.OUT and &
157  &FERMISURF_DN.OUT")')
158 else
159  write(*,'(" 3D Fermi surface data written to FERMISURF.OUT")')
160 end if
161 if (task == 100) then
162  write(*,'(" in terms of the product of eigenvalues minus the Fermi energy")')
163 else if (task == 101) then
164  write(*,'(" in terms of separate eigenvalues minus the Fermi energy")')
165 else if (task == 103) then
166  write(*,'(" in terms of a smooth delta function at the Fermi energy")')
167 else
168  write(*,'(" in terms of separate delta functions at the Fermi energy")')
169 end if
170 deallocate(vpc)
171 ! restore original parameters
173 end subroutine
174 
integer nmatmax
Definition: modmain.f90:853
real(8) efermi
Definition: modmain.f90:907
real(8), dimension(:,:), allocatable evalsv
Definition: modmain.f90:921
integer task
Definition: modmain.f90:1299
logical spinpol
Definition: modmain.f90:228
integer nkpt
Definition: modmain.f90:461
logical tefvit
Definition: modmain.f90:873
integer ndmag
Definition: modmain.f90:238
integer reducek0
Definition: modmain.f90:455
Definition: modomp.f90:6
real(8) swidth
Definition: modmain.f90:895
integer, dimension(:,:,:), allocatable ivkik
Definition: modmain.f90:467
subroutine genvsig
Definition: genvsig.f90:10
subroutine genapwlofr
Definition: genapwlofr.f90:7
subroutine gensocfr
Definition: gensocfr.f90:7
subroutine linengy
Definition: linengy.f90:10
pure subroutine plotpt3d(vpl)
Definition: plotpt3d.f90:7
integer nstsv
Definition: modmain.f90:889
subroutine eveqn(ik, evalfv, evecfv, evecsv)
Definition: eveqn.f90:10
subroutine fermisurf
Definition: fermisurf.f90:7
integer, dimension(3) ngridk
Definition: modmain.f90:448
real(8), dimension(3, 3) bvec
Definition: modmain.f90:16
subroutine init1
Definition: init1.f90:10
integer stype
Definition: modmain.f90:891
subroutine readstate
Definition: readstate.f90:10
subroutine freethd(nthd)
Definition: modomp.f90:106
subroutine holdthd(nloop, nthd)
Definition: modomp.f90:78
subroutine sort(n, x)
Definition: sort.f90:10
integer, dimension(3) np3d
Definition: modmain.f90:1134
integer reducek
Definition: modmain.f90:455
subroutine init0
Definition: init0.f90:10
pure subroutine r3mv(a, x, y)
Definition: r3mv.f90:10
integer nstfv
Definition: modmain.f90:887
integer nspnfv
Definition: modmain.f90:289