Branch data Line data Source code
1 : : !!****m* ABINIT/m_thmeig
2 : : !! NAME
3 : : !! m_thmeig
4 : : !!
5 : : !! FUNCTION
6 : : !! Calculate thermal corrections to the eigenvalues.
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2008-2026 ABINIT group (PB, XG, GA)
10 : : !! This file is distributed under the terms of the
11 : : !! GNU General Public License, see ~abinit/COPYING
12 : : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : : !!
14 : : !! SOURCE
15 : :
16 : : #if defined HAVE_CONFIG_H
17 : : #include "config.h"
18 : : #endif
19 : :
20 : : #include "abi_common.h"
21 : :
22 : : module m_thmeig
23 : :
24 : : use defs_basis
25 : : use m_abicore
26 : : use m_tetrahedron
27 : : use m_htetra
28 : : use m_errors
29 : : use m_ddb
30 : : use m_ddb_hdr
31 : : use m_xmpi
32 : : use m_sort
33 : :
34 : : use m_geometry, only : mkrdim, xred2xcart, metric
35 : : use m_symfind, only : symfind, symlatt
36 : : use m_matrix, only : mati3inv, matr3inv
37 : : use m_symtk, only : symatm
38 : : use m_crystal, only : crystal_t
39 : : use m_io_tools, only : open_file
40 : : use m_dynmat, only : asria_corr, dfpt_phfrq
41 : : use m_anaddb_dataset, only : anaddb_dataset_type
42 : : use m_pawtab, only : pawtab_type,pawtab_nullify,pawtab_free
43 : : use m_kpts, only : getkgrid
44 : :
45 : : implicit none
46 : :
47 : : private
48 : : !!***
49 : :
50 : : public :: thmeig
51 : : !!***
52 : :
53 : : contains
54 : : !!***
55 : :
56 : : !!****f* m_thmeig/thmeig
57 : : !! NAME
58 : : !! thmeig
59 : : !!
60 : : !! FUNCTION
61 : : !! This routine calculates the thermal corrections to the eigenvalues.
62 : : !! The output is this quantity for the input k point.
63 : : !!
64 : : !! INPUTS
65 : : !! elph_base_name = root filename for outputs
66 : : !! eig2_filnam = name of the eig2 database file
67 : : !! comm=MPI communicator
68 : : !!
69 : : !! OUTPUT
70 : : !!
71 : : !! SOURCE
72 : :
73 : 7 : subroutine thmeig(inp, ddb, crystal, iout, natom, mpert, msize, d2asr, comm)
74 : :
75 : : !Arguments ------------------------------------
76 : : !scalars
77 : : integer,intent(inout) :: natom
78 : : integer,intent(in) :: mpert,msize
79 : : integer,intent(in) :: comm
80 : : integer,intent(in) :: iout
81 : : type(crystal_t), intent(inout) :: crystal
82 : : type(anaddb_dataset_type),intent(inout) :: inp
83 : : type(ddb_type),intent(inout) :: ddb
84 : : !arrays
85 : : real(dp),intent(inout) :: d2asr(2,3,natom,3,natom)
86 : :
87 : :
88 : : !Local variables-------------------------------
89 : : !scalars
90 : : integer,parameter :: msppol=2,master=0,bcorr0=0
91 : : integer :: msym
92 : : integer :: nkpt,mband,ntypat
93 : : integer :: usepaw,natifc
94 : : integer :: nsym,occopt,nblok2
95 : : integer :: ntemper,telphint,thmflag
96 : : integer :: brav,chksymbreak,found,gqpt,iatom1,iatom2,iband,iblok,iblok2,idir1,idir2,ii,ikpt,ilatt,imod,index
97 : : integer :: iomega,iqpt,iqpt1,iqpt2,iqpt2_previous,iqpt3,iscf_fake,itemper
98 : : integer :: mpert_eig2,msize2,nene,ng2f,nqshft,nsym_new,unit_g2f,nqpt,nqpt_computed,qptopt,rftyp
99 : : !integer :: mqpt,nqpt2,option
100 : : integer :: unit_phdos,unitout
101 : : integer :: isym
102 : : integer :: nptsym,use_inversion
103 : : integer :: ierr
104 : : real(dp) :: ucvol
105 : : real(dp) :: g2fsmear,temperinc,tempermin
106 : : real(dp) :: bosein,deltaene,det,domega,enemax,enemin,fact2i,fact2r,factr
107 : : real(dp) :: gaussfactor,gaussprefactor,gaussval,invdet,omega,omega_max,omega_min,qnrm,qptrlen
108 : : real(dp) :: rcvol,tmp,tol,vec1i,vec1r,vec2i,vec2r,veci,vecr,xx
109 : : real(dp) :: tolsym,tolsym8 !new
110 : : character(len=500) :: message
111 : : character(len=fnlen) :: outfile, elph_base_name, eig2_filnam
112 : 7 : type(ddb_type) :: ddb_eig2
113 [ + + + + : 364 : type(ddb_hdr_type) :: ddb_hdr
+ + + + +
+ + + + +
+ + + + ]
114 : : !arrays
115 : : ! FIXME now these must be allocated
116 : : integer :: ngqpt(9),qptrlatt(3,3),rfelfd(4),rfphon(4),rfstrs(4),vacuum(3)
117 : : integer :: bravais(11)
118 : 7 : integer,allocatable :: typat(:)
119 : 7 : integer,allocatable :: symrel(:,:,:),symrec(:,:,:)
120 : 7 : integer,allocatable :: indsym(:,:,:)
121 : 7 : integer,allocatable :: indqpt(:)
122 : 7 : integer,allocatable :: symafm(:),symafm_new(:)
123 : 7 : integer,allocatable :: carflg_eig2(:,:,:,:)
124 : 7 : integer,allocatable :: ptsymrel(:,:,:),symrel_new(:,:,:)
125 : : !integer,allocatable :: symrec_new(:,:,:)
126 : : real(dp) :: rprim(3,3),gprim(3,3),rmet(3,3),gmet(3,3)
127 : : real(dp) :: acell(3)
128 : : real(dp) :: diff_qpt(3)
129 : : real(dp) :: gprimd(3,3),mesh(3,3)
130 : : real(dp) :: qlatt(3,3),qphnrm(3),qpt_search(3,3)
131 : : real(dp) :: rprimd(3,3),shiftq(3,MAX_NSHIFTK),tempqlatt(3)
132 : : real(dp) :: dummy(0),dummy2(0,0)
133 : 7 : real(dp),allocatable :: xcart(:,:),xred(:,:)
134 : 14 : real(dp),allocatable :: amu(:),zion(:)
135 : 7 : real(dp),allocatable :: tnons(:,:)
136 : 7 : real(dp),allocatable :: deigi(:,:), deigr(:,:), multi(:,:), multr(:,:)
137 : 7 : real(dp),allocatable :: dwtermi(:,:), dwtermr(:,:)
138 : 7 : real(dp),allocatable :: slope(:,:,:),thmeigen(:,:,:),zeropoint(:,:,:)
139 : 7 : real(dp),allocatable :: displ(:)
140 : 7 : real(dp),allocatable :: dos_phon(:),dtweightde(:,:),d2cart(:,:)
141 : 7 : real(dp),allocatable :: eigvec(:,:,:,:),eigval(:,:),g2f(:,:,:),intweight(:,:,:)
142 : 7 : real(dp),allocatable :: indtweightde(:,:,:),tmpg2f(:,:,:),tmpphondos(:),total_dos(:),tweight(:,:)
143 : 7 : real(dp),allocatable :: phfreq(:,:)
144 : 7 : real(dp),allocatable :: eig2dGamma(:,:,:,:),kpnt(:,:,:)
145 : 7 : real(dp),allocatable :: dedni(:,:,:,:),dednr(:,:,:,:)
146 : 7 : real(dp),allocatable :: eigen_in(:)
147 : 7 : real(dp),allocatable :: qpt_full(:,:),qptnrm(:)
148 : 7 : real(dp),allocatable :: spqpt(:,:),tnons_new(:,:),spinat(:,:)
149 : 7 : real(dp),allocatable :: wghtq(:)
150 : :
151 : 7 : type(t_tetrahedron) :: tetrahedra
152 : : !type(htetra_t) :: tetrahedra
153 : : character(len=80) :: errstr
154 : :
155 : : ! *********************************************************************
156 : :
157 : : ! Only master works for the time being
158 [ + - ]: 7 : if (xmpi_comm_rank(comm) /= master) return
159 : :
160 [ + + ]: 574 : write(message,'(83a)') ch10,('=',ii=1,80),ch10,&
161 [ + - ]: 581 : & ' Computation of the electron-phonon changes to the electronic eigenenergies '
162 : 7 : call wrtout(ab_out,message,'COLL')
163 : 7 : call wrtout(std_out,message,'COLL')
164 : :
165 : :
166 : : !=========================================================================
167 : : !0) Initializations
168 : : !=========================================================================
169 : :
170 : : !GA: TODO Perhaps those should be created at initialization of inp
171 [ + - ]: 7 : elph_base_name = trim(inp%prefix_outdata)//"_ep"
172 : 7 : eig2_filnam = inp%filename_eigr2d
173 : :
174 : :
175 : 7 : g2fsmear = inp%a2fsmear
176 : :
177 : 7 : telphint = inp%telphint
178 : 7 : temperinc = inp%temperinc
179 : 7 : tempermin = inp%tempermin
180 : 7 : thmflag = inp%thmflag
181 : :
182 : 7 : ntemper = inp%ntemper
183 : 7 : natifc = inp%natifc
184 : :
185 : : !Open Derivative DataBase then r/w Derivative DataBase preliminary information.
186 : :
187 : 7 : write(std_out, '(a)' ) '- thmeig: Initialize the second-order electron-phonon file with name :'
188 : 7 : write(std_out, '(a,a)' )'- ',trim(eig2_filnam)
189 : :
190 : 7 : call ddb_hdr%open_read(eig2_filnam, xmpi_comm_self)
191 : :
192 : 7 : mband = ddb_hdr%mband * ddb_hdr%nsppol
193 : 7 : nkpt = ddb_hdr%nkpt
194 : 7 : ntypat = ddb_hdr%ntypat
195 : :
196 : 7 : msym = ddb_hdr%msym
197 : 7 : nblok2 = ddb_hdr%nblok
198 : 7 : nsym = ddb_hdr%nsym
199 : 7 : occopt = ddb%occopt
200 : 7 : usepaw = ddb_hdr%usepaw
201 : :
202 [ - + + - : 21 : ABI_MALLOC(typat, (natom))
+ - + - -
+ - + ]
203 [ - + + - : 21 : ABI_MALLOC(zion, (ntypat))
+ - + - -
+ - + ]
204 [ - + + - : 14 : ABI_MALLOC(amu, (ntypat))
- + - + ]
205 : :
206 [ - + + - : 21 : ABI_MALLOC(xcart,(3,natom))
+ - + - -
+ - + ]
207 [ - + + - : 14 : ABI_MALLOC(xred,(3,natom))
- + - + ]
208 : :
209 [ - + + - : 21 : ABI_MALLOC(symafm, (nsym))
+ - + - -
+ - + ]
210 [ - + + - : 14 : ABI_MALLOC(spinat,(3,natom))
- + - + ]
211 : :
212 [ - + + - : 21 : ABI_MALLOC(symrel, (3,3,nsym))
+ - + - -
+ - + ]
213 [ - + + - : 14 : ABI_MALLOC(symrec, (3,3,nsym))
- + - + ]
214 [ - + + - : 21 : ABI_MALLOC(tnons, (3,nsym))
+ - + - -
+ - + ]
215 [ - + + - : 28 : ABI_MALLOC(indsym, (4,nsym,natom))
- + + - +
- + - - +
- + ]
216 : :
217 [ - + + - : 28 : ABI_MALLOC(deigi, (mband,nkpt))
- + + - +
- + - - +
- + ]
218 [ - + + - : 21 : ABI_MALLOC(deigr, (mband,nkpt))
- + + - -
+ - + ]
219 [ - + + - : 21 : ABI_MALLOC(dwtermi, (mband,nkpt))
- + + - -
+ - + ]
220 [ - + + - : 21 : ABI_MALLOC(dwtermr, (mband,nkpt))
- + + - -
+ - + ]
221 [ - + + - : 21 : ABI_MALLOC(multi, (mband,nkpt))
- + + - -
+ - + ]
222 [ - + + - : 21 : ABI_MALLOC(multr, (mband,nkpt))
- + + - -
+ - + ]
223 [ - + + - : 28 : ABI_MALLOC(slope, (2,mband,nkpt))
- + + - +
- + - - +
- + ]
224 [ - + + - : 21 : ABI_MALLOC(thmeigen, (2,mband,nkpt))
- + + - -
+ - + ]
225 [ - + + - : 21 : ABI_MALLOC(zeropoint, (2,mband,nkpt))
- + + - -
+ - + ]
226 : :
227 : : !At present, only atom-type perturbations are allowed for eig2 type matrix elements.
228 : 7 : mpert_eig2=natom
229 : 7 : msize2=3*mpert_eig2*3*mpert_eig2
230 : :
231 : 7 : ddb_eig2%nsppol = ddb_hdr%nsppol
232 : 7 : call ddb_eig2%malloc(msize2,nblok2,natom,ntypat,mpert_eig2,nkpt,mband)
233 : :
234 [ - + + - : 35 : ABI_MALLOC(eig2dGamma,(2,msize2,mband,nkpt))
- + + - -
+ + - + -
+ - - + -
+ ]
235 : :
236 [ - + + - : 28 : ABI_MALLOC(eigvec,(2,3,natom,3*natom))
+ - - + +
- + - + -
- + - + ]
237 [ - + + - : 28 : ABI_MALLOC(phfreq,(3*natom,ddb%nblok))
- + + - +
- + - - +
- + ]
238 : :
239 : : !amu = ddb%amu
240 [ + + ]: 14 : amu(:) = ddb_hdr%amu(1:ntypat)
241 [ + + ]: 26 : typat(:) = ddb_hdr%typat(1:natom)
242 [ + + ]: 14 : zion(:) = ddb_hdr%zion(1:ntypat)
243 [ + + + + : 98 : symrel(:,:,1:nsym) = ddb_hdr%symrel(:,:,1:nsym)
+ + ]
244 [ + + + + ]: 35 : tnons(:,1:nsym) = ddb_hdr%tnons(:,1:nsym)
245 : :
246 [ + + + + ]: 83 : xred(:,:) = ddb_hdr%xred(:,:)
247 : :
248 [ + + ]: 14 : symafm(:) = ddb_hdr%symafm(1:nsym)
249 [ + + + + ]: 83 : spinat(:,:) = ddb_hdr%spinat(:,1:natom)
250 : :
251 : : !symrel = ddb_hdr%symrel ! out
252 : : !tnons = ddb_hdr%tnons ! out
253 : :
254 : : !acell = ddb%acell
255 : : !natom = ddb_hdr%natom
256 [ + + ]: 28 : acell = ddb_hdr%acell
257 [ + + + + ]: 91 : rprim = ddb_hdr%rprim
258 : :
259 : : !Compute different matrices in real and reciprocal space, also
260 : : !checks whether ucvol is positive.
261 : 7 : call mkrdim(acell,rprim,rprimd)
262 : 7 : call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
263 : :
264 : : !Obtain reciprocal space primitive transl g from inverse trans of r
265 : 7 : call matr3inv(rprim,gprim)
266 : :
267 : : !Generate atom positions in cartesian coordinates
268 : 7 : call xred2xcart(natom,rprimd,xcart,xred)
269 : :
270 : : !Transposed inversion of the symmetry matrices, for use in
271 : : !the reciprocal space
272 [ + + ]: 14 : do isym=1,nsym
273 : 14 : call mati3inv(symrel(:,:,isym),symrec(:,:,isym))
274 : : end do
275 : :
276 : : !SYMATM generates for all the atoms and all the symmetries, the atom
277 : : !on which the referenced one is sent and also the translation bringing
278 : : !back this atom to the referenced unit cell
279 : 7 : tolsym8=tol8
280 : 7 : call symatm(indsym,natom,nsym,symrec(:,:,1:nsym),tnons(:,1:nsym),tolsym8,typat,xred)
281 : :
282 [ + + + + : 91391 : eig2dGamma(:,:,:,:)=zero
+ + + + ]
283 : :
284 [ - + + - : 35 : ABI_MALLOC(carflg_eig2,(3,mpert_eig2,3,mpert_eig2))
+ - - + +
- + - + -
- + - + ]
285 [ - + + - : 21 : ABI_MALLOC(kpnt,(3,nkpt,1))
+ - + - -
+ - + ]
286 : :
287 : : ! Copy a bunch of stuff back into crystal (to retain old behavior)
288 : : ! TODO comment these: doesnt make a difference
289 [ + - + - : 90 : crystal%xcart = xcart
- + - - +
+ + + ]
290 : 7 : crystal%ucvol = ucvol
291 [ + - - + : 21 : crystal%zion = zion
- - + + ]
292 [ + + + + ]: 91 : crystal%gmet = gmet
293 [ + + + + ]: 91 : crystal%rmet = rmet
294 : 7 : crystal%nsym = nsym
295 [ + - + - : 105 : crystal%symrel = symrel
+ - - + -
- + + + +
+ + ]
296 [ + - + - : 105 : crystal%symrec = symrec
+ - - + -
- + + + +
+ + ]
297 [ + - + - : 42 : crystal%tnons = tnons
- + - - +
+ + + ]
298 [ + - + - : 128 : crystal%indsym = indsym
+ - - + -
- + + + +
+ + ]
299 : :
300 : :
301 : : !=========================================================================
302 : : !1) Take care of the Gamma point for thmflag=3, 5 or 7
303 : : !=========================================================================
304 : :
305 [ + - ]: 7 : if(thmflag==3 .or. thmflag==5 .or. thmflag==7) then
306 : 7 : found=0
307 [ + - ]: 7 : do iblok2=1,nblok2
308 : :
309 : 7 : call ddb_eig2%read_d2eig(ddb_hdr, iblok2, iblok2)
310 : :
311 : : qnrm = ddb_eig2%qpt(1,iblok2)*ddb_eig2%qpt(1,iblok2)+ &
312 : : & ddb_eig2%qpt(2,iblok2)*ddb_eig2%qpt(2,iblok2)+ &
313 : 7 : & ddb_eig2%qpt(3,iblok2)*ddb_eig2%qpt(3,iblok2)
314 [ + - ]: 7 : if(qnrm < DDB_QTOL) then
315 [ + + + + : 91391 : eig2dGamma(:,:,:,:) = ddb_eig2%eig2dval(:,:,:,:)
+ + + + ]
316 : 7 : gqpt=iblok2
317 : 7 : write(std_out,*)'-thmeig: found Gamma point in EIG2 DDB, blok number ',iblok2
318 : : found=1
319 : : exit
320 : : end if
321 : : end do
322 : :
323 : : if(found==0)then
324 : : write(message,'(a,i3,2a)')&
325 : 0 : & 'Was unable to find the blok for Gamma point in EIG2 DDB file, while thmflag= ',thmflag,ch10,&
326 : 0 : & 'Action: compute the contribution from Gamma, and merge it in your EIG2 DDB file.'
327 : 0 : ABI_ERROR(message)
328 : : end if
329 : :
330 : : ! Put eig2dGamma in cartesian coordinates
331 : : call carttransf(ddb_eig2%flg,eig2dGamma,carflg_eig2,gprimd,gqpt,mband,&
332 : 7 : & mpert_eig2,msize2,natom,nblok2,nkpt,rprimd)
333 : :
334 : : end if
335 : :
336 : 7 : call ddb_hdr%close()
337 : :
338 : : !=========================================================================
339 : : !2) Calculation of dE(n,k)/dn(Q,j) : consider all q and modes
340 : : !=========================================================================
341 : :
342 [ + + ]: 7 : if(thmflag==3 .or. thmflag==4)then
343 : :
344 : :
345 : : ! Use the first list of q wavevectors
346 : 4 : nqpt=inp%nph1l
347 [ - + + - : 12 : ABI_MALLOC(spqpt,(3,nqpt))
+ - + - -
+ - + ]
348 [ + + ]: 12 : do iqpt=1,inp%nph1l
349 [ + + ]: 36 : spqpt(:,iqpt)=inp%qph1l(:,iqpt)/inp%qnrml1(iqpt)
350 : : end do
351 [ - + + - : 12 : ABI_MALLOC(wghtq,(nqpt))
+ - + - -
+ - + ]
352 [ + + ]: 12 : wghtq(:)=one/nqpt
353 : :
354 [ + - ]: 3 : else if(thmflag>=5 .and. thmflag<=8)then
355 : :
356 : : ! Generates the q point grid
357 [ + + ]: 12 : ngqpt(1:3)=inp%ngqpt(1:3)
358 : 3 : nqshft=inp%nqshft
359 : 3 : qptrlatt(:,:)=0
360 : 3 : qptrlatt(1,1)=ngqpt(1)
361 : 3 : qptrlatt(2,2)=ngqpt(2)
362 : 3 : qptrlatt(3,3)=ngqpt(3)
363 : :
364 [ - + + - : 9 : ABI_MALLOC(ptsymrel,(3,3,msym))
+ - + - -
+ - + ]
365 [ - + + - : 9 : ABI_MALLOC(symafm_new,(msym))
+ - + - -
+ - + ]
366 [ - + + - : 6 : ABI_MALLOC(symrel_new,(3,3,msym))
- + - + ]
367 [ - + + - : 9 : ABI_MALLOC(tnons_new,(3,msym))
+ - + - -
+ - + ]
368 [ + + ]: 3 : if(thmflag==7 .or. thmflag==8) then
369 : : ! Re-generate symmetry operations from the lattice and atomic coordinates
370 : 2 : tolsym=tol8
371 : 2 : call symlatt(bravais,std_out,msym,nptsym,ptsymrel,rprimd,tolsym)
372 : 2 : use_inversion=1
373 : : call symfind(gprimd,msym,natom,nptsym,1,nsym_new,0,&
374 : 2 : & ptsymrel,spinat,symafm_new,symrel_new,tnons_new,tolsym,typat,use_inversion,xred)
375 : 2 : write(std_out,*)' thmeig : found ',nsym_new,' symmetries ',ch10
376 : 2 : qptopt=1
377 : : else
378 : 1 : nsym_new=1
379 [ + + + + ]: 13 : symrel_new(:,:,1)=0 ; symrel_new(1,1,1)=1 ; symrel_new(2,2,1)=1 ; symrel_new(3,3,1)=1
380 [ + + ]: 4 : tnons_new(:,1)=zero
381 : 1 : symafm_new(1)=1
382 : 1 : qptopt=3
383 : : end if
384 : :
385 : : ! GA: This is useless
386 : 3 : brav=inp%brav
387 [ - + ]: 3 : if(abs(brav)/=1)then
388 : 0 : message = ' The possibility to have abs(brav)/=1 for thmeig was disabled.'
389 : 0 : ABI_ERROR(message)
390 : : end if
391 : :
392 : : ! Prepare to compute the q-point grid in the ZB or IZB
393 : 3 : iscf_fake=5 ! Need the weights
394 : 3 : chksymbreak=0
395 : 3 : vacuum=0
396 [ + + + + ]: 27 : shiftq(:,1:nqshft)=inp%q1shft(:,1:nqshft)
397 : : ! Compute the final number of q points
398 : : call getkgrid(chksymbreak,0,iscf_fake,dummy2,qptopt,qptrlatt,qptrlen,&
399 : : & nsym_new,0,nqpt,nqshft,nsym_new,rprimd,&
400 : 3 : & shiftq,symafm_new,symrel_new,vacuum,dummy)
401 [ - + + - : 9 : ABI_MALLOC(spqpt,(3,nqpt))
+ - + - -
+ - + ]
402 [ - + + - : 9 : ABI_MALLOC(wghtq,(nqpt))
+ - + - -
+ - + ]
403 : : call getkgrid(chksymbreak,iout,iscf_fake,spqpt,qptopt,qptrlatt,qptrlen,&
404 : : & nsym_new,nqpt,nqpt_computed,nqshft,nsym_new,rprimd,&
405 : 3 : & shiftq,symafm_new,symrel_new,vacuum,wghtq)
406 : :
407 [ - + ]: 3 : ABI_FREE(ptsymrel)
408 [ - + ]: 3 : ABI_FREE(symafm_new)
409 [ - + ]: 3 : ABI_FREE(symrel_new)
410 [ - + ]: 6 : ABI_FREE(tnons_new)
411 : :
412 : : end if
413 : :
414 : 7 : call ddb_hdr%free()
415 : :
416 : :
417 : 7 : write(message,'(a,a)')ch10,' thmeig : list of q wavevectors, with integration weights '
418 : 7 : call wrtout(ab_out,message,'COLL')
419 : 7 : call wrtout(std_out,message,'COLL')
420 [ + + ]: 28 : do iqpt=1,nqpt
421 : 21 : write(message,'(i6,3es16.6,es20.6)')iqpt,spqpt(:,iqpt),wghtq(iqpt)
422 : 21 : call wrtout(ab_out,message,'COLL')
423 : 28 : call wrtout(std_out,message,'COLL')
424 : : end do
425 : :
426 : : if(.not.allocated(indqpt))then
427 [ - + + - : 21 : ABI_MALLOC(indqpt,(nqpt))
+ - + - -
+ - + ]
428 : : end if
429 [ - + + - : 42 : ABI_MALLOC(dedni,(mband,nkpt,3*natom,nqpt))
- + + - +
- - + + -
- + + - +
- + - - +
- + ]
430 [ - + + - : 35 : ABI_MALLOC(dednr,(mband,nkpt,3*natom,nqpt))
- + + - -
+ + - - +
+ - - + -
+ ]
431 [ - + + - : 21 : ABI_MALLOC(eigen_in,(nqpt))
+ - + - -
+ - + ]
432 [ - + + - : 21 : ABI_MALLOC(qpt_full,(3,nqpt))
+ - + - -
+ - + ]
433 [ - + + - : 14 : ABI_MALLOC(qptnrm,(nqpt))
- + - + ]
434 : :
435 [ + + + + : 7246 : dednr(:,:,:,:) = zero
+ + + + ]
436 [ + + + + : 7246 : dedni(:,:,:,:) = zero
+ + + + ]
437 : :
438 : : !!Prepare the reading of the EIG2 files
439 : 7 : call ddb_hdr%open_read(eig2_filnam, xmpi_comm_self, msym=msym)
440 : 7 : call ddb_hdr%free()
441 : :
442 : : !iqpt2 will be the index of the q point bloks inside the EIG2 file
443 : 7 : iqpt2=0
444 : :
445 : : !Sum on all phonon wavevectors and modes
446 [ + + ]: 28 : do iqpt=1,nqpt
447 : :
448 : : ! Finding the target wavevector in DDB file
449 : 21 : qpt_search(:,:)=0.0d0
450 [ + + ]: 84 : qpt_search(:,1)=spqpt(:,iqpt)
451 [ + + ]: 84 : qphnrm(:)=one
452 [ + + ]: 63 : rfphon(1:2)=1
453 : : ! NOTE : at present, no LO-TO splitting included !!!
454 [ + + ]: 63 : rfelfd(1:2)=0
455 [ + + ]: 63 : rfstrs(1:2)=0
456 : 21 : rftyp=1
457 : :
458 : 21 : write(std_out,'(a,3es16.6)' )' Looking for spqpt=',qpt_search(:,1)
459 : :
460 : 21 : call ddb%get_block(iblok,qpt_search,qphnrm,rfphon,rfelfd,rfstrs,rftyp)
461 : :
462 [ - + ]: 21 : if(iblok==0) then
463 : : write(message,'(a,3es16.6,2a)')&
464 : 0 : & 'Was unable to find in DDB file, the blok for point ',spqpt(:,iqpt),ch10,&
465 : 0 : & 'Action: compute the contribution from this point, and merge it in your DDB file.'
466 : 0 : ABI_ERROR(message)
467 : : end if
468 : :
469 [ - + + - : 63 : ABI_MALLOC(d2cart,(2,msize))
+ - + - -
+ - + ]
470 : : ! Copy the dynamical matrix in d2cart
471 [ + + + + ]: 111612 : d2cart(:,1:msize)=ddb%val(:,:,iblok)
472 : :
473 : : ! Eventually impose the acoustic sum rule based on previously calculated d2asr
474 : : !call asrq0_apply(asrq0, natom, mpert, msize, crystal%xcart, d2cart)
475 [ + - ]: 21 : if (inp%asr==1 .or. inp%asr==2 .or. inp%asr==5) then
476 : 21 : call asria_corr(inp%asr,d2asr,d2cart,mpert,natom)
477 : : end if
478 : :
479 : : ! Calculation of the eigenvectors and eigenvalues
480 : : ! of the dynamical matrix
481 [ + - - + : 63 : ABI_MALLOC(displ,(2*3*natom*3*natom))
+ - + - +
- - + -
+ ]
482 [ - + + - : 63 : ABI_MALLOC(eigval,(3,natom))
+ - + - -
+ - + ]
483 : : call dfpt_phfrq(amu,displ,d2cart,eigval,eigvec,indsym,&
484 : : & mpert,msym,natom,nsym,ntypat,phfreq(:,iqpt),qphnrm(1),spqpt(:,iqpt),rprimd,inp%symdynmat,&
485 : 21 : & symrel,symafm,typat,ucvol)
486 [ - + ]: 21 : ABI_FREE(displ)
487 [ - + ]: 21 : ABI_FREE(eigval)
488 [ - + ]: 21 : ABI_FREE(d2cart)
489 : :
490 : :
491 : : ! Read the next bloks to find the next q point.
492 : 21 : found=0 ; iqpt2_previous=iqpt2
493 [ - + ]: 21 : do while (iqpt2<nblok2)
494 : 21 : iqpt2=iqpt2+1
495 : 21 : call ddb_eig2%read_d2eig(ddb_hdr, iqpt2, iqpt2)
496 [ + + ]: 84 : diff_qpt(:)=ddb_eig2%qpt(1:3,iqpt2)/ddb_eig2%nrm(1,iqpt2)-spqpt(:,iqpt)
497 [ - + ]: 21 : if(diff_qpt(1)**2+diff_qpt(2)**2+diff_qpt(3)**2 < DDB_QTOL )then
498 : : found=1
499 : : exit
500 : : end if
501 : : end do
502 : :
503 : : ! Usually, the q points come in the right order. However, this is not always the case...
504 [ - + ]: 21 : if(found==0)then
505 : :
506 : : ! If the EIG2 database file has to be read again, close it, then search for the right q point,
507 : : ! from the beginning of the file
508 : 0 : call ddb_hdr%close()
509 : :
510 : 0 : call ddb_hdr%open_read(eig2_filnam, xmpi_comm_self, msym=msym)
511 : :
512 : : ! And examine again the EIG2 file. Still, not beyond the previously examined value.
513 : 0 : found=0
514 [ # # ]: 0 : do iqpt2=1,iqpt2_previous
515 : 0 : call ddb_eig2%read_d2eig(ddb_hdr, iqpt2, iqpt2)
516 [ # # ]: 0 : diff_qpt(:)=ddb_eig2%qpt(1:3,iqpt2)/ddb_eig2%nrm(1,iqpt2)-spqpt(:,iqpt)
517 [ # # ]: 0 : if(diff_qpt(1)**2+diff_qpt(2)**2+diff_qpt(3)**2 < DDB_QTOL )then
518 : : found=1
519 : : exit
520 : : end if
521 : : end do
522 : :
523 [ # # ]: 0 : if(found==0)then
524 : : write(message,'(a,3es16.6,2a)')&
525 : 0 : & 'Was unable to find in EIG2 DDB file, the blok for point ',spqpt(:,iqpt),ch10,&
526 : 0 : & 'Action: compute the contribution from this point, and merge it in your EIG2 DDB file.'
527 : 0 : ABI_ERROR(message)
528 : : end if
529 : :
530 : 0 : call ddb_hdr%free()
531 : :
532 : : end if
533 : :
534 : : ! Put eig2dval in cartesian coordinates
535 : : call carttransf(ddb_eig2%flg,ddb_eig2%eig2dval,carflg_eig2,gprimd,iqpt,mband,&
536 : 21 : & mpert_eig2,msize2,natom,nblok2,nkpt,rprimd)
537 : :
538 [ + + ]: 148 : do imod=1,3*natom
539 : :
540 : : ! Calculate the derivative
541 [ + + + + ]: 7218 : deigr(:,:) = zero
542 [ + + + + ]: 7218 : deigi(:,:) = zero
543 [ + + + + ]: 7218 : dwtermr(:,:)=zero
544 [ + + + + ]: 7218 : dwtermi(:,:)=zero
545 : 480 : index=0
546 [ + + ]: 480 : do iatom1=1,natom
547 [ + + ]: 1560 : do idir1=1,3
548 [ + + ]: 6984 : do iatom2=1,natom
549 : : ! Compute factor for SE term
550 [ + + ]: 5544 : if(phfreq(imod,iqpt)<tol6)then
551 : : factr = zero
552 : : else
553 : 4755 : factr=one/sqrt(amu(typat(iatom1))*amu(typat(iatom2)))/phfreq(imod,iqpt)/amu_emass
554 : : end if
555 : :
556 [ + + ]: 23256 : do idir2=1,3
557 : 16632 : index = idir1 + 3*((iatom1 - 1) + natom * ((idir2-1)+3*(iatom2-1)))
558 : :
559 : : ! Compute products of polarization vectors
560 : : vecr = eigvec(1,idir1,iatom1,imod)*eigvec(1,idir2,iatom2,imod)+&
561 : 16632 : & eigvec(2,idir1,iatom1,imod)*eigvec(2,idir2,iatom2,imod)
562 : : veci = eigvec(2,idir1,iatom1,imod)*eigvec(1,idir2,iatom2,imod)-&
563 : 16632 : & eigvec(1,idir1,iatom1,imod)*eigvec(2,idir2,iatom2,imod)
564 : :
565 : : vec1r = eigvec(1,idir1,iatom1,imod)*eigvec(1,idir2,iatom1,imod)+&
566 : 16632 : & eigvec(2,idir1,iatom1,imod)*eigvec(2,idir2,iatom1,imod)
567 : : vec1i = eigvec(2,idir1,iatom1,imod)*eigvec(1,idir2,iatom1,imod)-&
568 : 16632 : & eigvec(1,idir1,iatom1,imod)*eigvec(2,idir2,iatom1,imod)
569 : :
570 : : vec2r = eigvec(1,idir1,iatom2,imod)*eigvec(1,idir2,iatom2,imod)+&
571 : 16632 : & eigvec(2,idir1,iatom2,imod)*eigvec(2,idir2,iatom2,imod)
572 : : vec2i = eigvec(2,idir1,iatom2,imod)*eigvec(1,idir2,iatom2,imod)-&
573 : 16632 : & eigvec(1,idir1,iatom2,imod)*eigvec(2,idir2,iatom2,imod)
574 : :
575 : : ! Compute factor for DW term
576 [ + + ]: 16632 : if(phfreq(imod,iqpt)<tol6)then
577 : : fact2r = zero
578 : : fact2i = zero
579 : : else
580 : : fact2r = -wghtq(iqpt)*(vec1r/amu(typat(iatom1)) + vec2r/amu(typat(iatom2)))/phfreq(imod,iqpt)/&
581 : 14265 : & amu_emass/2 !/norm(idir1)/norm(idir2)
582 : : fact2i = -wghtq(iqpt)*(vec1i/amu(typat(iatom1)) + vec2i/amu(typat(iatom2)))/phfreq(imod,iqpt)/&
583 : 14265 : & amu_emass/2 !/norm(idir1)/norm(idir2)
584 : : end if
585 : :
586 [ + + + + ]: 673920 : multr(:,:) =(ddb_eig2%eig2dval(1,index,:,:)*vecr - ddb_eig2%eig2dval(2,index,:,:)*veci) !/(norm(idir1)*norm(idir2))
587 [ + + + + ]: 673920 : multi(:,:) =(ddb_eig2%eig2dval(1,index,:,:)*veci + ddb_eig2%eig2dval(2,index,:,:)*vecr) !/(norm(idir1)*norm(idir2))
588 : :
589 : :
590 : : ! Debye-Waller Term
591 [ + - ]: 16632 : if(thmflag==3 .or. thmflag==5 .or. thmflag==7) then
592 [ + + + + ]: 673920 : dwtermr(1:mband,1:nkpt)=dwtermr(1:mband,1:nkpt)+fact2r*eig2dGamma(1,index,:,:)-fact2i*eig2dGamma(2,index,:,:)
593 [ + + + + ]: 673920 : dwtermi(1:mband,1:nkpt)=dwtermi(1:mband,1:nkpt)+fact2r*eig2dGamma(2,index,:,:)+fact2i*eig2dGamma(1,index,:,:)
594 : : end if
595 : :
596 : : ! Self-energy Term (Fan)
597 [ + + + + ]: 673920 : deigr(1:mband,1:nkpt) = deigr(1:mband,1:nkpt) + wghtq(iqpt)*factr*multr(1:mband,1:nkpt)
598 [ + + + + ]: 679464 : deigi(1:mband,1:nkpt) = deigi(1:mband,1:nkpt) + wghtq(iqpt)*factr*multi(1:mband,1:nkpt)
599 : :
600 : : end do !idir2
601 : : end do !iatom2
602 : : end do !idir1
603 : : end do !iatom1
604 : : ! Eigenvalue derivative or broadening
605 [ + - - ]: 141 : if(thmflag==3 .or. thmflag==5 .or. thmflag==7) then
606 [ + + + + ]: 7218 : dednr(1:mband,1:nkpt,imod,iqpt) = deigr(1:mband,1:nkpt) + dwtermr(1:mband,1:nkpt)
607 [ + + + + ]: 7218 : dedni(1:mband,1:nkpt,imod,iqpt) = deigi(1:mband,1:nkpt) + dwtermi(1:mband,1:nkpt)
608 : : else if(thmflag==4 .or. thmflag==6 .or. thmflag==8) then
609 [ # # # # ]: 0 : dednr(1:mband,1:nkpt,imod,iqpt) = pi*deigr(1:mband,1:nkpt)
610 [ # # # # ]: 0 : dedni(1:mband,1:nkpt,imod,iqpt) = pi*deigi(1:mband,1:nkpt)
611 : : end if
612 : :
613 : : end do ! imod
614 : : end do !iqpt
615 : :
616 : 7 : call ddb_hdr%close()
617 : :
618 : :
619 : : !=============================================================================
620 : : !3) Evaluation of the Eliashberg type spectral function
621 : : !and phonon DOS via gaussian broadning
622 : : !=============================================================================
623 : :
624 [ + - ]: 7 : if(telphint==1)then
625 : 7 : ng2f = 500 ! number of frequencies
626 : 7 : omega_min=zero
627 : 7 : omega_max=zero
628 [ + + ]: 28 : do iqpt=1,nqpt
629 [ + + ]: 148 : do imod=1,3*natom
630 : 120 : omega_min = min(omega_min,phfreq(imod,iqpt))
631 : 141 : omega_max = max(omega_max,phfreq(imod,iqpt))
632 : : end do
633 : : end do
634 : :
635 [ - + ]: 7 : ABI_MALLOC(dos_phon,(ng2f))
636 [ - + + - : 35 : ABI_MALLOC(g2f,(mband,nkpt,ng2f))
- + + - +
- + - + -
- + - + ]
637 [ - + + - : 28 : ABI_MALLOC(tmpg2f,(mband,nkpt,ng2f))
- + + - +
- - + -
+ ]
638 [ - + ]: 7 : ABI_MALLOC(tmpphondos,(ng2f))
639 : :
640 : 7 : write(std_out,'(a,es13.6)') 'omega_min :', omega_min
641 : 7 : write(std_out,'(a,es13.6)') 'omega_max :', omega_max
642 : 7 : write(std_out,'(a,i8)') 'ng2f :', ng2f
643 : :
644 : 7 : omega_max = omega_max + 0.1 * omega_max
645 : 7 : domega = (omega_max-omega_min)/(ng2f-one)
646 : :
647 : 7 : gaussprefactor = sqrt(piinv) / g2fsmear
648 : 7 : gaussfactor = one / g2fsmear
649 : :
650 [ + + + + : 227507 : g2f(:,:,:) = zero
+ + ]
651 [ + + ]: 3507 : dos_phon(:) = zero
652 : :
653 [ + + ]: 28 : do iqpt=1,nqpt
654 [ + + ]: 148 : do imod=1,3*natom
655 : 60120 : omega = omega_min
656 [ + + + + : 3609120 : tmpg2f(:,:,:) = zero
+ + ]
657 [ + + ]: 60120 : tmpphondos(:) = zero
658 [ + + ]: 60120 : do iomega=1,ng2f
659 : 60000 : xx = (omega-phfreq(imod,iqpt))*gaussfactor
660 : 60000 : gaussval = gaussprefactor*exp(-xx*xx)
661 [ + + + + ]: 3609000 : tmpg2f(:,:,iomega) = tmpg2f(:,:,iomega) + gaussval*dednr(:,:,imod,iqpt)
662 : 60000 : tmpphondos(iomega) = tmpphondos(iomega) + gaussval
663 : 60120 : omega = omega+domega
664 : : end do
665 : :
666 [ + + + + : 3609120 : g2f(:,:,:) = g2f(:,:,:) + tmpg2f(:,:,:)
+ + ]
667 [ + + ]: 60141 : dos_phon(:) = dos_phon(:) + tmpphondos(:)
668 : :
669 : : end do !imod
670 : : end do !iqpt
671 : :
672 [ + + ]: 3507 : dos_phon(:) = dos_phon(:) / nqpt
673 : :
674 : : ! output the g2f
675 [ + + + + ]: 255 : kpnt(:,:,1) = ddb_eig2%kpt(:,:)
676 : 7 : unit_g2f = 108
677 : 7 : call outg2f(domega,omega_min,omega_max,elph_base_name,g2f,g2fsmear,kpnt,mband,ng2f,nkpt,nqpt,1,telphint,unit_g2f)
678 : :
679 : : ! output the phonon DOS
680 : 7 : unit_phdos = 108
681 : 7 : call outphdos(domega,dos_phon,omega_min,omega_max,elph_base_name,g2fsmear,ng2f,nqpt,1,telphint,unit_g2f)
682 : :
683 : :
684 [ - + ]: 7 : ABI_FREE(dos_phon)
685 [ - + ]: 7 : ABI_FREE(g2f)
686 [ - + ]: 7 : ABI_FREE(tmpg2f)
687 [ - + ]: 7 : ABI_FREE(tmpphondos)
688 : :
689 : : end if !telphint
690 : :
691 : : !=======================================================================
692 : : !4) Evaluation of the Eliashberg type spectral function
693 : : !and phonon DOS via improved tetrahedron method
694 : : !=======================================================================
695 : :
696 [ - + ]: 7 : if(telphint==0)then
697 : :
698 : : ! make dimension-ful rprimd and gprimd for transformation of derivatives to cartesian coordinates.
699 : 0 : call mkrdim(acell,rprim,rprimd)
700 : 0 : call matr3inv(rprimd,gprimd)
701 : :
702 : : ! Q point Grid
703 [ # # # # ]: 0 : qpt_full(:,:) = ddb%qpt(1:3,:)
704 : :
705 : : ! Trivial Q point index
706 [ # # ]: 0 : do iqpt=1,nqpt
707 : 0 : indqpt(iqpt)=iqpt
708 : 0 : qptnrm(iqpt)= qpt_full(1,iqpt)*qpt_full(1,iqpt)+qpt_full(2,iqpt)*qpt_full(2,iqpt)+qpt_full(3,iqpt)*qpt_full(3,iqpt)
709 : : end do
710 : :
711 : : ! Build qlatt from scratch (for 5.7)
712 : 0 : tol = 0.1_dp
713 : 0 : ilatt = 0
714 : 0 : call sort_dp(nqpt,qptnrm,indqpt,tol)
715 : :
716 [ # # ]: 0 : do iqpt1=1,nqpt-2
717 [ # # ]: 0 : mesh(1:3,1) = qpt_full(1:3,indqpt(iqpt1))
718 [ # # ]: 0 : do iqpt2=iqpt1+1,nqpt-1
719 [ # # ]: 0 : mesh(1:3,2)= qpt_full(1:3,indqpt(iqpt2))
720 [ # # ]: 0 : do iqpt3=iqpt2+1,nqpt
721 [ # # ]: 0 : mesh(1:3,3)= qpt_full(1:3,indqpt(iqpt3))
722 : : det = mesh(1,1)*mesh(2,2)*mesh(3,3) + mesh(1,2)*mesh(2,3)*mesh(3,1) + mesh(1,3)*mesh(2,1)*mesh(3,2) &
723 : 0 : & -mesh(3,1)*mesh(2,2)*mesh(1,3) - mesh(3,2)*mesh(2,3)*mesh(1,1) - mesh(3,3)*mesh(2,1)*mesh(1,2)
724 : 0 : invdet = one/det
725 [ # # # # ]: 0 : if (abs(nint(invdet))==nqpt .and. abs(invdet)-nqpt < tol) then
726 : 0 : ilatt = 1
727 : 0 : qlatt(:,:) = mesh(:,:)
728 : : exit
729 : : end if
730 : : end do
731 : 0 : if(ilatt==1) exit
732 : : end do
733 [ # # ]: 0 : if(ilatt==1) exit
734 : : end do
735 : :
736 : : ! error message if qlatt not found and stop
737 [ # # ]: 0 : if(ilatt==0) then
738 : : write(message, '(a,a)' ) &
739 : 0 : & ' Could not find homogeneous basis vectors for Q point grid ',ch10
740 : 0 : call wrtout(std_out,message,'COLL')
741 : 0 : call wrtout(ab_out,message,'COLL')
742 : 0 : ABI_ERROR("Aborting now")
743 : : end if
744 : :
745 : : ! test if qlatt is righthanded and possibly fixe it
746 [ # # ]: 0 : if(invdet < 0) then
747 [ # # ]: 0 : tempqlatt(:) = qlatt(:,2)
748 [ # # ]: 0 : qlatt(:,2) = qlatt(:,1)
749 [ # # ]: 0 : qlatt(:,1) = tempqlatt(:)
750 : : end if
751 : :
752 : 0 : write(std_out,*) 'qlatt',qlatt
753 : :
754 : : ! test if qlatt generates all Q points TO DO
755 : :
756 : : ! Get tetrahedra, ie indexes of the full kpoints at their summits
757 : 0 : call init_tetra(indqpt,gprimd,qlatt,qpt_full,nqpt, tetrahedra, ierr, errstr, xmpi_comm_self)
758 : : !call htetra_init(tetra, indqpt, gprimd, qlatt, qpt_full, nqpt, kpt_ibz, nkpt_ibz, ierr, errstr, xmpi_comm_self
759 [ # # ]: 0 : ABI_CHECK(ierr==0,errstr)
760 : :
761 : : rcvol = abs (gprimd(1,1)*(gprimd(2,2)*gprimd(3,3)-gprimd(3,2)*gprimd(2,3)) &
762 : : & -gprimd(2,1)*(gprimd(1,2)*gprimd(3,3)-gprimd(3,2)*gprimd(1,3)) &
763 : 0 : & +gprimd(3,1)*(gprimd(1,2)*gprimd(2,3)-gprimd(2,2)*gprimd(1,3)))
764 : :
765 : : ! Calculate weights for phonon DOS
766 : : ! Special precautions must be taking for Gamma point
767 : : ! because of non-analytic term.
768 : : ! Non-analyticity must be taken out and treated separatly.
769 : :
770 : 0 : nene = 100 !nene=number of energies for DOS
771 [ # # # # : 0 : enemin = minval(phfreq)
# # # # #
# # # ]
772 [ # # # # : 0 : enemax = maxval(phfreq)
# # # # #
# # # ]
773 : 0 : deltaene = (enemax-enemin)/dble(nene-1)
774 : : ! redefine enemin enemax to be at rounded multiples of deltaene
775 : : ! enemin = elph_ds%fermie - dble(ifermi)*deltaene
776 : : ! enemax = elph_ds%fermie + dble(nene-ifermi-1)*deltaene
777 : :
778 [ # # # # : 0 : ABI_MALLOC(tweight,(nqpt,nene))
# # # # #
# # # #
# ]
779 [ # # # # : 0 : ABI_MALLOC(dtweightde,(nqpt,nene))
# # # # #
# ]
780 [ # # # # : 0 : ABI_MALLOC(intweight,(3*natom,nqpt,nene))
# # # # #
# # # # #
# # # # #
# ]
781 [ # # # # : 0 : ABI_MALLOC(indtweightde,(3*natom,nqpt,nene))
# # # # #
# # # #
# ]
782 : :
783 [ # # ]: 0 : do iband=1,3*natom
784 [ # # ]: 0 : eigen_in(:) = phfreq(iband,:)
785 : :
786 : : ! calculate general integration weights at each irred kpoint
787 : : ! as in Blochl et al PRB 49 16223 [[cite:Bloechl1994a]]
788 : : call get_tetra_weight(eigen_in,enemin,enemax,&
789 : : & one,nene,nqpt,tetrahedra,bcorr0,&
790 : 0 : & tweight,dtweightde,xmpi_comm_self)
791 : :
792 [ # # # # ]: 0 : intweight(iband,:,:) = tweight(:,:)
793 [ # # # # ]: 0 : indtweightde(iband,:,:) = dtweightde(:,:)
794 : :
795 : : end do !iband
796 : :
797 : : ! intdtweightse(nband,nqpt,nene) represents the weight in each energy bin for every kpt and every band
798 : : ! So phonon DOS is calculated (neglecting the non-analyticity contribution for now !!!)
799 : :
800 [ # # # # : 0 : ABI_MALLOC(total_dos,(nene))
# # # # #
# # # ]
801 [ # # # # : 0 : ABI_MALLOC(g2f,(mband,nkpt,nene))
# # # # #
# # # # #
# # # # #
# ]
802 : :
803 [ # # ]: 0 : total_dos(:) = zero
804 [ # # ]: 0 : do iband=1,3*natom
805 [ # # ]: 0 : do iqpt=1,nqpt
806 [ # # ]: 0 : total_dos(:) = total_dos + indtweightde(iband,iqpt,:)
807 : : end do
808 : : end do
809 : :
810 : : ! For the g2f function
811 : : ! Right now for one electronic band and one K point: dednr(1:mband,1:nkpt,imod,iqpt)
812 : : ! Once again must pay close attention to the Gamma point
813 [ # # # # : 0 : g2f(:,:,:) = zero
# # ]
814 [ # # ]: 0 : do ii=1,mband
815 [ # # ]: 0 : do ikpt=1,nkpt
816 [ # # ]: 0 : do iband=1,3*natom
817 [ # # ]: 0 : do iqpt=1,nqpt
818 [ # # ]: 0 : g2f(ii,ikpt,:) = g2f(ii,ikpt,:) + dednr(ii,ikpt,iband,iqpt) * indtweightde(iband,iqpt,:)
819 : : end do
820 : : end do
821 : : end do
822 : : end do
823 : :
824 : : ! output the g2f
825 : 0 : unit_g2f = 108
826 : 0 : call outg2f(deltaene,enemin,enemax,elph_base_name,g2f,g2fsmear,kpnt,mband,nene,nkpt,nqpt,tetrahedra%ntetra,telphint,unit_g2f)
827 : :
828 : : ! output the phonon DOS
829 : 0 : unit_phdos = 108
830 : 0 : call outphdos(deltaene,total_dos,enemin,enemax,elph_base_name,g2fsmear,nene,nqpt,tetrahedra%ntetra,telphint,unit_g2f)
831 : :
832 [ # # ]: 0 : ABI_FREE(tweight)
833 [ # # ]: 0 : ABI_FREE(dtweightde)
834 [ # # ]: 0 : ABI_FREE(intweight)
835 [ # # ]: 0 : ABI_FREE(indtweightde)
836 [ # # ]: 0 : ABI_FREE(total_dos)
837 [ # # ]: 0 : ABI_FREE(g2f)
838 : : end if !telphint
839 : :
840 : : !=======================================================================
841 : : !5) direct evaluation of thermal corrections
842 : : !=======================================================================
843 : :
844 : : !open TBS file
845 [ + - ]: 7 : outfile = trim(elph_base_name)//"_TBS"
846 [ - + ]: 7 : if (open_file(outfile,message,newunit=unitout,form='formatted',status='unknown') /= 0) then
847 : 0 : ABI_ERROR(message)
848 : : end if
849 : 7 : write(unitout,'(a)')'thmeig: Thermal Eigenvalue corrections (eV)'
850 : :
851 [ + + + + : 1227 : slope(:,:,:) = zero
+ + ]
852 [ + + + + : 1227 : zeropoint(:,:,:) = zero
+ + ]
853 : : !Loop on temperatures
854 [ + + ]: 77 : do itemper= 1, ntemper
855 : 70 : tmp=tempermin+temperinc*float(itemper-1)
856 [ + + + + : 12270 : thmeigen(:,:,:) = zero
+ + ]
857 : :
858 : : ! Sum on all phonon wavevectors and modes
859 [ + + ]: 280 : do iqpt=1,nqpt
860 [ + + ]: 1480 : do imod=1,3*natom
861 : :
862 : : ! Bose-Einstein distribution
863 : : ! jmb overflow with exp(). So, select bosein to be still significant wrt half
864 [ + + + + ]: 1200 : if(phfreq(imod,iqpt)<tol6 .or. (phfreq(imod,iqpt)/(kb_HaK*tmp)) > -log(tol16))then
865 : : bosein = zero
866 : : else
867 : 969 : bosein = one/(exp(phfreq(imod,iqpt)/(kb_HaK*tmp))-one)
868 : : end if
869 : :
870 : : ! Calculate total
871 [ + + + + ]: 72180 : thmeigen(1,1:mband,1:nkpt) = thmeigen(1,1:mband,1:nkpt) + dednr(1:mband,1:nkpt,imod,iqpt)*(bosein+half)
872 [ + + + + ]: 72180 : thmeigen(2,1:mband,1:nkpt) = thmeigen(2,1:mband,1:nkpt) + dedni(1:mband,1:nkpt,imod,iqpt)*(bosein+half)
873 : :
874 [ + + ]: 1410 : if(itemper==1)then
875 : : ! Calculate slope of linear regime
876 [ + + ]: 120 : if(phfreq(imod,iqpt)<tol6)then
877 : : slope(1,1:mband,1:nkpt) = slope(1,1:mband,1:nkpt)
878 : : slope(2,1:mband,1:nkpt) = slope(2,1:mband,1:nkpt)
879 : : else
880 [ + + + + ]: 5845 : slope(1,1:mband,1:nkpt) = slope(1,1:mband,1:nkpt) + dednr(1:mband,1:nkpt,imod,iqpt)*(kb_HaK/phfreq(imod,iqpt))
881 [ + + + + ]: 5845 : slope(2,1:mband,1:nkpt) = slope(2,1:mband,1:nkpt) + dedni(1:mband,1:nkpt,imod,iqpt)*(kb_HaK/phfreq(imod,iqpt))
882 : : end if
883 : : ! Calculate zero-point renormalization
884 [ + + + + ]: 7218 : zeropoint(1,1:mband,1:nkpt) = zeropoint(1,1:mband,1:nkpt) + dednr(1:mband,1:nkpt,imod,iqpt)*half
885 [ + + + + ]: 7218 : zeropoint(2,1:mband,1:nkpt) = zeropoint(2,1:mband,1:nkpt) + dedni(1:mband,1:nkpt,imod,iqpt)*half
886 : :
887 : : end if
888 : : end do ! imod
889 : : end do !iqpt
890 : :
891 : : ! Write temperature independent results
892 [ + + ]: 70 : if(itemper==1)then
893 : 7 : write(unitout,'(a)')'Temperature independent results (zero-point renormalization and slope)'
894 [ + + ]: 69 : do ikpt=1,nkpt
895 : 62 : write(unitout,'(a,3es16.8)')' Kpt :', kpnt(:,ikpt,1)
896 [ + + ]: 455 : do iband=1,mband
897 : 386 : write(unitout,'(4d22.14)') Ha_eV*zeropoint(1,iband,ikpt),Ha_eV*zeropoint(2,iband,ikpt),&
898 : 834 : & Ha_eV*slope(1,iband,ikpt),Ha_eV*slope(2,iband,ikpt)
899 : : end do
900 : : end do
901 : 7 : write(unitout,'(a)')'Temperature dependent corrections'
902 : : end if
903 : : ! Write result in file for each temperature
904 : 70 : write(unitout,'(a,es10.3,a)')'T :', tmp,' K'
905 [ + + ]: 697 : do ikpt=1,nkpt
906 : 620 : write(unitout,'(a,3es16.8)')' Kpt :', kpnt(:,ikpt,1)
907 [ + + ]: 4550 : do iband=1,mband
908 : 4480 : write(unitout,'(2d22.14)') Ha_eV*thmeigen(1,iband,ikpt), Ha_eV*thmeigen(2,iband,ikpt)
909 : : end do
910 : : end do
911 : : end do !itemper
912 : :
913 : 7 : close(unitout)
914 : :
915 : : !Write temperature-independent results to the main output file
916 : 7 : write(iout,'(a)')' '
917 [ + - + + ]: 567 : write(iout,'(80a)') ('-',ii=1,80)
918 : 7 : write(iout,'(a)')' '
919 : 7 : write(iout,'(a)')' Electron-phonon change of electronic structure.'
920 : 7 : write(iout,'(a)')' The temperature-dependent values are written in the _TBS file.'
921 : 7 : write(iout,'(a)')' Here follows, for each electronic wavevector and band :'
922 : 7 : write(iout,'(a)')' zero-point renormalisation (Ha) and linear slope (Ha/Kelvin)'
923 [ + + ]: 69 : do ikpt=1,nkpt
924 : 62 : write(iout,'(2a,i6,a,3es16.6)')ch10,' Kpt number ',ikpt,', with reduced coordinates :',kpnt(:,ikpt,1)
925 [ + + ]: 455 : do iband=1,mband
926 : 448 : write(iout,'(i6,2es20.6)') iband,zeropoint(1,iband,ikpt),slope(1,iband,ikpt)
927 : : end do
928 : : end do
929 : :
930 [ - + ]: 7 : ABI_FREE(typat)
931 [ - + ]: 7 : ABI_FREE(zion)
932 [ - + ]: 7 : ABI_FREE(amu)
933 [ - + ]: 7 : ABI_FREE(xcart)
934 [ - + ]: 7 : ABI_FREE(xred)
935 [ - + ]: 7 : ABI_FREE(symafm)
936 [ - + ]: 7 : ABI_FREE(spinat)
937 [ - + ]: 7 : ABI_FREE(symrel)
938 [ - + ]: 7 : ABI_FREE(symrec)
939 [ - + ]: 7 : ABI_FREE(indsym)
940 [ - + ]: 7 : ABI_FREE(tnons)
941 [ - + ]: 7 : ABI_FREE(deigi)
942 [ - + ]: 7 : ABI_FREE(deigr)
943 [ - + ]: 7 : ABI_FREE(dwtermi)
944 [ - + ]: 7 : ABI_FREE(dwtermr)
945 [ - + ]: 7 : ABI_FREE(multi)
946 [ - + ]: 7 : ABI_FREE(multr)
947 [ - + ]: 7 : ABI_FREE(slope)
948 [ - + ]: 7 : ABI_FREE(thmeigen)
949 [ - + ]: 7 : ABI_FREE(zeropoint)
950 : :
951 [ - + ]: 7 : ABI_FREE(dedni)
952 [ - + ]: 7 : ABI_FREE(dednr)
953 [ + - ]: 7 : if(allocated(indqpt)) then
954 : 7 : ABI_FREE(indqpt)
955 : : end if
956 [ - + ]: 7 : ABI_FREE(eigen_in)
957 [ - + ]: 7 : ABI_FREE(qpt_full)
958 [ - + ]: 7 : ABI_FREE(qptnrm)
959 [ - + ]: 7 : ABI_FREE(wghtq)
960 [ - + ]: 7 : ABI_FREE(spqpt)
961 [ - + ]: 7 : ABI_FREE(eigvec)
962 [ - + ]: 7 : ABI_FREE(phfreq)
963 : :
964 [ - + ]: 7 : ABI_FREE(eig2dGamma)
965 [ - + ]: 7 : ABI_FREE(kpnt)
966 [ - + ]: 7 : ABI_FREE(carflg_eig2)
967 : :
968 : 7 : call ddb_eig2%free()
969 : 7 : call destroy_tetra(tetrahedra)
970 : :
971 [ - + - + : 7 : end subroutine thmeig
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
- - - - -
- - - - -
- - - - -
- - - - -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + ]
972 : : !!***
973 : :
974 : : !!****f* m_thmeig/outphdos
975 : : !! NAME
976 : : !! outphdos
977 : : !!
978 : : !! FUNCTION
979 : : !! Print out phonon density of states
980 : : !!
981 : : !! INPUTS
982 : : !! deltaene = step on energy/frequency grid, in Hartree
983 : : !! dos_phon = phonon DOS calculated on a grid
984 : : !! enemin = minimal frequency
985 : : !! enemax = maximal frequency
986 : : !! filnam = file name for output to disk
987 : : !! g2fsmear = smearing width
988 : : !! nene = number of points on energy axis
989 : : !! nqpt = number of q-points
990 : : !! ntetra = number of tetrahedra, if tetrahedron interpolation is used
991 : : !! telphint = flag for el-phonon interpolation method (to indicate Gaussian or tetrahedron integration)
992 : : !! unit_phdos = unit for phonon DOS output
993 : : !!
994 : : !!
995 : : !! OUTPUT
996 : : !! only write
997 : : !!
998 : : !! SIDE EFFECTS
999 : : !!
1000 : : !! NOTES
1001 : : !! FIXME
1002 : : !! overcomplete inputs. Eliminate unit_phdos (just filnam) and deltaene (gotten from max-min/nene)
1003 : : !!
1004 : : !! SOURCE
1005 : :
1006 : 7 : subroutine outphdos(deltaene,dos_phon,enemin,enemax,filnam,g2fsmear,nene,nqpt,ntetra,telphint,unit_phdos)
1007 : :
1008 : : !Arguments ------------------------------------
1009 : : !scalars
1010 : : integer,intent(in) :: nene,nqpt,ntetra,telphint,unit_phdos
1011 : : character(len=fnlen),intent(in) :: filnam
1012 : : real(dp) :: deltaene,enemin,enemax,g2fsmear
1013 : : !arrays
1014 : : real(dp) :: dos_phon(nene)
1015 : :
1016 : : !Local variables-------------------------------
1017 : : !scalars
1018 : : integer :: iomega,iost,step10
1019 : : real(dp) :: dos_effective,omega
1020 : : character(len=fnlen) :: outfile
1021 : : character(len=500) :: message
1022 : : !arrays
1023 : :
1024 : : ! *************************************************************************
1025 : :
1026 [ + - ]: 7 : outfile = trim(filnam) // '_PDS'
1027 : 7 : write(message, '(3a)')ch10,&
1028 : 14 : & ' Will write phonon DOS in file ',trim(outfile)
1029 : 7 : call wrtout(ab_out,message,'COLL')
1030 : 7 : call wrtout(std_out,message,'COLL')
1031 : :
1032 : 7 : write(message, '(4a)')ch10,&
1033 : 7 : & ' For checking purposes, write ten values in the present file.',ch10,&
1034 : 14 : & ' Index Energy (in Ha) DOS '
1035 : 7 : call wrtout(ab_out,message,'COLL')
1036 : 7 : call wrtout(std_out,message,'COLL')
1037 : :
1038 : 7 : open (unit=unit_phdos,file=outfile,status='replace',iostat=iost)
1039 [ - + ]: 7 : if (iost /= 0) then
1040 : 0 : write (message,'(3a)')' Opening file ',trim(outfile),' as new'
1041 : 0 : ABI_ERROR(message)
1042 : : end if
1043 : :
1044 : 7 : write (unit_phdos,'(a)') '#'
1045 : 7 : write (unit_phdos,'(a)') '# ABINIT package : phonon DOS file'
1046 : 7 : write (unit_phdos,'(a)') '#'
1047 : 7 : write (unit_phdos,'(a,i10)') '# Number of Qpoints integrated over : ', nqpt
1048 : 7 : write (unit_phdos,'(a,i10)') '# Number of energy points : ', nene
1049 : 7 : write (unit_phdos,'(a,es16.6,a,es16.6,a)') '# between omega_min = ', enemin, &
1050 : 14 : & ' Ha and omega_max = ', enemax, ' Ha'
1051 [ + - ]: 7 : if(telphint==1)then
1052 : 7 : write (unit_phdos,'(a,es16.6)') '# The smearing width for gaussians is ', g2fsmear
1053 : : end if
1054 [ - + ]: 7 : if(telphint==0)then
1055 : 0 : write (unit_phdos,'(a,i10)') '# Number of tetrahedrons', ntetra
1056 : : end if
1057 : 7 : write (unit_phdos,'(a)') '#'
1058 : 7 : write (unit_phdos,'(a)') '# Index Energy (in Ha) DOS '
1059 : :
1060 : 7 : omega = enemin
1061 [ + + ]: 3507 : do iomega=1,nene
1062 : 3500 : dos_effective=dos_phon(iomega)
1063 [ + + ]: 3500 : if(abs(dos_effective)<tol16)then
1064 : 2738 : dos_effective=zero
1065 : : end if
1066 : 3500 : step10=nene/10
1067 [ + + ]: 3500 : if(mod(iomega,step10)==1)write (std_out,'(i10,es18.6,es18.6)')iomega, omega, dos_effective
1068 [ + + ]: 3500 : if(mod(iomega,step10)==1)write (ab_out,'(i10,es18.6,es18.6)')iomega, omega, dos_effective
1069 : 3500 : write (unit_phdos, '(i10,es18.6,es18.6)')iomega, omega, dos_effective
1070 : 3507 : omega=omega+deltaene
1071 : : end do
1072 : :
1073 : 7 : close (unit=unit_phdos)
1074 : :
1075 : 7 : end subroutine outphdos
1076 : : !!***
1077 : :
1078 : : !!****f* m_thmeig/outg2f
1079 : : !! NAME
1080 : : !! outg2f
1081 : : !!
1082 : : !! FUNCTION
1083 : : !! Output g2f function to file. FIXME: Paul, please explain what g2f is.
1084 : : !! Probably a variant on the Eliashberg spectral function a2F
1085 : : !!
1086 : : !! INPUTS
1087 : : !!
1088 : : !! OUTPUT
1089 : : !! only write
1090 : : !!
1091 : : !! SOURCE
1092 : :
1093 : 7 : subroutine outg2f(deltaene,enemin,enemax,filnam,g2f,g2fsmear,kpnt,mband,nene,nkpt,nqpt,ntetra,telphint,unit_g2f)
1094 : :
1095 : : !Arguments ------------------------------------
1096 : : !scalars
1097 : : integer,intent(in) :: mband,nene,nkpt,nqpt,ntetra,telphint,unit_g2f
1098 : : character(len=fnlen),intent(in) :: filnam
1099 : : real(dp) :: deltaene,enemin,enemax,g2fsmear
1100 : : !arrays
1101 : : real(dp) :: g2f(mband,nkpt,nene),kpnt(3,nkpt,nqpt)
1102 : :
1103 : : !Local variables-------------------------------
1104 : : !scalars
1105 : : integer :: iband,ikpt,iomega,iost
1106 : : real(dp) :: omega
1107 : : character(len=fnlen) :: outfile
1108 : : character(len=500) :: message
1109 : : !arrays
1110 : :
1111 : : ! *************************************************************************
1112 : :
1113 : : !output the g2f
1114 [ + - ]: 7 : outfile = trim(filnam) // '_G2F'
1115 : 7 : open (unit=unit_g2f,file=outfile,status='unknown',iostat=iost)
1116 [ - + ]: 7 : if (iost /= 0) then
1117 : 0 : write (message,'(3a)')' thmeig : ERROR- opening file ',trim(outfile),' as new'
1118 : 0 : ABI_ERROR(message)
1119 : : end if
1120 : :
1121 : 7 : write(std_out,*) ' g2f function'
1122 : 7 : write (unit_g2f,'(a)') '#'
1123 : 7 : write (unit_g2f,'(a)') '# ABINIT package : g2f file'
1124 : 7 : write (unit_g2f,'(a)') '#'
1125 : 7 : write (unit_g2f,'(a,I10)') '# number of qpoints integrated over : ', nqpt
1126 : 7 : write (unit_g2f,'(a,I10)') '# number of energy points : ', nene
1127 : 7 : write (unit_g2f,'(a,E16.6,a,E16.6,a)') '# between omega_min = ', enemin, &
1128 : 14 : & ' Ha and omega_max = ', enemax, ' Ha'
1129 [ + - ]: 7 : if(telphint==1)then
1130 : 7 : write (unit_g2f,'(a,E16.6)') '# and the smearing width for gaussians is ', g2fsmear
1131 : 7 : write (unit_g2f,'(a)') '#'
1132 : : end if
1133 [ - + ]: 7 : if(telphint==0)then
1134 : 0 : write (unit_g2f,'(a,I10)') '# number of tetrahedrons', ntetra
1135 : 0 : write (unit_g2f,'(a)') '#'
1136 : : end if
1137 : :
1138 : : !Write only the a2f function for the first K point
1139 : : !ikpt=1
1140 [ + + ]: 69 : do ikpt=1,nkpt
1141 : 62 : write(unit_g2f,'(a,3es16.8)')' Kpt :', kpnt(:,ikpt,1)
1142 [ + + ]: 455 : do iband=1,mband
1143 : 386 : write(unit_g2f,*) 'band :', iband
1144 : 386 : omega = enemin
1145 [ + + ]: 193448 : do iomega=1,nene
1146 : 193000 : write (unit_g2f,*) omega*Ha_eV*1000, g2f(iband, ikpt,iomega)
1147 : 193386 : omega=omega+deltaene
1148 : : end do
1149 : : end do
1150 : : end do
1151 : :
1152 : 7 : close (unit=unit_g2f)
1153 : :
1154 : 7 : end subroutine outg2f
1155 : : !!***
1156 : :
1157 : : end module m_thmeig
1158 : : !!***
|