Line data Source code
1 : !!****m* ABINIT/m_phpi
2 : !! NAME
3 : !!
4 : !! FUNCTION
5 : !! Computation of phonon-electron self-energy.
6 : !!
7 : !! COPYRIGHT
8 : !! Copyright (C) 2008-2026 ABINIT group (GKA)
9 : !! This file is distributed under the terms of the
10 : !! GNU General Public License, see ~abinit/COPYING
11 : !! or http://www.gnu.org/copyleft/gpl.txt .
12 : !!
13 : !! SOURCE
14 :
15 : #if defined HAVE_CONFIG_H
16 : #include "config.h"
17 : #endif
18 :
19 : #include "abi_common.h"
20 :
21 : module m_phpi
22 :
23 : use, intrinsic :: iso_c_binding
24 : use defs_basis
25 : use m_abicore
26 : use m_xmpi
27 : use m_errors
28 : use m_ifc
29 : use m_ebands
30 : use m_nctk
31 : use netcdf
32 : use m_wfk
33 : use m_ddb
34 : use m_dvdb
35 : use m_fft
36 : use m_hamiltonian
37 : use m_pawcprj
38 : use m_dtset
39 : use m_dtfil
40 :
41 : use defs_datatypes, only : pseudopotential_type
42 : use defs_abitypes, only : mpi_type
43 : use m_time, only : cwtime
44 : use m_fstrings, only : sjoin, itoa, ftoa, ktoa, ltoa, strcat
45 : use m_io_tools, only : iomode_from_fname
46 : use m_cgtools, only : dotprod_g
47 : use m_kg, only : getph
48 : use m_fftcore, only : get_kg
49 : use m_crystal, only : crystal_t
50 : use m_bz_mesh, only : findqg0
51 : use m_wfd, only : wfd_t
52 : use m_pawang, only : pawang_type
53 : use m_pawrad, only : pawrad_type
54 : use m_pawtab, only : pawtab_type
55 : use m_pawfgr, only : pawfgr_type
56 : use m_getgh1c, only : getgh1c, rf_transgrid_and_pack, getgh1c_setup
57 :
58 : implicit none
59 :
60 : private
61 : !!***
62 :
63 : public :: eph_phpi
64 :
65 :
66 : contains !=================================================================================
67 : !!***
68 :
69 : !!****f* m_phpi/eph_phpi
70 : !! NAME
71 : !! eph_phpi
72 : !!
73 : !! FUNCTION
74 : !! Compute phonon-electron self-energy.
75 : !!
76 : !! INPUTS
77 : !! wk0_path=String with the path to the GS unperturbed WFK file.
78 : !! ngfft(18),ngfftf(18)=Coarse and Fine FFT meshes.
79 : !! dtset<dataset_type>=All input variables for this dataset.
80 : !! ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
81 : !! dvdb<dbdb_type>=Database with the DFPT SCF potentials.
82 : !! ifc<ifc_type>=interatomic force constants and corresponding real space grid info.
83 : !! pawfgr <type(pawfgr_type)>=fine grid parameters and related data
84 : !! pawang<pawang_type)>=PAW angular mesh and related data.
85 : !! pawrad(ntypat*usepaw)<pawrad_type>=Paw radial mesh and related data.
86 : !! pawtab(ntypat*usepaw)<pawtab_type>=Paw tabulated starting data.
87 : !! psps<pseudopotential_type>=Variables related to pseudopotentials.
88 : !! comm=MPI communicator.
89 : !!
90 : !! OUTPUT
91 : !!
92 : !! SOURCE
93 :
94 0 : subroutine eph_phpi(wfk0_path,wfq_path,dtfil,ngfft,ngfftf,dtset,cryst,ebands_k,ebands_kq,dvdb,ifc,&
95 0 : pawfgr,pawang,pawrad,pawtab,psps,mpi_enreg,comm)
96 :
97 : !Arguments ------------------------------------
98 : !scalars
99 : character(len=*),intent(in) :: wfk0_path, wfq_path
100 : integer,intent(in) :: comm
101 : type(datafiles_type),intent(in) :: dtfil
102 : type(dataset_type),intent(in) :: dtset
103 : type(crystal_t),intent(in) :: cryst
104 : type(ebands_t),intent(in) :: ebands_k, ebands_kq
105 : type(dvdb_t),intent(inout) :: dvdb
106 : type(pawang_type),intent(in) :: pawang
107 : type(pseudopotential_type),intent(in) :: psps
108 : type(pawfgr_type),intent(in) :: pawfgr
109 : type(ifc_type),intent(in) :: ifc
110 : type(mpi_type),intent(in) :: mpi_enreg
111 : !arrays
112 : integer,intent(in) :: ngfft(18),ngfftf(18)
113 : type(pawrad_type),intent(in) :: pawrad(psps%ntypat*psps%usepaw)
114 : type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
115 :
116 : !Local variables ------------------------------
117 : !scalars
118 : integer,parameter :: tim_getgh1c = 1,berryopt0 = 0, useylmgr1 = 0, master = 0
119 : integer :: my_rank,nproc,iomode,mband,mband_kq,my_minb,my_maxb,nsppol,nkpt,nkpt_kq,idir,ipert
120 : integer :: cplex,db_iqpt,natom,natom3,ipc,nspinor,onpw,imode
121 : integer :: ib1,ib2,ik,ikq,spin,istwf_k,istwf_kq,npw_k,npw_kq
122 : integer :: mpw,my_mpw,ierr,my_kstart,my_kstop,cnt
123 : integer :: n1,n2,n3,n4,n5,n6,nspden
124 : integer :: sij_opt,usecprj,usevnl,optlocal,optnl,opt_gvnlx1
125 : integer :: nfft,nfftf,mgfft,mgfftf,nkpg,nkpg1
126 : real(dp) :: cpu,wall,gflops
127 : real(dp) :: ecut,eshift,eig0nk,eig0mkq,dotr,doti
128 : real(dp) :: eta,f_nk,f_mkq,omega,wtk,gkk2,term1,term2
129 : logical :: i_am_master,gen_eigenpb
130 0 : type(wfd_t) :: wfd_k,wfd_kq
131 0 : type(gs_hamiltonian_type) :: gs_hamkq
132 0 : type(rf_hamiltonian_type) :: rf_hamkq
133 : character(len=500) :: msg
134 : !arrays
135 : integer :: g0_k(3), units(2)
136 0 : integer,allocatable :: kg_k(:,:),kg_kq(:,:),gtmp(:,:),nband(:,:),nband_kq(:,:),blkflg(:,:), wfd_istwfk(:)
137 0 : real(dp) :: kk(3),kq(3),qpt(3),phfrq(3*cryst%natom)
138 0 : real(dp) :: displ_cart(2,3,cryst%natom,3*cryst%natom),displ_red(2,3,cryst%natom,3*cryst%natom)
139 0 : real(dp) :: Pi_ph(3*cryst%natom)
140 0 : real(dp),allocatable :: grad_berry(:,:),kinpw_kq(:),kpg_kq(:,:),kpg_k(:,:),dkinpw(:)
141 0 : real(dp),allocatable :: ffnl_k(:,:,:,:),ffnl_kq(:,:,:,:),ph3d_k(:,:,:),ph3d_kq(:,:,:)
142 0 : real(dp),allocatable :: v1scf(:,:,:,:),gkk(:,:,:,:,:), gkk_m(:,:,:)
143 0 : real(dp),allocatable :: bras_kq(:,:,:),kets_k(:,:,:),h1kets_kq(:,:,:)
144 0 : real(dp),allocatable :: ph1d(:,:),vlocal(:,:,:,:),vlocal1(:,:,:,:,:)
145 0 : real(dp),allocatable :: ylm_kq(:,:),ylm_k(:,:),ylmgr_kq(:,:,:)
146 0 : real(dp),allocatable :: dummy_vtrial(:,:),gvnlx1(:,:)
147 0 : real(dp),allocatable :: gs1c(:,:)
148 0 : logical,allocatable :: bks_mask(:,:,:),bks_mask_kq(:,:,:),keep_ur(:,:,:),keep_ur_kq(:,:,:)
149 0 : type(pawcprj_type),allocatable :: cwaveprj0(:,:) !natom,nspinor*usecprj)
150 : !************************************************************************
151 :
152 0 : units = [std_out, ab_out]
153 0 : write(msg, '(3a)') ch10, "Computation of the real part of the phonon self-energy", ch10
154 0 : call wrtout(units, msg, do_flush=.True.)
155 :
156 0 : if (psps%usepaw == 1) then
157 0 : ABI_ERROR("PAW not implemented")
158 : ABI_UNUSED((/pawang%nsym, pawrad(1)%mesh_size/))
159 : end if
160 :
161 0 : my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
162 0 : i_am_master = (my_rank == master)
163 :
164 : ! Copy important dimensions
165 0 : natom = cryst%natom; natom3 = 3 * natom; nsppol = ebands_k%nsppol; nspinor = ebands_k%nspinor; nspden = dtset%nspden
166 0 : nkpt = ebands_k%nkpt
167 0 : mband = ebands_k%mband
168 0 : nkpt_kq = ebands_kq%nkpt
169 0 : mband_kq = ebands_kq%mband
170 0 : ecut = dtset%ecut
171 :
172 : ! GKA TODO: Make sure there is a single q-point present.
173 0 : qpt = dtset%qptn(:)
174 :
175 0 : nfftf = product(ngfftf(1:3)); mgfftf = maxval(ngfftf(1:3))
176 0 : nfft = product(ngfft(1:3)) ; mgfft = maxval(ngfft(1:3))
177 0 : n1=ngfft(1); n2=ngfft(2); n3=ngfft(3)
178 0 : n4=ngfft(4); n5=ngfft(5); n6=ngfft(6)
179 :
180 : ! Open the DVDB file
181 0 : call dvdb%open_read(ngfftf, xmpi_comm_self)
182 :
183 : ! Initialize the wave function descriptors.
184 : ! For the time being, no memory distribution, each node has the full set of states.
185 0 : my_minb = 1; my_maxb = mband
186 :
187 0 : ABI_MALLOC(nband, (nkpt, nsppol))
188 0 : ABI_MALLOC(bks_mask,(mband, nkpt, nsppol))
189 0 : ABI_MALLOC(keep_ur,(mband, nkpt ,nsppol))
190 0 : nband=mband; bks_mask=.False.; keep_ur=.False.
191 :
192 0 : ABI_MALLOC(nband_kq, (nkpt_kq, nsppol))
193 0 : ABI_MALLOC(bks_mask_kq,(mband_kq, nkpt_kq, nsppol))
194 0 : ABI_MALLOC(keep_ur_kq,(mband_kq, nkpt_kq ,nsppol))
195 0 : nband_kq=mband_kq; bks_mask_kq=.False.; keep_ur_kq=.False.
196 :
197 : ! Distribute the k-points over the processors
198 0 : call xmpi_split_work(nkpt,comm,my_kstart,my_kstop)
199 0 : do ik=1,nkpt
200 0 : if (.not. ((ik .ge. my_kstart) .and. (ik .le. my_kstop))) cycle
201 0 : kk = ebands_k%kptns(:,ik)
202 0 : kq = kk + qpt
203 0 : call findqg0(ikq,g0_k,kq,nkpt_kq,ebands_kq%kptns(:,:),(/1,1,1/)) ! Find the index of the k+q point
204 0 : bks_mask(:,ik,:) = .True.
205 0 : bks_mask_kq(:,ikq,:) = .True.
206 : end do
207 :
208 : ! Initialize the wavefunction descriptors
209 :
210 : ! Impose istwfk=1 for all k points. This is also done in respfn (see inkpts)
211 : ! wfd_read_wfk will handle a possible conversion if WFK contains istwfk /= 1.
212 0 : ABI_MALLOC(wfd_istwfk, (nkpt))
213 0 : wfd_istwfk = 1
214 :
215 : call wfd_k%init(cryst,pawtab,psps,keep_ur,mband,nband,nkpt,nsppol,bks_mask,&
216 : nspden,nspinor,ecut,dtset%ecutsm,dtset%dilatmx,wfd_istwfk,ebands_k%kptns,ngfft,&
217 0 : dtset%nloalg,dtset%prtvol,dtset%pawprtvol,comm)
218 0 : ABI_FREE(wfd_istwfk)
219 :
220 0 : call wfd_k%print([std_out], header="Wavefunctions on the k-points grid")
221 :
222 0 : ABI_MALLOC(wfd_istwfk, (nkpt_kq))
223 0 : wfd_istwfk = 1
224 :
225 : call wfd_kq%init(cryst,pawtab,psps,keep_ur_kq,mband_kq,nband_kq,nkpt_kq,nsppol,bks_mask_kq,&
226 : nspden,nspinor,ecut,dtset%ecutsm,dtset%dilatmx,wfd_istwfk,ebands_kq%kptns,ngfft,&
227 0 : dtset%nloalg,dtset%prtvol,dtset%pawprtvol,comm)
228 :
229 0 : ABI_FREE(wfd_istwfk)
230 :
231 0 : call wfd_kq%print([std_out], header="Wavefunctions on the q-shifted k-points grid")
232 :
233 0 : ABI_FREE(nband)
234 0 : ABI_FREE(bks_mask)
235 0 : ABI_FREE(keep_ur)
236 0 : ABI_FREE(nband_kq)
237 0 : ABI_FREE(bks_mask_kq)
238 0 : ABI_FREE(keep_ur_kq)
239 :
240 : ! Read wavefunctions on the k-points grid and q-shifted k-points grid.
241 0 : iomode = iomode_from_fname(wfk0_path)
242 0 : call wfd_k%read_wfk(wfk0_path,iomode)
243 : if (.False.) call wfd_k%test_ortho(cryst,pawtab,unit=std_out,mode_paral="PERS")
244 :
245 0 : iomode = iomode_from_fname(wfq_path)
246 0 : call wfd_kq%read_wfk(wfq_path,iomode)
247 : if (.False.) call wfd_kq%test_ortho(cryst,pawtab,unit=std_out,mode_paral="PERS")
248 :
249 : ! ph1d(2,3*(2*mgfft+1)*natom)=one-dimensional structure factor information on the coarse grid.
250 0 : ABI_MALLOC(ph1d, (2,3*(2*mgfft+1)*natom))
251 0 : call getph(cryst%atindx,natom,n1,n2,n3,ph1d,cryst%xred)
252 :
253 : ! Find the appropriate value of mpw
254 0 : mpw = 0; cnt=0
255 0 : do spin=1,nsppol
256 0 : do ik=1,nkpt
257 0 : cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle
258 0 : kk = ebands_k%kptns(:,ik)
259 0 : call get_kg(kk,1,ecut,cryst%gmet,onpw,gtmp)
260 0 : ABI_FREE(gtmp)
261 0 : mpw = max(mpw, onpw)
262 : end do
263 : end do
264 0 : cnt=0
265 0 : do spin=1,nsppol
266 0 : do ikq=1,nkpt_kq
267 0 : cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle
268 0 : kq = ebands_kq%kptns(:,ikq)
269 0 : call get_kg(kq,1,ecut,cryst%gmet,onpw,gtmp)
270 0 : ABI_FREE(gtmp)
271 0 : mpw = max(mpw, onpw)
272 : end do
273 : end do
274 0 : my_mpw = mpw; call xmpi_max(my_mpw, mpw, comm, ierr)
275 :
276 : ! Allow PW-arrays dimensioned with mpw
277 0 : ABI_MALLOC(kg_k, (3, mpw))
278 0 : ABI_MALLOC(kg_kq, (3, mpw))
279 :
280 : ! Spherical Harmonics for useylm==1.
281 : ! FIXME: These arrays should allocated with npw_k and npw_kq
282 0 : ABI_MALLOC(ylm_k,(mpw, psps%mpsang*psps%mpsang*psps%useylm))
283 0 : ABI_MALLOC(ylm_kq,(mpw, psps%mpsang*psps%mpsang*psps%useylm))
284 0 : ABI_MALLOC(ylmgr_kq,(mpw, 3, psps%mpsang*psps%mpsang*psps%useylm*useylmgr1))
285 :
286 : ! TODO FOR PAW
287 0 : usecprj = 0
288 0 : ABI_MALLOC(cwaveprj0, (natom, nspinor*usecprj))
289 :
290 : ! Prepare call to getgh1c
291 0 : usevnl = 0
292 0 : optlocal = 1 ! local part of H^(1) is computed in gh1c=<G|H^(1)|C>
293 0 : optnl = 2 ! non-local part of H^(1) is totally computed in gh1c=<G|H^(1)|C>
294 0 : opt_gvnlx1 = 0 ! gvnlx1 is output
295 0 : ABI_MALLOC(gvnlx1, (2,usevnl))
296 0 : ABI_MALLOC(grad_berry, (2,nspinor*(berryopt0/4)))
297 :
298 : ! This part is taken from dfpt_vtorho
299 : !==== Initialize most of the Hamiltonian (and derivative) ====
300 : !1) Allocate all arrays and initialize quantities that do not depend on k and spin.
301 : !2) Perform the setup needed for the non-local factors:
302 : !* Norm-conserving: Constant kleimann-Bylander energies are copied from psps to gs_hamk.
303 : !* PAW: Initialize the overlap coefficients and allocate the Dij coefficients.
304 :
305 : call gs_hamkq%init(psps,pawtab,nspinor,NSPPOL,nspden,natom,&
306 : dtset%typat,cryst%xred,nfft,mgfft,ngfft,cryst%rprimd,dtset%nloalg,&
307 : comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab,mpi_spintab=mpi_enreg%my_isppoltab,&
308 0 : usecprj=usecprj,ph1d=ph1d,nucdipmom=dtset%nucdipmom,gpu_option=dtset%gpu_option)
309 :
310 : ! Allocate vlocal. Note nvloc
311 : ! I set vlocal to huge to trigger possible bugs (DFPT routines should not access the data)
312 0 : ABI_MALLOC(vlocal,(n4,n5,n6,gs_hamkq%nvloc))
313 0 : vlocal = huge(one)
314 :
315 : ! Allocate work space arrays.
316 0 : ABI_MALLOC(blkflg, (natom3,natom3))
317 0 : ABI_CALLOC(dummy_vtrial, (nfftf,nspden))
318 :
319 0 : call cwtime(cpu,wall,gflops,"start")
320 :
321 : ! Find the index of the q-point in the DVDB.
322 0 : db_iqpt = dvdb%findq(qpt)
323 :
324 0 : if (db_iqpt /= -1) then
325 0 : if (dtset%prtvol > 0) call wrtout(std_out, sjoin("Found: ",ktoa(qpt)," in DVDB with index ",itoa(db_iqpt)))
326 : ! Read or reconstruct the dvscf potentials for all 3*natom perturbations.
327 : ! This call allocates v1scf(cplex, nfftf, nspden, 3*natom))
328 0 : call dvdb%readsym_allv1(db_iqpt, cplex, nfftf, ngfftf, v1scf, comm)
329 : else
330 0 : ABI_ERROR(sjoin("Could not find symmetric of q-point:", ktoa(qpt), "in DVDB"))
331 : end if
332 :
333 : ! Allocate vlocal1 with correct cplex. Note nvloc
334 0 : ABI_MALLOC_OR_DIE(vlocal1,(cplex*n4,n5,n6,gs_hamkq%nvloc,natom3), ierr)
335 :
336 : ! Allocate el-ph coupling matrix elements
337 0 : ABI_MALLOC(gkk, (2, mband_kq, mband, natom, 3))
338 0 : ABI_MALLOC(gkk_m, (2, mband_kq, mband))
339 :
340 : ! Compute displacement vectors and phonon frequencies
341 0 : call ifc%fourq(cryst, qpt, phfrq, displ_cart, out_displ_red=displ_red)
342 :
343 : ! Broadening parameter
344 0 : if (dtset%elph2_imagden .gt. tol12) then
345 0 : eta = dtset%elph2_imagden
346 : else
347 : eta = 0.0001_dp
348 : end if
349 :
350 : ! Kpoints weights (not using symmetries at the moment)
351 0 : wtk = 1.0 / nkpt
352 :
353 : ! Initialize phonon self-energy
354 0 : Pi_ph = zero
355 :
356 : ! Examine the symmetries of the q wavevector
357 : ! call littlegroup_q(cryst%nsym,qpt,symq,cryst%symrec,cryst%symafm,timerev_q,prtvol=dtset%prtvol)
358 :
359 : ! ----------------------------------------------------------------------------------------------- !
360 : ! Begin loop over states
361 : ! ----------------------------------------------------------------------------------------------- !
362 0 : do spin=1,nsppol
363 :
364 : ! Set up local potential vlocal1 with proper dimensioning, from vtrial1 taking into account the spin.
365 0 : do ipc=1,natom3
366 : call rf_transgrid_and_pack(spin,nspden,psps%usepaw,cplex,nfftf,nfft,ngfft,gs_hamkq%nvloc,&
367 0 : pawfgr,mpi_enreg,dummy_vtrial,v1scf(:,:,:,ipc),vlocal,vlocal1(:,:,:,:,ipc))
368 : end do
369 :
370 : ! Continue to initialize the Hamiltonian
371 0 : call gs_hamkq%load_spin(spin,vlocal=vlocal,with_nonlocal=.true.)
372 :
373 0 : do ik=1,nkpt
374 : ! Only do a subset a k-points
375 0 : if (.not. ((ik .ge. my_kstart) .and. (ik .le. my_kstop))) cycle
376 :
377 : ! Allocate workspace for wavefunctions. Make npw larger than expected.
378 0 : ABI_MALLOC(bras_kq, (2, mpw*nspinor, mband))
379 0 : ABI_MALLOC(kets_k, (2, mpw*nspinor, mband))
380 0 : ABI_MALLOC(h1kets_kq, (2, mpw*nspinor, mband))
381 :
382 0 : kk = ebands_k%kptns(:,ik)
383 0 : kq = kk + qpt
384 0 : call findqg0(ikq,g0_k,kq,nkpt_kq,ebands_kq%kptns(:,:),(/1,1,1/)) ! Find the index of the k+q point
385 :
386 : ! Copy u_k(G)
387 0 : istwf_k = wfd_k%istwfk(ik); npw_k = wfd_k%npwarr(ik)
388 0 : ABI_CHECK(mpw >= npw_k, "mpw < npw_k")
389 0 : kg_k(:,1:npw_k) = wfd_k%kdata(ik)%kg_k
390 0 : do ib2=1,mband
391 0 : call wfd_k%copy_cg(ib2, ik, spin, kets_k(1,1,ib2))
392 : end do
393 :
394 : ! Copy u_kq(G)
395 0 : istwf_kq = wfd_kq%istwfk(ikq); npw_kq = wfd_kq%npwarr(ikq)
396 0 : ABI_CHECK(mpw >= npw_kq, "mpw < npw_kq")
397 0 : kg_kq(:,1:npw_kq) = wfd_kq%kdata(ikq)%kg_k
398 0 : do ib1=1,mband_kq
399 0 : call wfd_kq%copy_cg(ib1, ikq, spin, bras_kq(1,1,ib1))
400 : end do
401 :
402 : ! if PAW, one has to solve a generalized eigenproblem
403 : ! BE careful here because I will need sij_opt==-1
404 0 : gen_eigenpb = (psps%usepaw==1)
405 0 : sij_opt = 0; if (gen_eigenpb) sij_opt = 1
406 0 : ABI_MALLOC(gs1c, (2,npw_kq*nspinor*((sij_opt+1)/2)))
407 :
408 0 : gkk = zero
409 :
410 : ! Loop over all 3*natom perturbations.
411 0 : do ipc=1,natom3
412 0 : idir = mod(ipc-1, 3) + 1
413 0 : ipert = (ipc - idir) / 3 + 1
414 :
415 : !write(msg, '(a,2i4)') "Treating ipert, idir = ", ipert, idir
416 : !call wrtout(std_out, msg, do_flush=.True.)
417 :
418 : ! Prepare application of the NL part.
419 0 : call rf_hamkq%init(cplex,gs_hamkq,ipert,has_e1kbsc=.true.)
420 0 : call rf_hamkq%load_spin(spin,vlocal1=vlocal1(:,:,:,:,ipc),with_nonlocal=.true.)
421 :
422 : ! This call is not optimal because there are quantities in out that do not depend on idir,ipert
423 : call getgh1c_setup(gs_hamkq,rf_hamkq,dtset,psps,kk,kq,idir,ipert,& ! In
424 : cryst%natom,cryst%rmet,cryst%gprimd,cryst%gmet,istwf_k,& ! In
425 : npw_k,npw_kq,useylmgr1,kg_k,ylm_k,kg_kq,ylm_kq,ylmgr_kq,& ! In
426 0 : dkinpw,nkpg,nkpg1,kpg_k,kpg_kq,kinpw_kq,ffnl_k,ffnl_kq,ph3d_k,ph3d_kq) ! Out
427 :
428 : ! Calculate dvscf * psi_k, results stored in h1kets_kq on the k+q sphere.
429 : ! Compute H(1) applied to GS wavefunction Psi(0)
430 0 : do ib2=1,mband
431 0 : eig0nk = ebands_k%eig(ib2,ik,spin)
432 : ! Use scissor shift on 0-order eigenvalue
433 0 : eshift = eig0nk - dtset%dfpt_sciss
434 :
435 : call getgh1c(berryopt0,kets_k(:,:,ib2),cwaveprj0,h1kets_kq(:,:,ib2),&
436 : & grad_berry,gs1c,gs_hamkq,gvnlx1,idir,ipert,(/eshift/),mpi_enreg,1,optlocal,&
437 0 : & optnl,opt_gvnlx1,rf_hamkq,sij_opt,tim_getgh1c,usevnl)
438 : end do
439 :
440 0 : ABI_FREE(kinpw_kq)
441 0 : ABI_FREE(kpg_kq)
442 0 : ABI_FREE(kpg_k)
443 0 : ABI_FREE(dkinpw)
444 0 : ABI_FREE(ffnl_k)
445 0 : ABI_FREE(ffnl_kq)
446 0 : ABI_FREE(ph3d_k)
447 0 : ABI_SFREE(ph3d_kq)
448 0 : ABI_SFREE(gs1c)
449 :
450 : ! Calculate elphmat(j,i) = <psi_{k+q,j}|dvscf_q*psi_{k,i}> for this perturbation.
451 : !The array eig1_k contains:
452 : !
453 : ! <u_(band,k+q)^(0)|H_(k+q,k)^(1)|u_(band,k)^(0)> (NC psps)
454 : ! <u_(band,k+q)^(0)|H_(k+q,k)^(1)-(eig0_k+eig0_k+q)/2.S^(1)|u_(band,k)^(0)> (PAW)
455 0 : do ib2=1,mband
456 0 : do ib1=1,mband_kq
457 : call dotprod_g(dotr,doti,istwf_kq,npw_kq*nspinor,2,bras_kq(1,1,ib1),h1kets_kq(1,1,ib2),&
458 0 : mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
459 0 : gkk(:,ib1,ib2,ipert,idir) = [dotr, doti]
460 : end do
461 : end do
462 :
463 : end do ! ipc
464 :
465 : ! Loop over 3*natom phonon branches.
466 0 : do imode=1,natom3
467 0 : omega = phfrq(imode)
468 : ! Do not compute Pi for negative or too small frequencies
469 0 : if (omega .lt. tol6) cycle
470 0 : gkk_m = zero
471 :
472 : ! Transform the gkk from atom,cart basis to mode basis
473 0 : do idir=1,3
474 0 : do ipert=1,natom
475 : gkk_m(1,:,:) = gkk_m(1,:,:) &
476 : + gkk(1,:,:,ipert,idir) * displ_red(1,idir,ipert,imode) &
477 0 : - gkk(2,:,:,ipert,idir) * displ_red(2,idir,ipert,imode)
478 : gkk_m(2,:,:) = gkk_m(2,:,:) &
479 : + gkk(1,:,:,ipert,idir) * displ_red(2,idir,ipert,imode) &
480 0 : + gkk(2,:,:,ipert,idir) * displ_red(1,idir,ipert,imode)
481 : end do
482 : end do
483 :
484 0 : gkk_m = gkk_m / sqrt(two * omega)
485 :
486 : ! sum contribution to phonon self-energy
487 0 : do ib2=1,mband
488 0 : do ib1=1,mband_kq
489 0 : f_nk = ebands_k%occ(ib2,ik,spin)
490 0 : f_mkq = ebands_kq%occ(ib1,ikq,spin)
491 0 : if (abs(f_mkq - f_nk) .le. tol12) cycle
492 :
493 0 : eig0nk = ebands_k%eig(ib2,ik,spin)
494 0 : eig0mkq = ebands_kq%eig(ib1,ikq,spin)
495 :
496 0 : gkk2 = gkk_m(1,ib1,ib2) ** 2 + gkk_m(2,ib1,ib2) ** 2
497 :
498 0 : term1 = (f_mkq - f_nk) * (eig0mkq - eig0nk - omega) / ((eig0mkq - eig0nk - omega) ** 2 + eta ** 2)
499 0 : term2 = (f_mkq - f_nk) * (eig0mkq - eig0nk ) / ((eig0mkq - eig0nk ) ** 2 + eta ** 2)
500 :
501 0 : Pi_ph(imode) = Pi_ph(imode) + wtk * gkk2 * (term1 - term2)
502 : end do
503 : end do
504 :
505 : end do ! imode
506 :
507 0 : ABI_FREE(bras_kq)
508 0 : ABI_FREE(kets_k)
509 0 : ABI_FREE(h1kets_kq)
510 : end do ! ikfs
511 :
512 0 : call rf_hamkq%free()
513 : end do ! spin
514 :
515 : ! Gather the k-points computed by all processes
516 0 : call xmpi_sum_master(Pi_ph,master,comm,ierr)
517 :
518 : ! Output the results
519 0 : if (i_am_master) then
520 0 : call out_phpi(ab_out, Pi_ph, phfrq, qpt, natom3)
521 0 : call out_phpi(std_out, Pi_ph, phfrq, qpt, natom3)
522 : end if
523 :
524 0 : if (i_am_master) call out_phpi_nc(dtfil, cryst, Pi_ph, phfrq, qpt, natom3)
525 :
526 : ! Free memory
527 0 : call cwtime(cpu,wall,gflops,"stop")
528 :
529 0 : write(msg, '(3a)') "Computation of the real part of the phonon self-energy completed", ch10, &
530 0 : "--------------------------------------------------------------------------------"
531 0 : call wrtout(units, msg, do_flush=.True.)
532 :
533 : ! Free memory
534 0 : ABI_FREE(gkk)
535 0 : ABI_FREE(gkk_m)
536 0 : ABI_FREE(v1scf)
537 0 : ABI_FREE(vlocal1)
538 0 : ABI_FREE(gvnlx1)
539 0 : ABI_FREE(grad_berry)
540 0 : ABI_FREE(dummy_vtrial)
541 0 : ABI_FREE(ph1d)
542 0 : ABI_FREE(vlocal)
543 0 : ABI_FREE(kg_k)
544 0 : ABI_FREE(kg_kq)
545 0 : ABI_FREE(ylm_k)
546 0 : ABI_FREE(ylm_kq)
547 0 : ABI_FREE(ylmgr_kq)
548 0 : ABI_FREE(blkflg)
549 :
550 0 : call gs_hamkq%free()
551 0 : call wfd_k%free()
552 0 : call wfd_kq%free()
553 :
554 0 : call pawcprj_free(cwaveprj0)
555 0 : ABI_FREE(cwaveprj0)
556 :
557 0 : end subroutine eph_phpi
558 : !!***
559 :
560 : !----------------------------------------------------------------------
561 :
562 : !!****f* m_phpi/out_phpi
563 : !! NAME
564 : !! out_phpi
565 : !!
566 : !! FUNCTION
567 : !! Output the phonon self-energy.
568 : !!
569 : !! INPUTS
570 : !!
571 : !! OUTPUT
572 : !!
573 : !! NOTES
574 : !!
575 : !! SOURCE
576 :
577 0 : subroutine out_phpi(iout, Pi_ph, phfrq, qpt, natom3)
578 :
579 : !Arguments ------------------------------------
580 : !scalars
581 : integer,intent(in) :: iout
582 : integer,intent(in) :: natom3
583 : !arrays
584 : real(dp),intent(in) :: Pi_ph(natom3),phfrq(natom3),qpt(3)
585 :
586 : !Local variables ------------------------------
587 : !scalars
588 : integer :: imode
589 :
590 0 : write(iout,'(a)')' '
591 : !write(iout,'(a)')' ----------------------------------------'
592 : !write(iout,'(a)')' '
593 0 : write(iout,'(a)')' Phonon self-energy (Hartree)'
594 0 : write(iout,'(a)')' '
595 0 : write(iout,'(a,3f14.8)')' qpt =',qpt
596 0 : write(iout,'(a)')' '
597 0 : write(iout,'(1x,a,10x,a)')'omega','Pi(omega)'
598 :
599 0 : do imode=1,natom3
600 0 : write(iout,'(1x,f12.8,1x,es14.6)') phfrq(imode), Pi_ph(imode)
601 : end do
602 :
603 0 : write(iout,'(a)')' '
604 : !write(iout,'(a)')' ----------------------------------------'
605 :
606 0 : end subroutine out_phpi
607 : !!***
608 :
609 : !----------------------------------------------------------------------
610 :
611 : !!****f* m_phpi/out_phpi_nc
612 : !! NAME
613 : !! out_phpi_nc
614 : !!
615 : !! FUNCTION
616 : !! Output the phonon self-energy in netCDF format.
617 : !!
618 : !! INPUTS
619 : !!
620 : !! OUTPUT
621 : !!
622 : !! NOTES
623 : !!
624 : !! SOURCE
625 :
626 0 : subroutine out_phpi_nc(dtfil, cryst, Pi_ph, phfrq, qpt, natom3)
627 :
628 : !Arguments ------------------------------------
629 : !scalars
630 : integer,intent(in) :: natom3
631 : type(datafiles_type), intent(in) :: dtfil
632 : type(crystal_t),intent(in) :: cryst
633 : !arrays
634 : real(dp),intent(in) :: Pi_ph(natom3),phfrq(natom3),qpt(3)
635 :
636 : !Local variables ------------------------------
637 : !scalars
638 : integer :: natom,one_dim,cplex,cart_dir
639 : integer :: ncid, ncerr
640 : character(len=fnlen) :: fname
641 :
642 : ! Initialize NetCDF file.
643 0 : fname = strcat(dtfil%filnam_ds(4),"_Pi.nc")
644 0 : NCF_CHECK(nctk_open_create(ncid, fname, xmpi_comm_self))
645 :
646 : ! Write information of the crystal
647 0 : NCF_CHECK(cryst%ncwrite(ncid))
648 :
649 : ! Write the dimensions specified by ETSF
650 0 : one_dim = 1
651 0 : cplex = 2
652 0 : cart_dir = 3
653 :
654 0 : natom = natom3 / 3
655 :
656 : ncerr = nctk_def_dims(ncid, [&
657 : nctkdim_t('current_one_dim', one_dim), &
658 : nctkdim_t('number_of_atoms', natom), &
659 : nctkdim_t('number_of_cartesian_directions', cart_dir), &
660 : nctkdim_t('number_of_perturbations', natom3), &
661 0 : nctkdim_t('cplex',cplex)], defmode=.True.)
662 0 : NCF_CHECK(ncerr)
663 :
664 : ! Create the arrays
665 : ncerr = nctk_def_arrays(ncid, [&
666 : nctkarr_t('q_point_reduced_coord', "dp", 'number_of_cartesian_directions'),&
667 : nctkarr_t('phonon_frequencies', "dp", 'number_of_perturbations'), &
668 0 : nctkarr_t('phonon_self_energy_realpart', "dp", 'number_of_perturbations')])
669 0 : NCF_CHECK(ncerr)
670 :
671 0 : NCF_CHECK(nctk_set_atomic_units(ncid, 'phonon_frequencies'))
672 0 : NCF_CHECK(nctk_set_atomic_units(ncid, 'phonon_self_energy_realpart'))
673 :
674 : ! Write data
675 0 : NCF_CHECK(nctk_set_datamode(ncid))
676 0 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'q_point_reduced_coord'), qpt))
677 0 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'phonon_frequencies'), phfrq))
678 0 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'phonon_self_energy_realpart'), Pi_ph))
679 :
680 : ! Close file
681 0 : NCF_CHECK(nf90_close(ncid))
682 :
683 0 : end subroutine out_phpi_nc
684 : !!***
685 :
686 : !----------------------------------------------------------------------
687 :
688 : end module m_phpi
689 : !!***
|