The Elk Code
 
Loading...
Searching...
No Matches
dos.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!BOP
7! !ROUTINE: dos
8! !INTERFACE:
9subroutine dos(fext,tocc,occsvp)
10! !USES:
11use modmain
12use modomp
13use modtest
14! !INPUT/OUTPUT PARAMETERS:
15! fext : filename extension (in,character(*))
16! tocc : .true. if just the occupied orbitals should contribute to the DOS
17! (in,logical)
18! occsvp : occupation numbers of second-variational orbitals
19! (in,real(nstsv,nkpt))
20! !DESCRIPTION:
21! Produces a total and partial density of states (DOS) for plotting. The total
22! DOS is written to the file {\tt TDOS.OUT} while the partial DOS is written
23! to the file {\tt PDOS\_Sss\_Aaaaa.OUT} for atom {\tt aaaa} of species
24! {\tt ss}. In the case of the partial DOS, each symmetrised
25! $(l,m)$-projection is written consecutively and separated by blank lines.
26! If the global variable {\tt lmirep} is {\tt .true.}, then the density matrix
27! from which the $(l,m)$-projections are obtained is first rotated into a
28! irreducible representation basis, i.e. one that block diagonalises all the
29! site symmetry matrices in the $Y_{lm}$ basis. Eigenvalues of a quasi-random
30! matrix in the $Y_{lm}$ basis which has been symmetrised with the site
31! symmetries are written to {\tt ELMIREP.OUT}. This allows for identification
32! of the irreducible representations of the site symmetries, for example $e_g$
33! or $t_{2g}$, by the degeneracies of the eigenvalues. In the plot, spin-up is
34! made positive and spin-down negative. See the routines {\tt gendmatk} and
35! {\tt brzint}.
36!
37! !REVISION HISTORY:
38! Created January 2004 (JKD)
39! Parallelised and included sum over m, November 2009 (F. Cricchio)
40!EOP
41!BOC
42implicit none
43! arguments
44character(*), intent(in) :: fext
45logical, intent(in) :: tocc
46real(8), intent(in) :: occsvp(nstsv,nkpt)
47! local variables
48logical tsqaz
49integer nsk(3),ik,jk,ist,iw,ld
50integer nsd,ispn,jspn,is,ia,ias
51integer lmmax,l0,l1,l,m,lm,nthd
52real(8) dw,th,sps(2),vl(3),vc(3)
53real(8) v1(3),v2(3),v3(3),t1
54complex(8) su2(2,2),b(2,2),c(2,2)
55character(256) fname
56! allocatable arrays
57! low precision for band/spin character array saves memory
58real(4), allocatable :: bc(:,:,:,:,:),sc(:,:,:)
59real(8), allocatable :: w(:),e(:,:,:),f(:,:),g(:)
60real(8), allocatable :: dt(:,:),dp(:,:,:),elm(:,:)
61complex(8), allocatable :: ulm(:,:,:),a(:,:)
62complex(8), allocatable :: dmat(:,:,:,:,:),sdmat(:,:,:)
63complex(8), allocatable :: apwalm(:,:,:,:,:)
64complex(8), allocatable :: evecfv(:,:,:),evecsv(:,:)
65lmmax=(lmaxdos+1)**2
66ld=lmmax*nspinor
67if (dosssum) then
68 nsd=1
69else
70 nsd=nspinor
71end if
72if (dosmsum) then
73 l0=0; l1=lmaxdos
74else
75 l0=1; l1=lmmax
76end if
77allocate(bc(lmmax,nspinor,natmtot,nstsv,nkptnr))
78allocate(sc(nspinor,nstsv,nkptnr))
79! generate unitary matrices which convert the Yₗₘ basis into the irreducible
80! representation basis of the symmetry group at each atomic site
81if (lmirep) then
82 allocate(elm(lmmax,natmtot))
83 allocate(ulm(lmmax,lmmax,natmtot))
84 call genlmirep(lmaxdos,lmmax,elm,ulm)
85end if
86! compute the SU(2) operator used for rotating the density matrix to the
87! desired spin-quantisation axis
88v1(:)=sqados(:)
89t1=sqrt(v1(1)**2+v1(2)**2+v1(3)**2)
90if (t1 <= epslat) then
91 write(*,*)
92 write(*,'("Error(dos): spin-quantisation axis (sqados) has zero length")')
93 write(*,*)
94 stop
95end if
96v1(:)=v1(:)/t1
97if (v1(3) >= 1.d0-epslat) then
98 tsqaz=.true.
99else
100 tsqaz=.false.
101 v2(1:2)=0.d0
102 v2(3)=1.d0
103 call r3cross(v1,v2,v3)
104! note that the spin-quantisation axis is rotated, so the density matrix should
105! be rotated in the opposite direction
106 th=-acos(v1(3))
107 call axangsu2(v3,th,su2)
108end if
109! begin parallel loop over k-points
110call holdthd(nkptnr,nthd)
111!$OMP PARALLEL DEFAULT(SHARED) &
112!$OMP PRIVATE(apwalm,evecfv,evecsv,dmat,sdmat,a) &
113!$OMP PRIVATE(jk,ispn,jspn,vl,vc) &
114!$OMP PRIVATE(is,ia,ias,ist,lm,b,c,t1) &
115!$OMP NUM_THREADS(nthd)
116allocate(apwalm(ngkmax,apwordmax,lmmaxapw,natmtot,nspnfv))
117allocate(evecfv(nmatmax,nstfv,nspnfv),evecsv(nstsv,nstsv))
118allocate(dmat(lmmax,nspinor,lmmax,nspinor,nstsv))
119allocate(sdmat(nspinor,nspinor,nstsv),a(lmmax,lmmax))
120!$OMP DO SCHEDULE(DYNAMIC)
121do ik=1,nkptnr
122! equivalent reduced k-point
123 jk=ivkik(ivk(1,ik),ivk(2,ik),ivk(3,ik))
124! loop over first-variational spins
125 do ispn=1,nspnfv
126 vl(:)=vkl(:,ik)
127 vc(:)=vkc(:,ik)
128! spin-spiral case
129 if (spinsprl) then
130 if (ispn == 1) then
131 vl(:)=vl(:)+0.5d0*vqlss(:)
132 vc(:)=vc(:)+0.5d0*vqcss(:)
133 else
134 vl(:)=vl(:)-0.5d0*vqlss(:)
135 vc(:)=vc(:)-0.5d0*vqcss(:)
136 end if
137 end if
138! find the matching coefficients
139 call match(ngk(ispn,ik),vgkc(:,:,ispn,ik),gkc(:,ispn,ik), &
140 sfacgk(:,:,ispn,ik),apwalm(:,:,:,:,ispn))
141 end do
142! get the eigenvectors from file for non-reduced k-point
143 call getevecfv('.OUT',0,vkl(:,ik),vgkl(:,:,:,ik),evecfv)
144 call getevecsv('.OUT',0,vkl(:,ik),evecsv)
145 do is=1,nspecies
146 do ia=1,natoms(is)
147 ias=idxas(ia,is)
148! generate the density matrix for all states
149 call gendmatk(.false.,.false.,0,lmaxdos,ias,nstsv,[0],ngk(:,ik),apwalm, &
150 evecfv,evecsv,lmmax,dmat)
151! convert (l,m) part to an irreducible representation if required
152 if (lmirep) then
153 do ist=1,nstsv
154 do ispn=1,nspinor
155 do jspn=1,nspinor
156 call zgemm('N','N',lmmax,lmmax,lmmax,zone,ulm(:,:,ias),lmmax, &
157 dmat(:,ispn,1,jspn,ist),ld,zzero,a,lmmax)
158 call zgemm('N','C',lmmax,lmmax,lmmax,zone,a,lmmax,ulm(:,:,ias), &
159 lmmax,zzero,dmat(:,ispn,1,jspn,ist),ld)
160 end do
161 end do
162 end do
163 end if
164! spin rotate the density matrices to desired spin-quantisation axis
165 if (spinpol.and.(.not.tsqaz)) then
166 do ist=1,nstsv
167 do lm=1,lmmax
168 b(:,:)=dmat(lm,:,lm,:,ist)
169 call z2mm(su2,b,c)
170 call z2mmct(c,su2,b)
171 dmat(lm,:,lm,:,ist)=b(:,:)
172 end do
173 end do
174 end if
175! determine the band characters from the density matrix
176 do ist=1,nstsv
177 do ispn=1,nspinor
178 do lm=1,lmmax
179 t1=dble(dmat(lm,ispn,lm,ispn,ist))
180 bc(lm,ispn,ias,ist,ik)=real(t1)
181 end do
182 end do
183 end do
184 end do
185 end do
186! compute the spin density matrices of the second-variational states
187 call gensdmat(evecsv,sdmat)
188! spin rotate the density matrices to desired spin-quantisation axis
189 if (spinpol.and.(.not.tsqaz)) then
190 do ist=1,nstsv
191 call z2mm(su2,sdmat(:,:,ist),b)
192 call z2mmct(b,su2,sdmat(:,:,ist))
193 end do
194 end if
195 do ist=1,nstsv
196 do ispn=1,nspinor
197 t1=dble(sdmat(ispn,ispn,ist))
198 sc(ispn,ist,ik)=real(t1)
199 end do
200 end do
201end do
202!$OMP END DO
203deallocate(apwalm,evecfv,evecsv,dmat,sdmat,a)
204!$OMP END PARALLEL
205call freethd(nthd)
206allocate(w(nwplot),e(nstsv,nkptnr,nspinor))
207allocate(dt(nwplot,nsd),dp(nwplot,l0:l1,nsd))
208! generate frequency grid
209dw=(wplot(2)-wplot(1))/dble(nwplot)
210do iw=1,nwplot
211 w(iw)=dw*dble(iw-1)+wplot(1)
212end do
213! number of subdivisions used for interpolation in the Brillouin zone
214nsk(:)=max(ngrkf/ngridk(:),1)
215! sign for spin in DOS
216sps(1)=1.d0
217sps(2)=-1.d0
218!-------------------!
219! total DOS !
220!-------------------!
221allocate(f(nstsv,nkptnr),g(nwplot))
222dt(:,:)=0.d0
223do ispn=1,nspinor
224 do ik=1,nkptnr
225 jk=ivkik(ivk(1,ik),ivk(2,ik),ivk(3,ik))
226 do ist=1,nstsv
227! subtract the Fermi energy
228 e(ist,ik,ispn)=evalsv(ist,jk)-efermi
229! use diagonal of spin density matrix for weight
230 f(ist,ik)=sc(ispn,ist,ik)
231 if (tocc) then
232 f(ist,ik)=f(ist,ik)*occsvp(ist,jk)
233 else
234 f(ist,ik)=f(ist,ik)*occmax
235 end if
236 end do
237 end do
238! integrate over the Brillouin zone
239 call brzint(nswplot,ngridk,nsk,ivkiknr,nwplot,wplot,nstsv,nstsv,e(:,:,ispn), &
240 f,g)
241 if (dosssum) then
242 dt(:,1)=dt(:,1)+g(:)
243 else
244 dt(:,ispn)=g(:)
245 end if
246end do
247deallocate(f,g)
248! output to file
249open(50,file='TDOS'//trim(fext),form='FORMATTED',action='WRITE')
250do ispn=1,nsd
251 do iw=1,nwplot
252 write(50,'(2G18.10)') w(iw),dt(iw,ispn)*sps(ispn)
253 end do
254 write(50,*)
255end do
256close(50)
257! skip the partial DOS if required
258if (.not.tpdos) goto 10
259!---------------------!
260! partial DOS !
261!---------------------!
262do is=1,nspecies
263 do ia=1,natoms(is)
264 ias=idxas(ia,is)
265 dp(:,:,:)=0.d0
266 do ispn=1,nspinor
267 call holdthd(lmaxdos+1,nthd)
268!$OMP PARALLEL DEFAULT(SHARED) &
269!$OMP PRIVATE(f,g,lm,ik,jk,ist) &
270!$OMP NUM_THREADS(nthd)
271 allocate(f(nstsv,nkptnr),g(nwplot))
272!$OMP DO SCHEDULE(DYNAMIC)
273 do l=0,lmaxdos
274 do lm=l**2+1,(l+1)**2
275 do ik=1,nkptnr
276 jk=ivkik(ivk(1,ik),ivk(2,ik),ivk(3,ik))
277 do ist=1,nstsv
278 f(ist,ik)=bc(lm,ispn,ias,ist,ik)
279 if (tocc) then
280 f(ist,ik)=f(ist,ik)*occsvp(ist,jk)
281 else
282 f(ist,ik)=f(ist,ik)*occmax
283 end if
284 end do
285 end do
286 call brzint(nswplot,ngridk,nsk,ivkiknr,nwplot,wplot,nstsv,nstsv, &
287 e(:,:,ispn),f,g)
288 if (dosmsum) then
289 if (dosssum) then
290 dp(:,l,1)=dp(:,l,1)+g(:)
291 else
292 dp(:,l,ispn)=dp(:,l,ispn)+g(:)
293 end if
294 else
295 if (dosssum) then
296 dp(:,lm,1)=dp(:,lm,1)+g(:)
297 else
298 dp(:,lm,ispn)=g(:)
299 end if
300 end if
301! subtract from interstitial DOS
302!$OMP CRITICAL(dos_)
303 if (dosssum) then
304 dt(:,1)=dt(:,1)-g(:)
305 else
306 dt(:,ispn)=dt(:,ispn)-g(:)
307 end if
308!$OMP END CRITICAL(dos_)
309 end do
310 end do
311!$OMP END DO
312 deallocate(f,g)
313!$OMP END PARALLEL
314 call freethd(nthd)
315 end do
316! output to file
317 write(fname,'("PDOS_S",I2.2,"_A",I4.4)') is,ia
318 open(50,file=trim(fname)//trim(fext),form='FORMATTED',action='WRITE')
319 do ispn=1,nsd
320 do l=l0,l1
321 do iw=1,nwplot
322 write(50,'(2G18.10)') w(iw),dp(iw,l,ispn)*sps(ispn)
323 end do
324 write(50,*)
325 end do
326 end do
327 close(50)
328 end do
329end do
330!------------------------------------------!
331! irreducible representations file !
332!------------------------------------------!
333if (lmirep) then
334 open(50,file='ELMIREP'//trim(fext),form='FORMATTED',action='WRITE')
335 do is=1,nspecies
336 do ia=1,natoms(is)
337 ias=idxas(ia,is)
338 write(50,*)
339 write(50,'("Species : ",I4," (",A,"), atom : ",I4)') is, &
340 trim(spsymb(is)),ia
341 do l=0,lmaxdos
342 do m=-l,l
343 lm=l*(l+1)+m+1
344 write(50,'(" l = ",I2,", m = ",I2,", lm= ",I3," : ",G18.10)') l,m, &
345 lm,elm(lm,ias)
346 end do
347 end do
348 end do
349 end do
350 close(50)
351end if
352!--------------------------!
353! interstitial DOS !
354!--------------------------!
355open(50,file='IDOS'//trim(fext),form='FORMATTED',action='WRITE')
356do ispn=1,nsd
357 do iw=1,nwplot
358 write(50,'(2G18.10)') w(iw),dt(iw,ispn)*sps(ispn)
359 end do
360 write(50,*)
361end do
362close(50)
36310 continue
364! write the total DOS to test file
365call writetest(10,'total DOS',nv=nwplot*nsd,tol=2.d-2,rva=dt)
366deallocate(bc,sc,w,e,dt,dp)
367if (lmirep) deallocate(elm,ulm)
368end subroutine
369!EOC
370
pure subroutine axangsu2(v, th, su2)
Definition axangsu2.f90:10
subroutine brzint(nsm, ngridk, nsk, ivkik, nw, wint, n, ld, e, f, g)
Definition brzint.f90:10
subroutine dos(fext, tocc, occsvp)
Definition dos.f90:10
subroutine gendmatk(tspndg, tlmdg, lmin, lmax, ias, nst, idx, ngp, apwalm, evecfv, evecsv, ld, dmat)
Definition gendmatk.f90:8
subroutine genlmirep(lmax, ld, elm, ulm)
Definition genlmirep.f90:7
pure subroutine gensdmat(evecsv, sdmat)
Definition gensdmat.f90:10
subroutine getevecfv(fext, ikp, vpl, vgpl, evecfv)
Definition getevecfv.f90:10
subroutine getevecsv(fext, ikp, vpl, evecsv)
Definition getevecsv.f90:7
subroutine match(ngp, vgpc, gpc, sfacgp, apwalm)
Definition match.f90:10
real(8), dimension(:,:,:,:), allocatable vgkc
Definition modmain.f90:505
real(8), dimension(3) sqados
Definition modmain.f90:1098
logical dosssum
Definition modmain.f90:1086
complex(8), parameter zzero
Definition modmain.f90:1238
real(8), dimension(:,:,:), allocatable gkc
Definition modmain.f90:507
real(8) efermi
Definition modmain.f90:904
integer nkptnr
Definition modmain.f90:463
integer nspinor
Definition modmain.f90:267
integer ngrkf
Definition modmain.f90:1072
integer, dimension(maxspecies) natoms
Definition modmain.f90:36
integer, dimension(maxatoms, maxspecies) idxas
Definition modmain.f90:42
logical spinpol
Definition modmain.f90:228
integer nwplot
Definition modmain.f90:1070
integer, dimension(:,:), allocatable ngk
Definition modmain.f90:497
integer, dimension(:,:), allocatable ivk
Definition modmain.f90:465
logical lmirep
Definition modmain.f90:1095
complex(8), parameter zone
Definition modmain.f90:1238
integer nswplot
Definition modmain.f90:1074
integer lmmaxapw
Definition modmain.f90:199
logical dosmsum
Definition modmain.f90:1084
integer lmaxdos
Definition modmain.f90:1078
real(8), dimension(3) vqcss
Definition modmain.f90:295
integer apwordmax
Definition modmain.f90:760
real(8) epslat
Definition modmain.f90:24
integer natmtot
Definition modmain.f90:40
real(8), dimension(2) wplot
Definition modmain.f90:1076
integer nspnfv
Definition modmain.f90:289
real(8), dimension(:,:,:,:), allocatable vgkl
Definition modmain.f90:503
integer, dimension(3) ngridk
Definition modmain.f90:448
character(64), dimension(maxspecies) spsymb
Definition modmain.f90:78
integer nmatmax
Definition modmain.f90:848
logical tpdos
Definition modmain.f90:1082
logical spinsprl
Definition modmain.f90:283
real(8), dimension(:,:), allocatable vkl
Definition modmain.f90:471
integer ngkmax
Definition modmain.f90:499
integer, dimension(:,:,:), allocatable ivkiknr
Definition modmain.f90:469
real(8) occmax
Definition modmain.f90:898
real(8), dimension(3) vqlss
Definition modmain.f90:293
integer, dimension(:,:,:), allocatable ivkik
Definition modmain.f90:467
real(8), dimension(:,:), allocatable vkc
Definition modmain.f90:473
integer nstfv
Definition modmain.f90:884
complex(8), dimension(:,:,:,:), allocatable sfacgk
Definition modmain.f90:509
integer nspecies
Definition modmain.f90:34
real(8), dimension(:,:), allocatable evalsv
Definition modmain.f90:918
subroutine holdthd(nloop, nthd)
Definition modomp.f90:78
subroutine freethd(nthd)
Definition modomp.f90:106
subroutine writetest(id, descr, nv, iv, iva, tol, rv, rva, zv, zva)
Definition modtest.f90:16
pure subroutine r3cross(x, y, z)
Definition r3cross.f90:10
pure subroutine z2mm(a, b, c)
Definition z2mm.f90:10
pure subroutine z2mmct(a, b, c)
Definition z2mmct.f90:10