Line data Source code
1 : !!****m* ABINIT/m_gkk
2 : !! NAME
3 : !!
4 : !! FUNCTION
5 : !! Tools for the computation of electron-phonon coupling matrix elements (gkk)
6 : !!
7 : !! COPYRIGHT
8 : !! Copyright (C) 2008-2026 ABINIT group (GKA, MG)
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_gkk
22 :
23 : use defs_basis
24 : use m_abicore
25 : use m_xmpi
26 : use m_errors
27 : use m_dtset
28 : use m_ifc
29 : use m_ebands
30 : use m_ddb
31 : use m_dvdb
32 : use m_fft
33 : use m_hamiltonian
34 : use m_pawcprj
35 : use m_wfk
36 : use m_nctk
37 : use m_dtfil
38 : use netcdf
39 :
40 : use defs_abitypes, only : MPI_type
41 : use m_time, only : cwtime, sec2str
42 : use m_io_tools, only : iomode_from_fname
43 : use m_fstrings, only : itoa, sjoin, ktoa, ltoa, strcat
44 : use m_symtk, only : littlegroup_q
45 : use m_fftcore, only : get_kg
46 : use defs_datatypes, only : pseudopotential_type
47 : use m_crystal, only : crystal_t
48 : use m_bz_mesh, only : findqg0
49 : use m_cgtools, only : dotprod_g
50 : use m_kg, only : getph
51 : use m_pawang, only : pawang_type
52 : use m_pawrad, only : pawrad_type
53 : use m_pawtab, only : pawtab_type
54 : use m_pawfgr, only : pawfgr_type
55 : use m_eig2d, only : gkk_t, gkk_init, gkk_ncwrite, gkk_free
56 : use m_wfd, only : wfd_t
57 : use m_getgh1c, only : getgh1c, rf_transgrid_and_pack, getgh1c_setup
58 : use m_ephtk, only : ephtk_v1atm_to_vqnu
59 :
60 : implicit none
61 :
62 : private
63 : !!***
64 :
65 : public :: eph_gkk
66 : public :: ncwrite_v1qnu ! Compute \delta V_{q,nu)(r) and dump results to netcdf file.
67 :
68 : contains !===========================================================================
69 : !!***
70 :
71 : !!****f* m_gkk/eph_gkk
72 : !! NAME
73 : !! eph_gkk
74 : !!
75 : !! FUNCTION
76 : !! Compute electron-phonon coupling matrix elements.
77 : !!
78 : !! INPUTS
79 : !! wk0_path=String with the path to the GS unperturbed WFK file.
80 : !! ngfft(18),ngfftf(18)=Coarse and Fine FFT meshes.
81 : !! dtset<dataset_type>=All input variables for this dataset.
82 : !! ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
83 : !! dvdb<dbdb_type>=Database with the DFPT SCF potentials.
84 : !! ifc<ifc_type>=interatomic force constants and corresponding real space grid info.
85 : !! pawfgr <type(pawfgr_type)>=fine grid parameters and related data
86 : !! pawang<pawang_type)>=PAW angular mesh and related data.
87 : !! pawrad(ntypat*usepaw)<pawrad_type>=Paw radial mesh and related data.
88 : !! pawtab(ntypat*usepaw)<pawtab_type>=Paw tabulated starting data.
89 : !! psps<pseudopotential_type>=Variables related to pseudopotentials.
90 : !! comm=MPI communicator.
91 : !!
92 : !! OUTPUT
93 : !!
94 : !! SOURCE
95 :
96 2 : subroutine eph_gkk(wfk0_path,wfq_path,dtfil,ngfft,ngfftf,dtset,cryst,ebands_k,ebands_kq,dvdb,ifc,&
97 2 : pawfgr,pawang,pawrad,pawtab,psps,mpi_enreg,comm)
98 :
99 : !Arguments ------------------------------------
100 : !scalars
101 : character(len=*),intent(in) :: wfk0_path, wfq_path
102 : integer,intent(in) :: comm
103 : type(datafiles_type),intent(in) :: dtfil
104 : type(dataset_type),intent(in) :: dtset
105 : type(crystal_t),intent(in) :: cryst
106 : type(ebands_t),intent(in) :: ebands_k, ebands_kq
107 : type(dvdb_t),target,intent(inout) :: dvdb
108 : type(pawang_type),intent(in) :: pawang
109 : type(pseudopotential_type),intent(in) :: psps
110 : type(pawfgr_type),intent(in) :: pawfgr
111 : type(ifc_type),intent(in) :: ifc
112 : type(mpi_type),intent(inout) :: mpi_enreg
113 : !arrays
114 : integer,intent(in) :: ngfft(18),ngfftf(18)
115 : type(pawrad_type),intent(in) :: pawrad(psps%ntypat*psps%usepaw)
116 : type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
117 :
118 : !Local variables ------------------------------
119 : !scalars
120 : integer,parameter :: tim_getgh1c=1, berryopt0=0, useylmgr1=0, master=0, qptopt1 = 1
121 : integer :: my_rank,nproc,mband,mband_kq,my_minb,my_maxb,nsppol,nkpt,nkpt_kq,idir,ipert
122 : integer :: cplex,db_iqpt,natom,natom3,ipc,nspinor
123 : integer :: ib1,ib2,band,ik,ikq,timerev_q
124 : integer :: spin,istwf_k,istwf_kq,npw_k,npw_kq, comm_rpt
125 : integer :: mpw,mpw_k,mpw_kq,ierr,my_kstart,my_kstop,ncid
126 : integer :: n1,n2,n3,n4,n5,n6,nspden,ncerr
127 : integer :: sij_opt,usecprj,usevnl,optlocal,optnl,opt_gvnlx1
128 : integer :: nfft,nfftf,mgfft,mgfftf,nkpg,nkpg1, interpolated
129 : real(dp) :: cpu,wall,gflops,ecut,eshift,eig0nk,dotr,doti
130 : logical :: i_am_master, gen_eigenpb
131 2 : type(wfd_t) :: wfd_k, wfd_kq
132 2 : type(gs_hamiltonian_type) :: gs_hamkq
133 2 : type(rf_hamiltonian_type) :: rf_hamkq
134 2 : type(gkk_t) :: gkk2d
135 : character(len=500) :: msg, what
136 : character(len=fnlen) :: fname, gkkfilnam
137 : !arrays
138 4 : integer :: g0_k(3),symq(4,2,cryst%nsym), units(2)
139 2 : integer,allocatable :: kg_k(:,:),kg_kq(:,:),nband(:,:),nband_kq(:,:),wfd_istwfk(:)
140 : real(dp) :: ylmgr_kq_dum(1,1,1) ! ylmgr_k_dum(1,1,1),
141 4 : real(dp) :: kk(3),kq(3),qpt(3),phfrq(3*cryst%natom),dvdb_qdamp(1)
142 2 : real(dp),allocatable :: displ_cart(:,:,:),displ_red(:,:,:), eigens_kq(:,:,:)
143 2 : real(dp),allocatable :: grad_berry(:,:),kinpw_kq(:),kpg_kq(:,:),kpg_k(:,:),dkinpw(:)
144 2 : real(dp),allocatable :: ffnl_k(:,:,:,:),ffnl_kq(:,:,:,:),ph3d_k(:,:,:),ph3d_kq(:,:,:)
145 2 : real(dp),allocatable :: v1scf(:,:,:,:),gkk(:,:,:,:,:), bras(:,:,:),kets(:,:,:),h1_kets(:,:,:)
146 2 : real(dp),allocatable :: ph1d(:,:),vlocal(:,:,:,:),vlocal1(:,:,:,:,:), ylm_kq(:,:),ylm_k(:,:)
147 2 : real(dp),allocatable :: dummy_vtrial(:,:),gvnlx1(:,:), gs1c(:,:), gkq_atm(:,:,:,:)
148 2 : logical,allocatable :: bks_mask(:,:,:),bks_mask_kq(:,:,:),keep_ur(:,:,:),keep_ur_kq(:,:,:)
149 2 : type(pawcprj_type),allocatable :: cwaveprj0(:,:) !natom,nspinor*usecprj)
150 : !************************************************************************
151 :
152 6 : units = [std_out, ab_out]
153 :
154 2 : what = "(GKK files)"; if (dtset%eph_task == -2) what = "GKQ file"
155 2 : write(msg, '(3a)') " Computation of electron-phonon coupling matrix elements ", trim(what), ch10
156 2 : call wrtout(units, msg, do_flush=.True.)
157 :
158 2 : if (psps%usepaw == 1) then
159 0 : ABI_ERROR("PAW not implemented")
160 : ABI_UNUSED((/pawang%nsym, pawrad(1)%mesh_size/))
161 : end if
162 :
163 2 : my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm); i_am_master = my_rank == master
164 :
165 : ! Copy important dimensions
166 2 : natom = cryst%natom; natom3 = 3 * natom; nsppol = ebands_k%nsppol; nspinor = ebands_k%nspinor; nspden = dtset%nspden
167 2 : nkpt = ebands_k%nkpt; mband = ebands_k%mband; nkpt_kq = ebands_kq%nkpt; mband_kq = ebands_kq%mband
168 2 : ecut = dtset%ecut
169 : !write(std_out, *)"ebands dims (b, k, s): ", ebands_k%mband, ebands_k%nkpt, ebands_k%nsppol
170 : !write(std_out, *)"ebands_kq dims (b, k, s): ", ebands_kq%mband, ebands_kq%nkpt, ebands_kq%nsppol
171 :
172 8 : qpt = dtset%qptn(:)
173 :
174 8 : nfftf = product(ngfftf(1:3)); mgfftf = maxval(ngfftf(1:3))
175 14 : nfft = product(ngfft(1:3)) ; mgfft = maxval(ngfft(1:3))
176 2 : n1=ngfft(1); n2=ngfft(2); n3=ngfft(3)
177 2 : n4=ngfft(4); n5=ngfft(5); n6=ngfft(6)
178 :
179 : ! Open the DVDB file
180 2 : call dvdb%open_read(ngfftf, xmpi_comm_self)
181 :
182 : ! Initialize the wave function descriptors.
183 : ! For the time being, no memory distribution, each node has the full set of states.
184 2 : my_minb = 1; my_maxb = mband
185 :
186 8 : ABI_MALLOC(nband, (nkpt, nsppol))
187 10 : ABI_MALLOC(bks_mask,(mband, nkpt, nsppol))
188 8 : ABI_MALLOC(keep_ur,(mband, nkpt ,nsppol))
189 216 : nband=mband; bks_mask=.False.; keep_ur=.False.
190 :
191 8 : ABI_MALLOC(nband_kq, (nkpt_kq, nsppol))
192 10 : ABI_MALLOC(bks_mask_kq,(mband_kq, nkpt_kq, nsppol))
193 8 : ABI_MALLOC(keep_ur_kq,(mband_kq, nkpt_kq ,nsppol))
194 216 : nband_kq=mband_kq; bks_mask_kq=.False.; keep_ur_kq=.False.
195 :
196 : ! Distribute the k-points over the processors
197 2 : call xmpi_split_work(nkpt,comm,my_kstart,my_kstop)
198 18 : do ik=1,nkpt
199 16 : if (.not. (ik >= my_kstart .and. ik <= my_kstop)) cycle
200 64 : kk = ebands_k%kptns(:,ik)
201 64 : kq = kk + qpt
202 : ! Find the index of the k+q point
203 16 : call findqg0(ikq,g0_k,kq,nkpt_kq,ebands_kq%kptns(:,:), [1,1,1])
204 112 : bks_mask(:,ik,:) = .True.
205 114 : bks_mask_kq(:,ikq,:) = .True.
206 : end do
207 :
208 : ! Impose istwfk=1 for all k points. This is also done in respfn (see inkpts)
209 : ! wfd_read_wfk will handle a possible conversion if WFK contains istwfk /= 1.
210 6 : ABI_MALLOC(wfd_istwfk, (nkpt))
211 18 : wfd_istwfk = 1
212 :
213 : ! Initialize the wavefunction descriptors
214 : call wfd_k%init(cryst,pawtab,psps,keep_ur,mband,nband,nkpt,nsppol,bks_mask,&
215 : nspden,nspinor,ecut,dtset%ecutsm,dtset%dilatmx,wfd_istwfk,ebands_k%kptns,ngfft,&
216 2 : dtset%nloalg,dtset%prtvol,dtset%pawprtvol,comm)
217 2 : ABI_FREE(wfd_istwfk)
218 :
219 4 : call wfd_k%print([std_out], header="Wavefunctions on the k-points grid")
220 :
221 6 : ABI_MALLOC(wfd_istwfk, (nkpt_kq))
222 18 : wfd_istwfk = 1
223 :
224 : call wfd_kq%init(cryst,pawtab,psps,keep_ur_kq,mband_kq,nband_kq,nkpt_kq,nsppol,bks_mask_kq,&
225 : nspden,nspinor,ecut,dtset%ecutsm,dtset%dilatmx,wfd_istwfk,ebands_kq%kptns,ngfft,&
226 2 : dtset%nloalg,dtset%prtvol,dtset%pawprtvol,comm)
227 2 : ABI_FREE(wfd_istwfk)
228 :
229 4 : call wfd_kq%print([std_out], header="Wavefunctions on the q-shifted k-points grid")
230 :
231 2 : ABI_FREE(nband)
232 2 : ABI_FREE(bks_mask)
233 2 : ABI_FREE(keep_ur)
234 2 : ABI_FREE(nband_kq)
235 2 : ABI_FREE(bks_mask_kq)
236 2 : ABI_FREE(keep_ur_kq)
237 :
238 : ! Read wavefunctions on the k-points grid and q-shifted k-points grid.
239 2 : call wfd_k%read_wfk(wfk0_path, iomode_from_fname(wfk0_path))
240 2 : call wfd_kq%read_wfk(wfq_path, iomode_from_fname(wfq_path))
241 :
242 : ! ph1d(2,3*(2*mgfft+1)*natom)=one-dimensional structure factor information on the coarse grid.
243 6 : ABI_MALLOC(ph1d, (2,3*(2*mgfft+1)*natom))
244 2 : call getph(cryst%atindx,natom,n1,n2,n3,ph1d,cryst%xred)
245 :
246 : ! Find the appropriate value of mpw
247 2 : call find_mpw(mpw_k, ebands_k%kptns(:,:), nsppol, nkpt, cryst%gmet,ecut,comm)
248 2 : call find_mpw(mpw_kq, ebands_kq%kptns(:,:), nsppol, nkpt_kq, cryst%gmet,ecut,comm)
249 2 : mpw = max(mpw_k, mpw_kq)
250 :
251 : ! Allow PW-arrays dimensioned with mpw
252 6 : ABI_MALLOC(kg_k, (3, mpw))
253 4 : ABI_MALLOC(kg_kq, (3, mpw))
254 :
255 : ! Spherical Harmonics for useylm==1.
256 : ! TODO: These arrays should be allocated with npw_k and npw_kq
257 8 : ABI_MALLOC(ylm_k,(mpw, psps%mpsang*psps%mpsang*psps%useylm))
258 6 : ABI_MALLOC(ylm_kq,(mpw, psps%mpsang*psps%mpsang*psps%useylm))
259 :
260 : ! TODO FOR PAW
261 2 : usecprj = 0
262 4 : ABI_MALLOC(cwaveprj0, (natom, nspinor*usecprj))
263 :
264 : ! Prepare call to getgh1c
265 2 : usevnl = 0
266 2 : optlocal = 1 ! local part of H^(1) is computed in gh1c=<G|H^(1)|C>
267 2 : optnl = 2 ! non-local part of H^(1) is totally computed in gh1c=<G|H^(1)|C>
268 2 : opt_gvnlx1 = 0 ! gvnlx1 is output
269 2 : ABI_MALLOC(gvnlx1, (2,usevnl))
270 2 : ABI_MALLOC(grad_berry, (2,nspinor*(berryopt0/4)))
271 :
272 : ! This part is taken from dfpt_vtorho
273 : !==== Initialize most of the Hamiltonian (and derivative) ====
274 : !1) Allocate all arrays and initialize quantities that do not depend on k and spin.
275 : !2) Perform the setup needed for the non-local factors:
276 : !* Norm-conserving: Constant kleimann-Bylander energies are copied from psps to gs_hamk.
277 : !* PAW: Initialize the overlap coefficients and allocate the Dij coefficients.
278 :
279 : call gs_hamkq%init(psps,pawtab,nspinor,nsppol,nspden,natom,&
280 : dtset%typat,cryst%xred,nfft,mgfft,ngfft,cryst%rprimd,dtset%nloalg,&
281 : usecprj=usecprj,ph1d=ph1d,nucdipmom=dtset%nucdipmom,gpu_option=dtset%gpu_option,&
282 2 : comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab,mpi_spintab=mpi_enreg%my_isppoltab)
283 :
284 : ! Allocate vlocal. Note nvloc
285 12 : ABI_MALLOC(vlocal,(n4,n5,n6,gs_hamkq%nvloc))
286 : ! Allocate work space arrays.
287 3466 : ABI_CALLOC(dummy_vtrial, (nfftf,nspden))
288 :
289 2 : call cwtime(cpu, wall, gflops, "start")
290 :
291 2 : interpolated = 0
292 2 : if (dtset%eph_use_ftinterp /= 0) then
293 0 : ABI_WARNING(sjoin("Enforcing FT interpolation for q-point", ktoa(qpt)))
294 0 : comm_rpt = xmpi_comm_self
295 0 : call dvdb%ftinterp_setup(dtset%ddb_ngqpt, qptopt1, 1, dtset%ddb_shiftq, nfftf, ngfftf, comm_rpt)
296 0 : cplex = 2
297 0 : ABI_MALLOC(v1scf, (cplex, nfftf, nspden, dvdb%my_npert))
298 0 : call dvdb%ftinterp_qpt(qpt, nfftf, ngfftf, v1scf, dvdb%comm_rpt)
299 0 : interpolated = 1
300 : else
301 : ! Find the index of the q-point in the DVDB.
302 2 : db_iqpt = dvdb%findq(qpt)
303 2 : if (db_iqpt /= -1) then
304 2 : if (dtset%prtvol > 0) call wrtout(std_out, sjoin("Found: ",ktoa(qpt)," in DVDB with index ",itoa(db_iqpt)))
305 : ! Read or reconstruct the dvscf potentials for all 3*natom perturbations.
306 : ! This call allocates v1scf(cplex, nfftf, nspden, 3*natom))
307 2 : call dvdb%readsym_allv1(db_iqpt, cplex, nfftf, ngfftf, v1scf, comm)
308 : else
309 0 : ABI_WARNING(sjoin("Cannot find q-point:", ktoa(qpt), "in DVDB file"))
310 : end if
311 : end if
312 :
313 : ! Examine the symmetries of the q wavevector
314 2 : call littlegroup_q(cryst%nsym,qpt,symq,cryst%symrec,cryst%symafm,timerev_q,prtvol=dtset%prtvol)
315 :
316 : ! Allocate vlocal1 with correct cplex. Note nvloc
317 14 : ABI_MALLOC_OR_DIE(vlocal1,(cplex*n4,n5,n6,gs_hamkq%nvloc,natom3), ierr)
318 :
319 10 : ABI_MALLOC(displ_cart, (2,3*cryst%natom,3*cryst%natom))
320 6 : ABI_MALLOC(displ_red, (2,3*cryst%natom,3*cryst%natom))
321 :
322 2 : if (dtset%eph_task == 2) then
323 : ! Write GKK files (1 file for perturbation)
324 5 : ABI_MALLOC(gkk, (2*mband*nsppol,nkpt,1,1,mband_kq))
325 :
326 1 : else if (dtset%eph_task == -2) then
327 : ! Write GKQ file with all perturbations. gkq are given in the atom representation.
328 : ! TODO: Assuming mband_kq == mband
329 5 : ABI_MALLOC(gkq_atm, (2, mband_kq, mband, nkpt))
330 1 : if (i_am_master) then
331 1 : call ifc%fourq(cryst, qpt, phfrq, displ_cart, out_displ_red=displ_red)
332 1 : fname = strcat(dtfil%filnam_ds(4), "_GKQ.nc")
333 1 : NCF_CHECK_MSG(nctk_open_create(ncid, fname, xmpi_comm_self), "Creating GKQ file")
334 1 : NCF_CHECK(cryst%ncwrite(ncid))
335 : ! Write bands on k mesh.
336 1 : NCF_CHECK(ebands_k%ncwrite(ncid))
337 2 : ncerr = nctk_def_dims(ncid, [nctkdim_t('number_of_phonon_modes', natom3)], defmode=.True.)
338 1 : NCF_CHECK(ncerr)
339 : ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: &
340 5 : "symdynmat", "symv1scf", "dvdb_add_lr", "interpolated"])
341 1 : NCF_CHECK(ncerr)
342 2 : NCF_CHECK(nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: "qdamp"]))
343 :
344 : ! Define EPH arrays
345 : ncerr = nctk_def_arrays(ncid, [ &
346 : nctkarr_t('qpoint', "dp" , 'number_of_reduced_dimensions'), &
347 : nctkarr_t('emacro_cart', "dp", 'number_of_cartesian_directions, number_of_cartesian_directions'), &
348 : nctkarr_t('becs_cart', "dp", "number_of_cartesian_directions, number_of_cartesian_directions, number_of_atoms"), &
349 : nctkarr_t("eigenvalues_kq", "dp", "max_number_of_states, number_of_kpoints, number_of_spins"), &
350 : nctkarr_t('phfreqs', "dp", 'number_of_phonon_modes'), &
351 : nctkarr_t('phdispl_cart', "dp", 'complex, number_of_phonon_modes, number_of_phonon_modes'), &
352 : nctkarr_t('phdispl_red', "dp", 'complex, number_of_phonon_modes, number_of_phonon_modes'), &
353 : nctkarr_t("gkq_representation", "char", "character_string_length"), &
354 : nctkarr_t('gkq', "dp", &
355 : 'complex, max_number_of_states, max_number_of_states, number_of_phonon_modes, number_of_kpoints, number_of_spins') &
356 10 : ])
357 1 : NCF_CHECK(ncerr)
358 : ! Write data.
359 1 : NCF_CHECK(nctk_set_datamode(ncid))
360 : ncerr = nctk_write_iscalars(ncid, [character(len=nctk_slen) :: &
361 : "symdynmat", "symv1scf", "dvdb_add_lr", "interpolated"], &
362 9 : [dtset%symdynmat, dtset%symv1scf, dtset%dvdb_add_lr, interpolated])
363 1 : NCF_CHECK(ncerr)
364 2 : dvdb_qdamp = dvdb%qdamp
365 2 : NCF_CHECK(nctk_write_dpscalars(ncid, [character(len=nctk_slen) :: "qdamp"], dvdb_qdamp))
366 1 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "qpoint"), qpt))
367 1 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "emacro_cart"), dvdb%dielt))
368 1 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "becs_cart"), dvdb%zeff))
369 5 : ABI_MALLOC(eigens_kq, (ebands_kq%mband, nkpt, nsppol))
370 9 : do ik=1,nkpt
371 32 : kk = ebands_k%kptns(:,ik)
372 32 : kq = kk + qpt
373 : ! Find the index of the k+q point
374 8 : call findqg0(ikq, g0_k, kq, nkpt_kq, ebands_kq%kptns, [1,1,1])
375 57 : eigens_kq(:, ik, :) = ebands_kq%eig(:, ikq, :)
376 : end do
377 1 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "eigenvalues_kq"), eigens_kq))
378 1 : ABI_FREE(eigens_kq)
379 1 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "phfreqs"), phfrq))
380 1 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'phdispl_cart'), displ_cart))
381 1 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'phdispl_red'), displ_red))
382 1 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "gkq_representation"), "atom"))
383 : end if ! master
384 :
385 : else
386 0 : ABI_ERROR(sjoin("Invalid value for eph_task:", itoa(dtset%eph_task)))
387 : end if
388 :
389 : ! Loop over all 3*natom perturbations.
390 8 : do ipc=1,natom3
391 6 : idir = mod(ipc-1, 3) + 1
392 6 : ipert = (ipc - idir) / 3 + 1
393 6 : write(msg, '(a,2(i0,1x))') " Treating ipert, idir = ", ipert, idir
394 6 : call wrtout(std_out, msg, do_flush=.True.)
395 1371 : if (dtset%eph_task == 2) gkk = zero
396 :
397 12 : do spin=1,nsppol
398 1950 : if (dtset%eph_task == -2) gkq_atm = zero
399 :
400 : ! Set up local potential vlocal1 with proper dimensioning, from vtrial1 taking into account the spin.
401 : call rf_transgrid_and_pack(spin,nspden,psps%usepaw,cplex,nfftf,nfft,ngfft,gs_hamkq%nvloc,&
402 6 : pawfgr,mpi_enreg,dummy_vtrial,v1scf(:,:,:,ipc),vlocal,vlocal1(:,:,:,:,ipc))
403 :
404 : ! Continue to initialize the Hamiltonian
405 6 : call gs_hamkq%load_spin(spin,vlocal=vlocal,with_nonlocal=.true.)
406 :
407 : ! Allocate workspace for wavefunctions. Make npw larger than expected.
408 24 : ABI_MALLOC(bras, (2, mpw*nspinor, mband))
409 18 : ABI_MALLOC(kets, (2, mpw*nspinor, mband))
410 18 : ABI_MALLOC(h1_kets, (2, mpw*nspinor, mband))
411 :
412 : ! GKA: This little block used to be right after the perturbation loop
413 : ! Prepare application of the NL part.
414 6 : call rf_hamkq%init(cplex,gs_hamkq,ipert,has_e1kbsc=.true.)
415 6 : call rf_hamkq%load_spin(spin,vlocal1=vlocal1(:,:,:,:,ipc),with_nonlocal=.true.)
416 :
417 54 : do ik=1,nkpt
418 : ! Only do a subset a k-points
419 48 : if (.not. (ik >= my_kstart .and. ik <= my_kstop)) cycle
420 :
421 192 : kk = ebands_k%kptns(:,ik)
422 192 : kq = kk + qpt
423 : ! Find the index of the k+q point
424 48 : call findqg0(ikq, g0_k, kq, nkpt_kq, ebands_kq%kptns, [1,1,1])
425 :
426 : ! Copy u_k(G)
427 48 : istwf_k = wfd_k%istwfk(ik); npw_k = wfd_k%npwarr(ik)
428 48 : ABI_CHECK(mpw >= npw_k, "mpw < npw_k")
429 14664 : kg_k(:,1:npw_k) = wfd_k%kdata(ik)%kg_k
430 288 : do ib2=1,mband
431 288 : call wfd_k%copy_cg(ib2, ik, spin, kets(1,1,ib2))
432 : end do
433 :
434 : ! Copy u_kq(G)
435 48 : istwf_kq = wfd_kq%istwfk(ikq); npw_kq = wfd_kq%npwarr(ikq)
436 48 : ABI_CHECK(mpw >= npw_kq, "mpw < npw_kq")
437 13968 : kg_kq(:,1:npw_kq) = wfd_kq%kdata(ikq)%kg_k
438 288 : do ib1=1,mband_kq
439 288 : call wfd_kq%copy_cg(ib1, ikq, spin, bras(1,1,ib1))
440 : end do
441 :
442 : ! if PAW, one has to solve a generalized eigenproblem
443 : ! Be careful here because I will need sij_opt==-1
444 48 : gen_eigenpb = (psps%usepaw==1)
445 48 : sij_opt = 0; if (gen_eigenpb) sij_opt = 1
446 144 : ABI_MALLOC(gs1c, (2,npw_kq*nspinor*((sij_opt+1)/2)))
447 :
448 : ! GKA: Previous loop on 3*natom perturbations used to start here
449 : ! This call is not optimal because there are quantities in out that do not depend on idir,ipert
450 : call getgh1c_setup(gs_hamkq,rf_hamkq,dtset,psps,kk,kq,idir,ipert,& ! In
451 : cryst%natom,cryst%rmet,cryst%gprimd,cryst%gmet,istwf_k,& ! In
452 : npw_k,npw_kq,useylmgr1,kg_k,ylm_k,kg_kq,ylm_kq,ylmgr_kq_dum,& ! In
453 48 : dkinpw,nkpg,nkpg1,kpg_k,kpg_kq,kinpw_kq,ffnl_k,ffnl_kq,ph3d_k,ph3d_kq) ! Out
454 :
455 : ! Calculate dvscf * psi_k, results stored in h1_kets on the k+q sphere.
456 : ! Compute H(1) applied to GS wavefunction Psi(0)
457 288 : do ib2=1,mband
458 240 : eig0nk = ebands_k%eig(ib2,ik,spin)
459 : ! Use scissor shift on 0-order eigenvalue
460 240 : eshift = eig0nk - dtset%dfpt_sciss
461 :
462 : call getgh1c(berryopt0,kets(:,:,ib2),cwaveprj0,h1_kets(:,:,ib2),&
463 : grad_berry,gs1c,gs_hamkq,gvnlx1,idir,ipert, [eshift], mpi_enreg,1,optlocal,&
464 528 : optnl,opt_gvnlx1,rf_hamkq,sij_opt,tim_getgh1c,usevnl)
465 : end do
466 :
467 48 : ABI_FREE(kinpw_kq)
468 48 : ABI_FREE(kpg_k)
469 48 : ABI_FREE(kpg_kq)
470 48 : ABI_FREE(dkinpw)
471 48 : ABI_FREE(ffnl_k)
472 48 : ABI_FREE(ffnl_kq)
473 48 : ABI_FREE(gs1c)
474 48 : ABI_FREE(ph3d_k)
475 48 : ABI_SFREE(ph3d_kq)
476 :
477 : ! Calculate elphmat(j,i) = <psi_{k+q,j}|dvscf_q*psi_{k,i}> for this perturbation.
478 : ! The array eig1_k contains:
479 : !
480 : ! <u_(band,k+q)^(0)|H_(k+q,k)^(1)|u_(band,k)^(0)> (NC psps)
481 : ! <u_(band,k+q)^(0)|H_(k+q,k)^(1)-(eig0_k+eig0_k+q)/2.S^(1)|u_(band,k)^(0)> (PAW)
482 294 : do ib2=1,mband
483 1488 : do ib1=1,mband_kq
484 : call dotprod_g(dotr,doti,istwf_kq,npw_kq*nspinor,2,bras(1,1,ib1),h1_kets(1,1,ib2),&
485 1200 : mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
486 1200 : band = 2*ib2-1 + (spin-1) * 2 * mband
487 1440 : if (dtset%eph_task == 2) then
488 600 : gkk(band,ik,1,1,ib1) = dotr
489 600 : gkk(band+1,ik,1,1,ib1) = doti
490 : else
491 1800 : gkq_atm(:, ib1, ib2, ik) = [dotr, doti]
492 : end if
493 : end do ! ib1
494 : end do ! ib2
495 :
496 : end do ! ikpt
497 :
498 6 : ABI_FREE(bras)
499 6 : ABI_FREE(kets)
500 6 : ABI_FREE(h1_kets)
501 6 : call rf_hamkq%free()
502 :
503 12 : if (dtset%eph_task == -2) then
504 : ! Gather the k-points computed by all processes
505 3 : call xmpi_sum_master(gkq_atm, master, comm, ierr)
506 3 : if (i_am_master) then
507 : ! Write the netCDF file.
508 : ncerr = nf90_put_var(ncid, nctk_idname(ncid, "gkq"), gkq_atm, &
509 39 : start=[1, 1, 1, ipc, 1, spin], count=[2, mband, mband, 1, nkpt, 1])
510 3 : NCF_CHECK(ncerr)
511 : end if
512 : end if
513 :
514 : end do ! spin
515 :
516 8 : if (dtset%eph_task == 2) then
517 : ! Gather the k-points computed by all processes
518 3 : call xmpi_sum_master(gkk,master,comm,ierr)
519 : ! Init a gkk_t object
520 3 : call gkk_init(gkk,gkk2d,mband,nsppol,nkpt,1,1)
521 : ! Write the netCDF file.
522 3 : call appdig(ipc,dtfil%fnameabo_gkk,gkkfilnam)
523 3 : fname = strcat(gkkfilnam, ".nc")
524 3 : if (i_am_master) then
525 3 : NCF_CHECK_MSG(nctk_open_create(ncid, fname, xmpi_comm_self), "Creating GKK file")
526 3 : NCF_CHECK(cryst%ncwrite(ncid))
527 3 : NCF_CHECK(ebands_k%ncwrite(ncid))
528 3 : call gkk_ncwrite(gkk2d, qpt, 1.0_dp, ncid)
529 3 : NCF_CHECK(nf90_close(ncid))
530 : end if
531 : ! Free memory
532 3 : call gkk_free(gkk2d)
533 : end if
534 : end do ! ipc (loop over 3*natom atomic perturbations)
535 :
536 2 : call cwtime(cpu, wall, gflops, "stop")
537 2 : write(msg, '(2a)') " Computation of gkq matrix elements with ", trim(what)
538 2 : call wrtout(units, msg, do_flush=.True.)
539 2 : call wrtout(std_out, sjoin("cpu-time:", sec2str(cpu), ",wall-time:", sec2str(wall)), do_flush=.True.)
540 :
541 2 : if (dtset%eph_task == -2 .and. i_am_master) then
542 1 : NCF_CHECK(nf90_close(ncid))
543 : end if
544 :
545 : ! ===========
546 : ! Free memory
547 : ! ===========
548 2 : ABI_SFREE(gkk)
549 2 : ABI_SFREE(gkq_atm)
550 2 : ABI_FREE(displ_cart)
551 2 : ABI_FREE(displ_red)
552 2 : ABI_FREE(v1scf)
553 2 : ABI_FREE(vlocal1)
554 2 : ABI_FREE(gvnlx1)
555 2 : ABI_FREE(grad_berry)
556 2 : ABI_FREE(dummy_vtrial)
557 2 : ABI_FREE(ph1d)
558 2 : ABI_FREE(vlocal)
559 2 : ABI_FREE(kg_k)
560 2 : ABI_FREE(kg_kq)
561 2 : ABI_FREE(ylm_k)
562 2 : ABI_FREE(ylm_kq)
563 2 : call pawcprj_free(cwaveprj0)
564 2 : ABI_FREE(cwaveprj0)
565 :
566 2 : call gs_hamkq%free(); call wfd_k%free(); call wfd_kq%free()
567 :
568 10 : end subroutine eph_gkk
569 : !!***
570 :
571 : !----------------------------------------------------------------------
572 :
573 : !!****f* m_gkk/ncwrite_v1qnu
574 : !! NAME
575 : !! ncwrite_v1qnu
576 : !!
577 : !! FUNCTION
578 : !! Compute \delta V_{q,nu)(r) and dump results to netcdf file.
579 : !! This routine should be called by a single processor.
580 : !!
581 : !! INPUT
582 : !! dvdb<dbdb_type>=Database with the DFPT SCF potentials.
583 : !! dtset<dataset_type>= Input variables.
584 : !! ifc<ifc_type>=interatomic force constants and corresponding real space grid info.
585 : !! out_ncpath=Name of the netcdf file.
586 : !!
587 : !! OUTPUT
588 : !! Only writing
589 : !!
590 : !! SOURCE
591 :
592 0 : subroutine ncwrite_v1qnu(dvdb, dtset, ifc, out_ncpath)
593 :
594 : use m_bz_mesh, only : kpath_t
595 :
596 : !Arguments ------------------------------------
597 : class(dvdb_t),intent(inout) :: dvdb
598 : type(dataset_type),target,intent(in) :: dtset
599 : type(ifc_type),intent(in) :: ifc
600 : character(len=*),intent(in) :: out_ncpath
601 :
602 : !Local variables-------------------------------
603 : !scalars
604 : integer,parameter :: master = 0, qptopt1 = 1
605 : integer :: db_iqpt, cplex, nfft, comm, ip, idir, ipert, my_rank, interpolated, comm_rpt, ncid, ncerr
606 : integer :: iq, nu, iatom, ii, jj, kk
607 : real(dp) :: inv_qepsq, qtau, phre, phim, rtmp
608 : logical :: with_lr_model
609 0 : type(kpath_t) :: qpath
610 : !arrays
611 : integer :: ngfft(18), units(2)
612 0 : real(dp) :: phfreqs(dvdb%natom3),qpt(3)
613 0 : real(dp) :: displ_cart(2,3, dvdb%cryst%natom, dvdb%natom3), displ_red(2,dvdb%natom3,dvdb%natom3)
614 0 : real(dp),allocatable :: v1scf(:,:,:,:), v1_qnu(:,:,:,:), v1lr_atm(:,:,:,:), v1lr_qnu(:,:,:,:)
615 0 : real(dp) :: bounds(3,6), qpt_red(3), qpt_cart(3), glr(3), values(dvdb%natom3)
616 :
617 : !************************************************************************
618 :
619 : ! +0.50000 +0.50000 +0.50000 # L
620 : ! +0.00000 +0.00000 +0.00000 # $\Gamma$
621 : ! +0.50000 +0.00000 +0.50000 # X
622 : ! +0.50000 +0.25000 +0.75000 # W
623 : ! +0.37500 +0.37500 +0.75000 # K
624 : ! +0.00000 +0.00000 +0.00000 # $\Gamma$
625 : ! +0.37500 +0.37500 +0.75000 # K
626 :
627 : ! +0.62500 +0.25000 +0.62500 # U
628 : ! +0.50000 +0.50000 +0.50000 # L
629 : ! +0.37500 +0.37500 +0.75000 # K
630 : ! +0.62500 +0.25000 +0.62500 # U
631 : ! +0.50000 +0.00000 +0.50000 # X
632 :
633 0 : bounds(:, 1) = tol3 * [+0.50000, +0.50000, +0.50000] ! # L
634 0 : bounds(:, 2) = tol3 * [+0.00000, +0.00000, +0.00000] ! # $\Gamma$
635 0 : bounds(:, 3) = tol3 * [+0.50000, +0.00000, +0.50000] ! # X
636 0 : bounds(:, 4) = tol3 * [+0.37500, +0.37500, +0.75000] ! # K
637 0 : bounds(:, 5) = tol3 * [+0.00000, +0.00000, +0.00000] ! # $\Gamma$
638 0 : bounds(:, 6) = tol3 * [+0.50000, +0.25000, +0.75000] ! # W
639 :
640 0 : call qpath%init(bounds, dvdb%cryst%gprimd, dtset%ndivsm)
641 :
642 0 : units = [std_out, ab_out]
643 :
644 0 : do iq=1,qpath%npts
645 0 : qpt_red = qpath%points(:, iq)
646 0 : qpt_cart = two_pi * matmul(dvdb%cryst%gprimd, qpt_red)
647 0 : inv_qepsq = one / dot_product(qpt_cart, matmul(ifc%dielt, qpt_cart))
648 0 : call ifc%fourq(dvdb%cryst, qpt_red, phfreqs, displ_cart)
649 0 : do nu=1, dvdb%natom3
650 0 : glr = zero
651 0 : do iatom=1, dvdb%cryst%natom
652 : ! Phase factor exp(-i (q+G) . tau)
653 0 : qtau = - two_pi * dot_product(qpt_red, dvdb%cryst%xred(:,iatom))
654 0 : phre = cos(qtau); phim = sin(qtau)
655 0 : do jj=1,3
656 0 : do ii=1,3
657 0 : do kk=1,3
658 0 : rtmp = dvdb%qstar(ii, jj, kk, iatom) * qpt_cart(ii) * qpt_cart(jj)
659 0 : glr(1) = glr(1) + rtmp * (displ_cart(1, kk, iatom, nu) * phre - displ_cart(2, kk, iatom, nu) * phim)
660 0 : glr(2) = glr(2) + rtmp * (displ_cart(2, kk, iatom, nu) * phre + displ_cart(1, kk, iatom, nu) * phre)
661 : end do
662 : end do
663 : end do
664 : end do
665 0 : glr = half * (glr / inv_qepsq) * (four_pi / dvdb%cryst%ucvol)
666 0 : values(nu) = (glr(1) ** 2 + glr(2) ** 2) / (two * phfreqs(nu))
667 : end do ! nu
668 0 : write(std_out, "(i0, 4(f9.6), /, (es18.6, 1x))") iq, qpt_red, phfreqs(nu), (values(nu), nu=1, 3*dvdb%natom)
669 : end do ! iqpt
670 :
671 0 : call qpath%free()
672 : return
673 :
674 : my_rank = xmpi_comm_rank(dvdb%comm)
675 : comm = dvdb%comm
676 : qpt = dtset%qptn
677 :
678 : call wrtout(std_out, sjoin(" Writing Delta V_{q,nu)(r) potentials to file:", out_ncpath), do_flush=.True.)
679 : call wrtout(units, sjoin(ch10, "- Results stored in: ", out_ncpath))
680 : call wrtout(std_out, sjoin(" Using qpt:", ktoa(qpt)))
681 : !call wrtout(units, " Use `abiopen.py out_V1QAVG.nc -e` to visualize results")
682 : call dvdb%print([std_out], "", 0)
683 :
684 : ! Define FFT mesh
685 : ngfft = dvdb%ngfft
686 : nfft = product(ngfft(1:3))
687 :
688 : if (dtset%eph_task == -16) then
689 : call wrtout(units, " Assuming q-point already in the DVDB file. No interpolation.")
690 : interpolated = 0
691 :
692 : else if (dtset%eph_task == +16) then
693 : call wrtout(units, " Using Fourier interpolation.")
694 : comm_rpt = xmpi_comm_self
695 : call dvdb%ftinterp_setup(dtset%ddb_ngqpt, qptopt1, 1, dtset%ddb_shiftq, nfft, ngfft, comm_rpt)
696 : interpolated = 1
697 : else
698 : ABI_ERROR(sjoin("Invalid value for eph_task:", itoa(dtset%eph_task)))
699 : end if
700 :
701 : with_lr_model = .True.
702 :
703 : ! Create netcdf file.
704 : if (my_rank == master) then
705 : NCF_CHECK(nctk_open_create(ncid, out_ncpath, comm))
706 : NCF_CHECK(dvdb%cryst%ncwrite(ncid))
707 :
708 : ! Add other dimensions.
709 : ncerr = nctk_def_dims(ncid, [ &
710 : nctkdim_t("nfft", nfft), nctkdim_t("nspden", dvdb%nspden), &
711 : nctkdim_t("natom3", 3 * dvdb%cryst%natom)], defmode=.True.)
712 : NCF_CHECK(ncerr)
713 :
714 : ! Define arrays
715 : ncerr = nctk_def_arrays(ncid, [ &
716 : nctkarr_t("ngfft", "int", "three"), &
717 : nctkarr_t("qpt", "dp", "three"), &
718 : nctkarr_t("phfreqs", "dp", "natom3"), &
719 : nctkarr_t("displ_cart", "dp", "two, natom3, natom3"), &
720 : nctkarr_t("v1_qnu", "dp", "two, nfft, nspden, natom3")])
721 : NCF_CHECK(ncerr)
722 :
723 : if (with_lr_model) then
724 : NCF_CHECK(nctk_def_arrays(ncid, [nctkarr_t("v1lr_qnu", "dp", "two, nfft, nspden, natom3")]))
725 : end if
726 :
727 : NCF_CHECK(nctk_set_datamode(ncid))
728 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ngfft"), ngfft(1:3)))
729 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "qpt"), qpt))
730 : end if
731 :
732 : ABI_MALLOC(v1_qnu, (2, nfft, dvdb%nspden, dvdb%natom3))
733 : if (with_lr_model) then
734 : ABI_MALLOC(v1lr_atm, (2, nfft, dvdb%nspden, dvdb%natom3))
735 : ABI_MALLOC(v1lr_qnu, (2, nfft, dvdb%nspden, dvdb%natom3))
736 : end if
737 :
738 : ! Get phonon freqs and displacemented for this q-point.
739 : call ifc%fourq(dvdb%cryst, qpt, phfreqs, displ_cart, out_displ_red=displ_red)
740 :
741 : if (interpolated == 0) then
742 : ! Find the index of the q-point in the DVDB.
743 : db_iqpt = dvdb%findq(qpt)
744 : if (db_iqpt /= -1) then
745 : ! Read or reconstruct the dvscf potentials for all 3*natom perturbations.
746 : ! This call allocates v1scf(cplex, nfft, nspden, 3*natom))
747 : call dvdb%readsym_allv1(db_iqpt, cplex, nfft, ngfft, v1scf, comm)
748 : else
749 : ABI_ERROR(sjoin("Cannot find q-point:", ktoa(qpt), "in DVDB file"))
750 : end if
751 : else
752 :
753 : cplex = 2
754 : ABI_MALLOC(v1scf, (cplex, nfft, dvdb%nspden, dvdb%my_npert))
755 : call dvdb%ftinterp_qpt(qpt, nfft, ngfft, v1scf, dvdb%comm_rpt)
756 : end if
757 :
758 : ! Compute scattering potential the in phonon representations instead of atomic one.
759 : ! v1_qnu = \sum_{ka} phdispl{ka}(q,nu) D_{ka,q} V_scf(r)
760 : ! NOTE: prefactor 1/sqrt(2 w(q,nu)) is not included in the potentials saved to file.
761 : ! v1_qnu(2, nfft, nspden, natom3), v1scf(cplex, nfft, nspden, natom3)
762 : call ephtk_v1atm_to_vqnu(cplex, nfft, dvdb%nspden, dvdb%natom3, v1scf, displ_red, v1_qnu)
763 :
764 : if (with_lr_model) then
765 : ! Compute LR model in the atomic representation then compute phonon representation in v1lr_qnu.
766 : v1lr_atm = zero
767 : do idir=1,3
768 : do ipert=1,dvdb%natom
769 : ip = (ipert - 1) * 3 + idir
770 : call dvdb%get_v1r_long_range(qpt, idir, ipert, nfft, ngfft, v1lr_atm(:,:,1,ip))
771 : if (dvdb%nspden == 2) v1lr_atm(:,:,2,ip) = v1lr_atm(:,:,1,ip)
772 : end do
773 : end do
774 : call ephtk_v1atm_to_vqnu(2, nfft, dvdb%nspden, dvdb%natom3, v1lr_atm, displ_red, v1lr_qnu)
775 : end if
776 :
777 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "phfreqs"), phfreqs))
778 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "displ_cart"), displ_cart))
779 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "v1_qnu"), v1_qnu))
780 : if (with_lr_model) then
781 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "v1lr_qnu"), v1lr_qnu))
782 : end if
783 :
784 : ABI_FREE(v1scf)
785 : ABI_FREE(v1_qnu)
786 : ABI_SFREE(v1lr_atm)
787 : ABI_SFREE(v1lr_qnu)
788 :
789 : NCF_CHECK(nf90_close(ncid))
790 : call dvdb%close()
791 :
792 : call wrtout(std_out, "dvqnu file written", do_flush=.True.)
793 :
794 0 : end subroutine ncwrite_v1qnu
795 : !!***
796 :
797 : !----------------------------------------------------------------------
798 :
799 : !!****f* m_gkk/find_mpw
800 : !! NAME
801 : !! find_mpw
802 : !!
803 : !! FUNCTION
804 : !! Look at all k-points and spins to find the maximum number of plane waves.
805 : !!
806 : !! INPUTS
807 : !!
808 : !! OUTPUT
809 : !!
810 : !! SOURCE
811 :
812 4 : subroutine find_mpw(mpw, kpts, nsppol, nkpt, gmet, ecut, comm)
813 :
814 : !Arguments ------------------------------------
815 : !scalars
816 : integer,intent(out) :: mpw
817 : integer,intent(in) :: nsppol, nkpt, comm
818 : real(dp),intent(in) :: ecut
819 : !arrays
820 : real(dp),intent(in) :: kpts(3,nkpt), gmet(3,3)
821 :
822 : !Local variables ------------------------------
823 : !scalars
824 : integer :: my_rank, cnt, nproc, ierr, ispin, ikpt, my_mpw, onpw
825 4 : integer,allocatable :: gtmp(:,:)
826 : real(dp) :: kpt(3)
827 :
828 : !************************************************************************
829 :
830 4 : my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
831 :
832 4 : mpw = 0; cnt=0
833 8 : do ispin=1,nsppol
834 40 : do ikpt=1,nkpt
835 32 : cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle
836 128 : kpt = kpts(:,ikpt)
837 32 : call get_kg(kpt,1,ecut,gmet,onpw,gtmp)
838 32 : ABI_FREE(gtmp)
839 36 : mpw = max(mpw, onpw)
840 : end do
841 : end do
842 4 : my_mpw = mpw; call xmpi_max(my_mpw, mpw, comm, ierr)
843 :
844 4 : end subroutine find_mpw
845 : !!***
846 :
847 : end module m_gkk
848 : !!***
|