TABLE OF CONTENTS


ABINIT/m_gkk [ Modules ]

[ Top ] [ Modules ]

NAME

FUNCTION

  Tools for the computation of electron-phonon coupling matrix elements (gkk)

COPYRIGHT

  Copyright (C) 2008-2024 ABINIT group (GKA, MG)
  This file is distributed under the terms of the
  GNU General Public License, see ~abinit/COPYING
  or http://www.gnu.org/copyleft/gpl.txt .

SOURCE

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 #ifdef HAVE_NETCDF
39  use netcdf
40 #endif
41 
42  use defs_abitypes,    only : MPI_type
43  use m_time,           only : cwtime, sec2str
44  use m_io_tools,       only : iomode_from_fname
45  use m_fstrings,       only : itoa, sjoin, ktoa, ltoa, strcat
46  use m_symtk,          only : littlegroup_q
47  use m_fftcore,        only : get_kg
48  use defs_datatypes,   only : ebands_t, pseudopotential_type
49  use m_crystal,        only : crystal_t
50  use m_bz_mesh,        only : findqg0
51  use m_cgtools,        only : dotprod_g
52  use m_kg,             only : getph
53  use m_pawang,         only : pawang_type
54  use m_pawrad,         only : pawrad_type
55  use m_pawtab,         only : pawtab_type
56  use m_pawfgr,         only : pawfgr_type
57  use m_eig2d,          only : gkk_t, gkk_init, gkk_ncwrite, gkk_free
58  use m_wfd,            only : wfd_init, wfd_t
59  use m_getgh1c,        only : getgh1c, rf_transgrid_and_pack, getgh1c_setup
60 
61  implicit none
62 
63  private

m_gkk/eph_gkk [ Functions ]

[ Top ] [ m_gkk ] [ Functions ]

NAME

  eph_gkk

FUNCTION

  Compute electron-phonon coupling matrix elements.

INPUTS

 wk0_path=String with the path to the GS unperturbed WFK file.
 ngfft(18),ngfftf(18)=Coarse and Fine FFT meshes.
 dtset<dataset_type>=All input variables for this dataset.
 ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
 dvdb<dbdb_type>=Database with the DFPT SCF potentials.
 ifc<ifc_type>=interatomic force constants and corresponding real space grid info.
 pawfgr <type(pawfgr_type)>=fine grid parameters and related data
 pawang<pawang_type)>=PAW angular mesh and related data.
 pawrad(ntypat*usepaw)<pawrad_type>=Paw radial mesh and related data.
 pawtab(ntypat*usepaw)<pawtab_type>=Paw tabulated starting data.
 psps<pseudopotential_type>=Variables related to pseudopotentials.
 comm=MPI communicator.

OUTPUT

NOTES

SOURCE

 99 subroutine eph_gkk(wfk0_path,wfq_path,dtfil,ngfft,ngfftf,dtset,cryst,ebands_k,ebands_kq,dvdb,ifc,&
100                        pawfgr,pawang,pawrad,pawtab,psps,mpi_enreg,comm)
101 
102 !Arguments ------------------------------------
103 !scalars
104  character(len=*),intent(in) :: wfk0_path, wfq_path
105  integer,intent(in) :: comm
106  type(datafiles_type),intent(in) :: dtfil
107  type(dataset_type),intent(in) :: dtset
108  type(crystal_t),intent(in) :: cryst
109  type(ebands_t),intent(in) :: ebands_k, ebands_kq
110  type(dvdb_t),target,intent(inout) :: dvdb
111  type(pawang_type),intent(in) :: pawang
112  type(pseudopotential_type),intent(in) :: psps
113  type(pawfgr_type),intent(in) :: pawfgr
114  type(ifc_type),intent(in) :: ifc
115  type(mpi_type),intent(inout) :: mpi_enreg
116 !arrays
117  integer,intent(in) :: ngfft(18),ngfftf(18)
118  type(pawrad_type),intent(in) :: pawrad(psps%ntypat*psps%usepaw)
119  type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
120 
121 !Local variables ------------------------------
122 !scalars
123  integer,parameter :: tim_getgh1c=1, berryopt0=0, useylmgr1=0, master=0, qptopt1 = 1
124  integer :: my_rank,nproc,mband,mband_kq,my_minb,my_maxb,nsppol,nkpt,nkpt_kq,idir,ipert
125  integer :: cplex,db_iqpt,natom,natom3,ipc,nspinor
126  integer :: ib1,ib2,band,ik,ikq,timerev_q
127  integer :: spin,istwf_k,istwf_kq,npw_k,npw_kq, comm_rpt
128  integer :: mpw,mpw_k,mpw_kq,ierr,my_kstart,my_kstop,ncid
129  integer :: n1,n2,n3,n4,n5,n6,nspden,ncerr
130  integer :: sij_opt,usecprj,usevnl,optlocal,optnl,opt_gvnlx1
131  integer :: nfft,nfftf,mgfft,mgfftf,nkpg,nkpg1, interpolated
132  real(dp) :: cpu,wall,gflops,ecut,eshift,eig0nk,dotr,doti
133  logical :: i_am_master, gen_eigenpb
134  type(wfd_t) :: wfd_k, wfd_kq
135  type(gs_hamiltonian_type) :: gs_hamkq
136  type(rf_hamiltonian_type) :: rf_hamkq
137  type(gkk_t) :: gkk2d
138  character(len=500) :: msg, what
139  character(len=fnlen) :: fname, gkkfilnam
140 !arrays
141  integer :: g0_k(3),symq(4,2,cryst%nsym)
142  integer,allocatable :: kg_k(:,:),kg_kq(:,:),nband(:,:),nband_kq(:,:),blkflg(:,:), wfd_istwfk(:)
143  real(dp) :: kk(3),kq(3),qpt(3),phfrq(3*cryst%natom)
144  real(dp) :: dvdb_qdamp(1)
145  real(dp),allocatable :: displ_cart(:,:,:),displ_red(:,:,:), eigens_kq(:,:,:)
146  real(dp),allocatable :: grad_berry(:,:),kinpw1(:),kpg1_k(:,:),kpg_k(:,:),dkinpw(:)
147  real(dp),allocatable :: ffnlk(:,:,:,:),ffnl1(:,:,:,:),ph3d(:,:,:),ph3d1(:,:,:)
148  real(dp),allocatable :: v1scf(:,:,:,:),gkk(:,:,:,:,:)
149  real(dp),allocatable :: bras(:,:,:),kets(:,:,:),h1_kets(:,:,:)
150  real(dp),allocatable :: ph1d(:,:),vlocal(:,:,:,:),vlocal1(:,:,:,:,:)
151  real(dp),allocatable :: ylm_kq(:,:),ylm_k(:,:),ylmgr_kq(:,:,:)
152  real(dp),allocatable :: dummy_vtrial(:,:),gvnlx1(:,:), gs1c(:,:), gkq_atm(:,:,:,:)
153  logical,allocatable :: bks_mask(:,:,:),bks_mask_kq(:,:,:),keep_ur(:,:,:),keep_ur_kq(:,:,:)
154  type(pawcprj_type),allocatable  :: cwaveprj0(:,:) !natom,nspinor*usecprj)
155 
156 !************************************************************************
157 
158  what = "(GKK files)"; if (dtset%eph_task == -2) what = "GKQ file"
159  write(msg, '(3a)') " Computation of electron-phonon coupling matrix elements ", trim(what), ch10
160  call wrtout([std_out, ab_out], msg, do_flush=.True.)
161 
162  if (psps%usepaw == 1) then
163    ABI_ERROR("PAW not implemented")
164    ABI_UNUSED((/pawang%nsym, pawrad(1)%mesh_size/))
165  end if
166 
167  my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm); i_am_master = my_rank == master
168 
169  ! Copy important dimensions
170  natom = cryst%natom
171  natom3 = 3 * natom
172  nsppol = ebands_k%nsppol
173  nspinor = ebands_k%nspinor
174  nspden = dtset%nspden
175  nkpt = ebands_k%nkpt
176  mband = ebands_k%mband
177  nkpt_kq = ebands_kq%nkpt
178  mband_kq = ebands_kq%mband
179  ecut = dtset%ecut
180  !write(std_out, *)"ebands dims (b, k, s): ", ebands_k%mband, ebands_k%nkpt, ebands_k%nsppol
181  !write(std_out, *)"ebands_kq dims (b, k, s): ", ebands_kq%mband, ebands_kq%nkpt, ebands_kq%nsppol
182 
183  qpt = dtset%qptn(:)
184 
185  nfftf = product(ngfftf(1:3)); mgfftf = maxval(ngfftf(1:3))
186  nfft = product(ngfft(1:3)) ; mgfft = maxval(ngfft(1:3))
187  n1=ngfft(1); n2=ngfft(2); n3=ngfft(3)
188  n4=ngfft(4); n5=ngfft(5); n6=ngfft(6)
189 
190  ! Open the DVDB file
191  call dvdb%open_read(ngfftf, xmpi_comm_self)
192 
193  ! Initialize the wave function descriptors.
194  ! For the time being, no memory distribution, each node has the full set of states.
195  my_minb = 1; my_maxb = mband
196 
197  ABI_MALLOC(nband, (nkpt, nsppol))
198  ABI_MALLOC(bks_mask,(mband, nkpt, nsppol))
199  ABI_MALLOC(keep_ur,(mband, nkpt ,nsppol))
200  nband=mband; bks_mask=.False.; keep_ur=.False.
201 
202  ABI_MALLOC(nband_kq, (nkpt_kq, nsppol))
203  ABI_MALLOC(bks_mask_kq,(mband_kq, nkpt_kq, nsppol))
204  ABI_MALLOC(keep_ur_kq,(mband_kq, nkpt_kq ,nsppol))
205  nband_kq=mband_kq; bks_mask_kq=.False.; keep_ur_kq=.False.
206 
207  ! Distribute the k-points over the processors
208  call xmpi_split_work(nkpt,comm,my_kstart,my_kstop)
209  do ik=1,nkpt
210    if (.not. (ik >= my_kstart .and. ik <= my_kstop)) cycle
211    kk = ebands_k%kptns(:,ik)
212    kq = kk + qpt
213    ! Find the index of the k+q point
214    call findqg0(ikq,g0_k,kq,nkpt_kq,ebands_kq%kptns(:,:), [1,1,1])
215    bks_mask(:,ik,:) = .True.
216    bks_mask_kq(:,ikq,:) = .True.
217  end do
218 
219  ! Impose istwfk=1 for all k points. This is also done in respfn (see inkpts)
220  ! wfd_read_wfk will handle a possible conversion if WFK contains istwfk /= 1.
221  ABI_MALLOC(wfd_istwfk, (nkpt))
222  wfd_istwfk = 1
223 
224  ! Initialize the wavefunction descriptors
225  call wfd_init(wfd_k,cryst,pawtab,psps,keep_ur,mband,nband,nkpt,nsppol,bks_mask,&
226    nspden,nspinor,ecut,dtset%ecutsm,dtset%dilatmx,wfd_istwfk,ebands_k%kptns,ngfft,&
227    dtset%nloalg,dtset%prtvol,dtset%pawprtvol,comm)
228  ABI_FREE(wfd_istwfk)
229 
230  call wfd_k%print(header="Wavefunctions on the k-points grid",mode_paral='PERS')
231 
232  ABI_MALLOC(wfd_istwfk, (nkpt_kq))
233  wfd_istwfk = 1
234 
235  call wfd_init(wfd_kq,cryst,pawtab,psps,keep_ur_kq,mband_kq,nband_kq,nkpt_kq,nsppol,bks_mask_kq,&
236    nspden,nspinor,ecut,dtset%ecutsm,dtset%dilatmx,wfd_istwfk,ebands_kq%kptns,ngfft,&
237    dtset%nloalg,dtset%prtvol,dtset%pawprtvol,comm)
238  ABI_FREE(wfd_istwfk)
239 
240  call wfd_kq%print(header="Wavefunctions on the q-shifted k-points grid",mode_paral='PERS')
241 
242  ABI_FREE(nband)
243  ABI_FREE(bks_mask)
244  ABI_FREE(keep_ur)
245  ABI_FREE(nband_kq)
246  ABI_FREE(bks_mask_kq)
247  ABI_FREE(keep_ur_kq)
248 
249  ! Read wavefunctions on the k-points grid and q-shifted k-points grid.
250  call wfd_k%read_wfk(wfk0_path, iomode_from_fname(wfk0_path))
251 
252  call wfd_kq%read_wfk(wfq_path, iomode_from_fname(wfq_path))
253 
254  ! ph1d(2,3*(2*mgfft+1)*natom)=one-dimensional structure factor information on the coarse grid.
255  ABI_MALLOC(ph1d, (2,3*(2*mgfft+1)*natom))
256  call getph(cryst%atindx,natom,n1,n2,n3,ph1d,cryst%xred)
257 
258  ! Find the appropriate value of mpw
259  call find_mpw(mpw_k, ebands_k%kptns(:,:), nsppol, nkpt, cryst%gmet,ecut,comm)
260  call find_mpw(mpw_kq, ebands_kq%kptns(:,:), nsppol, nkpt_kq, cryst%gmet,ecut,comm)
261  mpw = max(mpw_k, mpw_kq)
262 
263  ! Allow PW-arrays dimensioned with mpw
264  ABI_MALLOC(kg_k, (3, mpw))
265  ABI_MALLOC(kg_kq, (3, mpw))
266 
267  ! Spherical Harmonics for useylm==1.
268  ABI_MALLOC(ylm_k,(mpw, psps%mpsang*psps%mpsang*psps%useylm))
269  ABI_MALLOC(ylm_kq,(mpw, psps%mpsang*psps%mpsang*psps%useylm))
270  ABI_MALLOC(ylmgr_kq,(mpw, 3, psps%mpsang*psps%mpsang*psps%useylm*useylmgr1))
271 
272  ! TODO FOR PAW
273  usecprj = 0
274  ABI_MALLOC(cwaveprj0, (natom, nspinor*usecprj))
275 
276  ! Prepare call to getgh1c
277  usevnl = 0
278  optlocal = 1  ! local part of H^(1) is computed in gh1c=<G|H^(1)|C>
279  optnl = 2     ! non-local part of H^(1) is totally computed in gh1c=<G|H^(1)|C>
280  opt_gvnlx1 = 0 ! gvnlx1 is output
281  ABI_MALLOC(gvnlx1, (2,usevnl))
282  ABI_MALLOC(grad_berry, (2,nspinor*(berryopt0/4)))
283 
284  ! This part is taken from dfpt_vtorho
285  !==== Initialize most of the Hamiltonian (and derivative) ====
286  !1) Allocate all arrays and initialize quantities that do not depend on k and spin.
287  !2) Perform the setup needed for the non-local factors:
288  !* Norm-conserving: Constant kleimann-Bylander energies are copied from psps to gs_hamk.
289  !* PAW: Initialize the overlap coefficients and allocate the Dij coefficients.
290 
291  call init_hamiltonian(gs_hamkq,psps,pawtab,nspinor,nsppol,nspden,natom,&
292    dtset%typat,cryst%xred,nfft,mgfft,ngfft,cryst%rprimd,dtset%nloalg,&
293    usecprj=usecprj,ph1d=ph1d,nucdipmom=dtset%nucdipmom,gpu_option=dtset%gpu_option,&
294    comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab,mpi_spintab=mpi_enreg%my_isppoltab)
295 
296  ! Allocate vlocal. Note nvloc
297  ABI_MALLOC(vlocal,(n4,n5,n6,gs_hamkq%nvloc))
298  ! Allocate work space arrays.
299  ABI_MALLOC(blkflg, (natom3,natom3))
300  ABI_CALLOC(dummy_vtrial, (nfftf,nspden))
301 
302  call cwtime(cpu, wall, gflops, "start")
303 
304  interpolated = 0
305  if (dtset%eph_use_ftinterp /= 0) then
306    ABI_WARNING(sjoin("Enforcing FT interpolation for q-point", ktoa(qpt)))
307    comm_rpt = xmpi_comm_self
308    call dvdb%ftinterp_setup(dtset%ddb_ngqpt, qptopt1, 1, dtset%ddb_shiftq, nfftf, ngfftf, comm_rpt)
309    cplex = 2
310    ABI_MALLOC(v1scf, (cplex, nfftf, nspden, dvdb%my_npert))
311    call dvdb%ftinterp_qpt(qpt, nfftf, ngfftf, v1scf, dvdb%comm_rpt)
312    interpolated = 1
313  else
314    ! Find the index of the q-point in the DVDB.
315    db_iqpt = dvdb%findq(qpt)
316    if (db_iqpt /= -1) then
317      if (dtset%prtvol > 0) call wrtout(std_out, sjoin("Found: ",ktoa(qpt)," in DVDB with index ",itoa(db_iqpt)))
318      ! Read or reconstruct the dvscf potentials for all 3*natom perturbations.
319      ! This call allocates v1scf(cplex, nfftf, nspden, 3*natom))
320      call dvdb%readsym_allv1(db_iqpt, cplex, nfftf, ngfftf, v1scf, comm)
321    else
322      ABI_WARNING(sjoin("Cannot find q-point:", ktoa(qpt), "in DVDB file"))
323    end if
324  end if
325 
326  ! Examine the symmetries of the q wavevector
327  call littlegroup_q(cryst%nsym,qpt,symq,cryst%symrec,cryst%symafm,timerev_q,prtvol=dtset%prtvol)
328 
329  ! Allocate vlocal1 with correct cplex. Note nvloc
330  ABI_MALLOC_OR_DIE(vlocal1,(cplex*n4,n5,n6,gs_hamkq%nvloc,natom3), ierr)
331 
332  ABI_MALLOC(displ_cart, (2,3*cryst%natom,3*cryst%natom))
333  ABI_MALLOC(displ_red, (2,3*cryst%natom,3*cryst%natom))
334 
335  if (dtset%eph_task == 2) then
336    ! Write GKK files (1 file for perturbation)
337    ABI_MALLOC(gkk, (2*mband*nsppol,nkpt,1,1,mband_kq))
338 
339  else if (dtset%eph_task == -2) then
340    ! Write GKQ file with all perturbations. gkq are given in the atom representation.
341    ! TODO: mband_kq == mband
342    ABI_MALLOC(gkq_atm, (2, mband_kq, mband, nkpt))
343    if (i_am_master) then
344      call ifc%fourq(cryst, qpt, phfrq, displ_cart, out_displ_red=displ_red)
345      fname = strcat(dtfil%filnam_ds(4), "_GKQ.nc")
346 #ifdef HAVE_NETCDF
347      NCF_CHECK_MSG(nctk_open_create(ncid, fname, xmpi_comm_self), "Creating GKQ file")
348      NCF_CHECK(cryst%ncwrite(ncid))
349      ! Write bands on k mesh.
350      NCF_CHECK(ebands_ncwrite(ebands_k, ncid))
351      ncerr = nctk_def_dims(ncid, [nctkdim_t('number_of_phonon_modes', natom3)], defmode=.True.)
352      NCF_CHECK(ncerr)
353      ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: &
354        "symdynmat", "symv1scf", "dvdb_add_lr", "interpolated"])
355      NCF_CHECK(ncerr)
356      NCF_CHECK(nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: "qdamp"]))
357 
358      ! Define EPH arrays
359      ncerr = nctk_def_arrays(ncid, [ &
360        nctkarr_t('qpoint', "dp" , 'number_of_reduced_dimensions'), &
361        nctkarr_t('emacro_cart', "dp", 'number_of_cartesian_directions, number_of_cartesian_directions'), &
362        nctkarr_t('becs_cart', "dp", "number_of_cartesian_directions, number_of_cartesian_directions, number_of_atoms"), &
363        nctkarr_t("eigenvalues_kq", "dp", "max_number_of_states, number_of_kpoints, number_of_spins"), &
364        nctkarr_t('phfreqs', "dp", 'number_of_phonon_modes'), &
365        nctkarr_t('phdispl_cart', "dp", 'complex, number_of_phonon_modes, number_of_phonon_modes'), &
366        !nctkarr_t('phdispl_cart_qvers', "dp", 'complex, number_of_phonon_modes, number_of_phonon_modes'), &
367        nctkarr_t('phdispl_red', "dp", 'complex, number_of_phonon_modes, number_of_phonon_modes'), &
368        nctkarr_t("gkq_representation", "char", "character_string_length"), &
369        nctkarr_t('gkq', "dp", &
370          'complex, max_number_of_states, max_number_of_states, number_of_phonon_modes, number_of_kpoints, number_of_spins') &
371      ])
372      NCF_CHECK(ncerr)
373      ! Write data.
374      NCF_CHECK(nctk_set_datamode(ncid))
375      ncerr = nctk_write_iscalars(ncid, [character(len=nctk_slen) :: &
376        "symdynmat", "symv1scf", "dvdb_add_lr", "interpolated"], &
377        [dtset%symdynmat, dtset%symv1scf, dtset%dvdb_add_lr, interpolated])
378      NCF_CHECK(ncerr)
379      dvdb_qdamp = dvdb%qdamp
380      NCF_CHECK(nctk_write_dpscalars(ncid, [character(len=nctk_slen) :: "qdamp"], dvdb_qdamp))
381      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "qpoint"), qpt))
382      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "emacro_cart"), dvdb%dielt))
383      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "becs_cart"), dvdb%zeff))
384      ABI_MALLOC(eigens_kq, (ebands_kq%mband, nkpt, nsppol))
385      do ik=1,nkpt
386        kk = ebands_k%kptns(:,ik)
387        kq = kk + qpt
388        ! Find the index of the k+q point
389        call findqg0(ikq, g0_k, kq, nkpt_kq, ebands_kq%kptns, [1,1,1])
390        eigens_kq(:, ik, :) = ebands_kq%eig(:, ikq, :)
391      end do
392      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "eigenvalues_kq"), eigens_kq))
393      ABI_FREE(eigens_kq)
394      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "phfreqs"), phfrq))
395      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'phdispl_cart'), displ_cart))
396      ! Add phonon displacement for qvers
397      !call ifc_fourq(ifc, cryst, qpt, phfrq, displ_cart, out_displ_red=displ_red, nanaqdir="reduced")
398      !NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'phdispl_cart_qvers'), displ_cart))
399      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'phdispl_red'), displ_red))
400      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "gkq_representation"), "atom"))
401 #endif
402    end if
403  else
404    ABI_ERROR(sjoin("Invalid value for eph_task:", itoa(dtset%eph_task)))
405  end if
406 
407  ! Loop over all 3*natom perturbations.
408  do ipc=1,natom3
409    idir = mod(ipc-1, 3) + 1
410    ipert = (ipc - idir) / 3 + 1
411    write(msg, '(a,2i4)') " Treating ipert, idir = ", ipert, idir
412    call wrtout(std_out, msg, do_flush=.True.)
413    if (dtset%eph_task == 2) gkk = zero
414 
415    do spin=1,nsppol
416      if (dtset%eph_task == -2) gkq_atm = zero
417 
418      ! Set up local potential vlocal1 with proper dimensioning, from vtrial1 taking into account the spin.
419      call rf_transgrid_and_pack(spin,nspden,psps%usepaw,cplex,nfftf,nfft,ngfft,gs_hamkq%nvloc,&
420                pawfgr,mpi_enreg,dummy_vtrial,v1scf(:,:,:,ipc),vlocal,vlocal1(:,:,:,:,ipc))
421 
422      ! Continue to initialize the Hamiltonian
423      call gs_hamkq%load_spin(spin,vlocal=vlocal,with_nonlocal=.true.)
424 
425      ! Allocate workspace for wavefunctions. Make npw larger than expected.
426      ABI_MALLOC(bras, (2, mpw*nspinor, mband))
427      ABI_MALLOC(kets, (2, mpw*nspinor, mband))
428      ABI_MALLOC(h1_kets, (2, mpw*nspinor, mband))
429 
430      ! GKA: This little block used to be right after the perturbation loop
431      ! Prepare application of the NL part.
432      call init_rf_hamiltonian(cplex,gs_hamkq,ipert,rf_hamkq,has_e1kbsc=.true.)
433      call rf_hamkq%load_spin(spin,vlocal1=vlocal1(:,:,:,:,ipc),with_nonlocal=.true.)
434 
435      do ik=1,nkpt
436        ! Only do a subset a k-points
437        if (.not. (ik >= my_kstart .and. ik <= my_kstop)) cycle
438 
439        kk = ebands_k%kptns(:,ik)
440        kq = kk + qpt
441        ! Find the index of the k+q point
442        call findqg0(ikq, g0_k, kq, nkpt_kq, ebands_kq%kptns, [1,1,1])
443 
444        ! Copy u_k(G)
445        istwf_k = wfd_k%istwfk(ik); npw_k = wfd_k%npwarr(ik)
446        ABI_CHECK(mpw >= npw_k, "mpw < npw_k")
447        kg_k(:,1:npw_k) = wfd_k%kdata(ik)%kg_k
448        do ib2=1,mband
449          call wfd_k%copy_cg(ib2, ik, spin, kets(1,1,ib2))
450        end do
451 
452        ! Copy u_kq(G)
453        istwf_kq = wfd_kq%istwfk(ikq); npw_kq = wfd_kq%npwarr(ikq)
454        ABI_CHECK(mpw >= npw_kq, "mpw < npw_kq")
455        kg_kq(:,1:npw_kq) = wfd_kq%kdata(ikq)%kg_k
456        do ib1=1,mband_kq
457          call wfd_kq%copy_cg(ib1, ikq, spin, bras(1,1,ib1))
458        end do
459 
460        ! if PAW, one has to solve a generalized eigenproblem
461        ! Be careful here because I will need sij_opt==-1
462        gen_eigenpb = (psps%usepaw==1)
463        sij_opt = 0; if (gen_eigenpb) sij_opt = 1
464        ABI_MALLOC(gs1c, (2,npw_kq*nspinor*((sij_opt+1)/2)))
465 
466        ! GKA: Previous loop on 3*natom perturbations used to start here
467        ! This call is not optimal because there are quantities in out that do not depend on idir,ipert
468        call getgh1c_setup(gs_hamkq,rf_hamkq,dtset,psps,kk,kq,idir,ipert,&    ! In
469          cryst%natom,cryst%rmet,cryst%gprimd,cryst%gmet,istwf_k,&            ! In
470          npw_k,npw_kq,useylmgr1,kg_k,ylm_k,kg_kq,ylm_kq,ylmgr_kq,&           ! In
471          dkinpw,nkpg,nkpg1,kpg_k,kpg1_k,kinpw1,ffnlk,ffnl1,ph3d,ph3d1)       ! Out
472 
473        ! Calculate dvscf * psi_k, results stored in h1_kets on the k+q sphere.
474        ! Compute H(1) applied to GS wavefunction Psi(0)
475        do ib2=1,mband
476          eig0nk = ebands_k%eig(ib2,ik,spin)
477          ! Use scissor shift on 0-order eigenvalue
478          eshift = eig0nk - dtset%dfpt_sciss
479 
480          call getgh1c(berryopt0,kets(:,:,ib2),cwaveprj0,h1_kets(:,:,ib2),&
481                       grad_berry,gs1c,gs_hamkq,gvnlx1,idir,ipert,eshift,mpi_enreg,optlocal,&
482                       optnl,opt_gvnlx1,rf_hamkq,sij_opt,tim_getgh1c,usevnl)
483        end do
484 
485        ABI_FREE(kinpw1)
486        ABI_FREE(kpg1_k)
487        ABI_FREE(kpg_k)
488        ABI_FREE(dkinpw)
489        ABI_FREE(ffnlk)
490        ABI_FREE(ffnl1)
491        ABI_FREE(ph3d)
492        ABI_FREE(gs1c)
493        ABI_SFREE(ph3d1)
494 
495        ! Calculate elphmat(j,i) = <psi_{k+q,j}|dvscf_q*psi_{k,i}> for this perturbation.
496        ! The array eig1_k contains:
497        !
498        ! <u_(band,k+q)^(0)|H_(k+q,k)^(1)|u_(band,k)^(0)>                           (NC psps)
499        ! <u_(band,k+q)^(0)|H_(k+q,k)^(1)-(eig0_k+eig0_k+q)/2.S^(1)|u_(band,k)^(0)> (PAW)
500        do ib2=1,mband
501          do ib1=1,mband_kq
502            call dotprod_g(dotr,doti,istwf_kq,npw_kq*nspinor,2,bras(1,1,ib1),h1_kets(1,1,ib2),&
503              mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
504            band = 2*ib2-1 + (spin-1) * 2 * mband
505 
506            if (dtset%eph_task == 2) then
507              gkk(band,ik,1,1,ib1) = dotr
508              gkk(band+1,ik,1,1,ib1) = doti
509            else
510              gkq_atm(:, ib1, ib2, ik) = [dotr, doti]
511            end if
512 
513          end do
514        end do
515 
516      end do ! ikpt
517 
518      ABI_FREE(bras)
519      ABI_FREE(kets)
520      ABI_FREE(h1_kets)
521      call rf_hamkq%free()
522 
523      if (dtset%eph_task == -2) then
524        ! Gather the k-points computed by all processes
525        call xmpi_sum_master(gkq_atm, master, comm, ierr)
526        if (i_am_master) then
527          ! Write the netCDF file.
528 #ifdef HAVE_NETCDF
529          ncerr = nf90_put_var(ncid, nctk_idname(ncid, "gkq"), gkq_atm, &
530            start=[1, 1, 1, ipc, 1, 1], count=[2, mband, mband, 1, nkpt, spin])
531          NCF_CHECK(ncerr)
532 #endif
533        end if
534      end if
535    end do ! spin
536 
537    if (dtset%eph_task == 2) then
538      ! Gather the k-points computed by all processes
539      call xmpi_sum_master(gkk,master,comm,ierr)
540      ! Init a gkk_t object
541      call gkk_init(gkk,gkk2d,mband,nsppol,nkpt,1,1)
542      ! Write the netCDF file.
543      call appdig(ipc,dtfil%fnameabo_gkk,gkkfilnam)
544      fname = strcat(gkkfilnam, ".nc")
545 #ifdef HAVE_NETCDF
546      if (i_am_master) then
547        NCF_CHECK_MSG(nctk_open_create(ncid, fname, xmpi_comm_self), "Creating GKK file")
548        NCF_CHECK(cryst%ncwrite(ncid))
549        NCF_CHECK(ebands_ncwrite(ebands_k, ncid))
550        call gkk_ncwrite(gkk2d, qpt, 1.0_dp,  ncid)
551        NCF_CHECK(nf90_close(ncid))
552      end if
553 #endif
554      ! Free memory
555      call gkk_free(gkk2d)
556    end if
557  end do ! ipc (loop over 3*natom atomic perturbations)
558 
559  call cwtime(cpu, wall, gflops, "stop")
560  write(msg, '(2a)') " Computation of gkq matrix elements with ", trim(what)
561  call wrtout([std_out, ab_out], msg, do_flush=.True.)
562  call wrtout(std_out, sjoin("cpu-time:", sec2str(cpu), ",wall-time:", sec2str(wall)), do_flush=.True.)
563 
564  if (dtset%eph_task == -2 .and. i_am_master) then
565 #ifdef HAVE_NETCDF
566    NCF_CHECK(nf90_close(ncid))
567 #endif
568  end if
569 
570  ! ===========
571  ! Free memory
572  ! ===========
573  ABI_SFREE(gkk)
574  ABI_SFREE(gkq_atm)
575  ABI_FREE(displ_cart)
576  ABI_FREE(displ_red)
577  ABI_FREE(v1scf)
578  ABI_FREE(vlocal1)
579  ABI_FREE(gvnlx1)
580  ABI_FREE(grad_berry)
581  ABI_FREE(dummy_vtrial)
582  ABI_FREE(ph1d)
583  ABI_FREE(vlocal)
584  ABI_FREE(kg_k)
585  ABI_FREE(kg_kq)
586  ABI_FREE(ylm_k)
587  ABI_FREE(ylm_kq)
588  ABI_FREE(ylmgr_kq)
589  ABI_FREE(blkflg)
590 
591  call gs_hamkq%free()
592  call wfd_k%free()
593  call wfd_kq%free()
594  call pawcprj_free(cwaveprj0)
595  ABI_FREE(cwaveprj0)
596 
597 end subroutine eph_gkk

m_gkk/find_mpw [ Functions ]

[ Top ] [ m_gkk ] [ Functions ]

NAME

  find_mpw

FUNCTION

  Look at all k-points and spins to find the maximum
  number of plane waves.

INPUTS

OUTPUT

NOTES

SOURCE

910 subroutine find_mpw(mpw, kpts, nsppol, nkpt, gmet, ecut, comm)
911 
912 !Arguments ------------------------------------
913 !scalars
914  integer,intent(out) :: mpw
915  integer,intent(in) :: nsppol, nkpt
916  integer,intent(in) :: comm
917  real(dp),intent(in) :: ecut
918 !arrays
919  real(dp),intent(in) :: kpts(3,nkpt)
920  real(dp),intent(in) :: gmet(3,3)
921 
922 !Local variables ------------------------------
923 !scalars
924  integer :: my_rank, cnt, nproc, ierr
925  integer :: ispin, ikpt
926  integer :: my_mpw, onpw
927  integer,allocatable :: gtmp(:,:)
928  real(dp) :: kpt(3)
929 
930  my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
931 
932  mpw = 0; cnt=0
933  do ispin=1,nsppol
934    do ikpt=1,nkpt
935      cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle
936      kpt = kpts(:,ikpt)
937      call get_kg(kpt,1,ecut,gmet,onpw,gtmp)
938      ABI_FREE(gtmp)
939      mpw = max(mpw, onpw)
940    end do
941  end do
942  my_mpw = mpw; call xmpi_max(my_mpw, mpw, comm, ierr)
943 
944 end subroutine find_mpw

m_gkk/ncwrite_v1qnu [ Functions ]

[ Top ] [ m_gkk ] [ Functions ]

NAME

  ncwrite_v1qnu

FUNCTION

  Compute \delta V_{q,nu)(r) and dump results to netcdf file.
  This routine should be called by a single processor.

 INPUT
  dvdb<dbdb_type>=Database with the DFPT SCF potentials.
  dtset<dataset_type>= Input variables.
  ifc<ifc_type>=interatomic force constants and corresponding real space grid info.
  out_ncpath=Name of the netcdf file.

OUTPUT

  Only writing

SOURCE

621 subroutine ncwrite_v1qnu(dvdb, dtset, ifc, out_ncpath)
622 
623  use m_bz_mesh, only : kpath_t, kpath_new
624 
625 !Arguments ------------------------------------
626 !scalars
627  type(dataset_type),target,intent(in) :: dtset
628  type(dvdb_t),intent(inout) :: dvdb
629  type(ifc_type),intent(in) :: ifc
630  character(len=*),intent(in) :: out_ncpath
631 
632 !Local variables-------------------------------
633 !scalars
634  integer,parameter :: master = 0, qptopt1 = 1
635  integer :: db_iqpt, cplex, nfft, comm, ip, idir, ipert, my_rank, interpolated, comm_rpt
636  logical :: with_lr_model
637 #ifdef HAVE_NETCDF
638  integer :: ncid, ncerr
639 #endif
640 !arrays
641  integer :: ngfft(18)
642  real(dp) :: phfreqs(dvdb%natom3),qpt(3)
643  real(dp) :: displ_cart(2,3, dvdb%cryst%natom, dvdb%natom3), displ_red(2,dvdb%natom3,dvdb%natom3)
644  real(dp),allocatable :: v1scf(:,:,:,:), v1_qnu(:,:,:,:)
645  real(dp),allocatable :: v1lr_atm(:,:,:,:), v1lr_qnu(:,:,:,:)
646 #if 1
647  integer :: iq, nu, iatom, ii, jj, kk
648  real(dp) :: inv_qepsq, qtau, phre, phim, rtmp
649  type(kpath_t) :: qpath
650  real(dp) :: bounds(3,6), qpt_red(3), qpt_cart(3),  glr(3)
651  real(dp) :: values(dvdb%natom3)
652 
653 !************************************************************************
654 
655  ! +0.50000  +0.50000  +0.50000  # L
656  ! +0.00000  +0.00000  +0.00000  # $\Gamma$
657  ! +0.50000  +0.00000  +0.50000  # X
658  ! +0.50000  +0.25000  +0.75000  # W
659  ! +0.37500  +0.37500  +0.75000  # K
660  ! +0.00000  +0.00000  +0.00000  # $\Gamma$
661  ! +0.37500  +0.37500  +0.75000  # K
662 
663  ! +0.62500  +0.25000  +0.62500  # U
664  ! +0.50000  +0.50000  +0.50000  # L
665  ! +0.37500  +0.37500  +0.75000  # K
666  ! +0.62500  +0.25000  +0.62500  # U
667  ! +0.50000  +0.00000  +0.50000  # X
668 
669  bounds(:, 1) = tol3 * [+0.50000,  +0.50000, +0.50000] !  # L
670  bounds(:, 2) = tol3 * [+0.00000,  +0.00000, +0.00000] !  # $\Gamma$
671  bounds(:, 3) = tol3 * [+0.50000,  +0.00000, +0.50000] !  # X
672  bounds(:, 4) = tol3 * [+0.37500,  +0.37500, +0.75000] !  # K
673  bounds(:, 5) = tol3 * [+0.00000,  +0.00000, +0.00000] !  # $\Gamma$
674  bounds(:, 6) = tol3 * [+0.50000,  +0.25000, +0.75000] !  # W
675 
676  qpath = kpath_new(bounds, dvdb%cryst%gprimd, dtset%ndivsm)
677 
678  do iq=1,qpath%npts
679    qpt_red = qpath%points(:, iq)
680    qpt_cart = two_pi * matmul(dvdb%cryst%gprimd, qpt_red)
681    inv_qepsq = one / dot_product(qpt_cart, matmul(ifc%dielt, qpt_cart))
682    call ifc%fourq(dvdb%cryst, qpt_red, phfreqs, displ_cart)
683    do nu=1, dvdb%natom3
684      glr = zero
685      do iatom=1, dvdb%cryst%natom
686        ! Phase factor exp(-i (q+G) . tau)
687        qtau = - two_pi * dot_product(qpt_red, dvdb%cryst%xred(:,iatom))
688        phre = cos(qtau); phim = sin(qtau)
689        do jj=1,3
690          do ii=1,3
691            do kk=1,3
692              rtmp = dvdb%qstar(ii, jj, kk, iatom) * qpt_cart(ii) * qpt_cart(jj)
693              glr(1) = glr(1) + rtmp * (displ_cart(1, kk, iatom, nu) * phre - displ_cart(2, kk, iatom, nu) * phim)
694              glr(2) = glr(2) + rtmp * (displ_cart(2, kk, iatom, nu) * phre + displ_cart(1, kk, iatom, nu) * phre)
695            end do
696          end do
697        end do
698      end do
699      glr = half * (glr / inv_qepsq) * (four_pi / dvdb%cryst%ucvol)
700      values(nu) = (glr(1) ** 2 + glr(2) ** 2) / (two *  phfreqs(nu))
701    end do ! nu
702    write(std_out, "(i0, 4(f9.6), /, (es18.6, 1x))") iq, qpt_red, phfreqs(nu), (values(nu), nu=1, 3*dvdb%natom)
703  end do ! iqpt
704 
705  call qpath%free()
706  return
707 #endif
708 
709  my_rank = xmpi_comm_rank(dvdb%comm)
710  comm = dvdb%comm
711  qpt = dtset%qptn
712 
713  call wrtout(std_out, sjoin(" Writing Delta V_{q,nu)(r) potentials to file:", out_ncpath), do_flush=.True.)
714  call wrtout([std_out, ab_out], sjoin(ch10, "- Results stored in: ", out_ncpath))
715  call wrtout(std_out, sjoin(" Using qpt:", ktoa(qpt)))
716  !call wrtout([std_out, ab_out], " Use `abiopen.py out_V1QAVG.nc -e` to visualize results")
717  call dvdb%print(unit=std_out)
718 
719  ! Define FFT mesh
720  ngfft = dvdb%ngfft
721  nfft = product(ngfft(1:3))
722 
723  if (dtset%eph_task == -16) then
724    call wrtout([std_out, ab_out], " Assuming q-point already in the DVDB file. No interpolation.")
725    interpolated = 0
726 
727  else if (dtset%eph_task == +16) then
728    call wrtout([std_out, ab_out], " Using Fourier interpolation.")
729     comm_rpt = xmpi_comm_self
730     call dvdb%ftinterp_setup(dtset%ddb_ngqpt, qptopt1, 1, dtset%ddb_shiftq, nfft, ngfft, comm_rpt)
731     interpolated = 1
732  else
733    ABI_ERROR(sjoin("Invalid value for eph_task:", itoa(dtset%eph_task)))
734  end if
735 
736  with_lr_model = .True.
737 
738  ! Create netcdf file.
739 #ifdef HAVE_NETCDF
740  if (my_rank == master) then
741    NCF_CHECK(nctk_open_create(ncid, out_ncpath, comm))
742    NCF_CHECK(dvdb%cryst%ncwrite(ncid))
743 
744    ! Add other dimensions.
745    ncerr = nctk_def_dims(ncid, [ &
746      nctkdim_t("nfft", nfft), nctkdim_t("nspden", dvdb%nspden), &
747      nctkdim_t("natom3", 3 * dvdb%cryst%natom)], defmode=.True.)
748    NCF_CHECK(ncerr)
749 
750    ! Define arrays
751    ncerr = nctk_def_arrays(ncid, [ &
752      nctkarr_t("ngfft", "int", "three"), &
753      nctkarr_t("qpt", "dp", "three"), &
754      nctkarr_t("phfreqs", "dp", "natom3"), &
755      nctkarr_t("displ_cart", "dp", "two, natom3, natom3"), &
756      nctkarr_t("v1_qnu", "dp", "two, nfft, nspden, natom3")])
757    NCF_CHECK(ncerr)
758 
759    if (with_lr_model) then
760      NCF_CHECK(nctk_def_arrays(ncid, [nctkarr_t("v1lr_qnu", "dp", "two, nfft, nspden, natom3")]))
761    end if
762 
763    NCF_CHECK(nctk_set_datamode(ncid))
764    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ngfft"), ngfft(1:3)))
765    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "qpt"), qpt))
766  end if
767 #endif
768 
769  ABI_MALLOC(v1_qnu, (2, nfft, dvdb%nspden, dvdb%natom3))
770  if (with_lr_model) then
771    ABI_MALLOC(v1lr_atm, (2, nfft, dvdb%nspden, dvdb%natom3))
772    ABI_MALLOC(v1lr_qnu, (2, nfft, dvdb%nspden, dvdb%natom3))
773  end if
774 
775  ! Get phonon freqs and displacemented for this q-point.
776  call ifc%fourq(dvdb%cryst, qpt, phfreqs, displ_cart, out_displ_red=displ_red)
777 
778  if (interpolated == 0) then
779    ! Find the index of the q-point in the DVDB.
780    db_iqpt = dvdb%findq(qpt)
781    if (db_iqpt /= -1) then
782      ! Read or reconstruct the dvscf potentials for all 3*natom perturbations.
783      ! This call allocates v1scf(cplex, nfft, nspden, 3*natom))
784      call dvdb%readsym_allv1(db_iqpt, cplex, nfft, ngfft, v1scf, comm)
785    else
786      ABI_ERROR(sjoin("Cannot find q-point:", ktoa(qpt), "in DVDB file"))
787    end if
788  else
789 
790    cplex = 2
791    ABI_MALLOC(v1scf, (cplex, nfft, dvdb%nspden, dvdb%my_npert))
792    call dvdb%ftinterp_qpt(qpt, nfft, ngfft, v1scf, dvdb%comm_rpt)
793  end if
794 
795  ! Compute scattering potential in phonon representations instead ot atomic one.
796  ! v1_qnu = \sum_{ka} phdispl{ka}(q,nu) D_{ka,q} V_scf(r)
797  ! NOTE: prefactor 1/sqrt(2 w(q,nu)) is not included in the potentials saved to file.
798  ! v1_qnu(2, nfft, nspden, natom3), v1scf(cplex, nfft, nspden, natom3)
799  call v1atm_to_vqnu(cplex, nfft, dvdb%nspden, dvdb%natom3, v1scf, displ_red, v1_qnu)
800 
801  if (with_lr_model) then
802    ! Compute LR model in the atomic representation then compute phonon representation in v1lr_qnu.
803    v1lr_atm = zero
804    do idir=1,3
805      do ipert=1,dvdb%natom
806        ip = (ipert - 1) * 3 + idir
807        call dvdb%get_v1r_long_range(qpt, idir, ipert, nfft, ngfft, v1lr_atm(:,:,1,ip))
808        if (dvdb%nspden == 2) v1lr_atm(:,:,2,ip) = v1lr_atm(:,:,1,ip)
809      end do
810    end do
811    call v1atm_to_vqnu(2, nfft, dvdb%nspden, dvdb%natom3, v1lr_atm, displ_red, v1lr_qnu)
812  end if
813 
814 #ifdef HAVE_NETCDF
815  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "phfreqs"), phfreqs))
816  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "displ_cart"), displ_cart))
817  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "v1_qnu"), v1_qnu))
818  if (with_lr_model) then
819    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "v1lr_qnu"), v1lr_qnu))
820  end if
821 #endif
822 
823  ABI_FREE(v1scf)
824  ABI_FREE(v1_qnu)
825  ABI_SFREE(v1lr_atm)
826  ABI_SFREE(v1lr_qnu)
827 
828 #ifdef HAVE_NETCDF
829  NCF_CHECK(nf90_close(ncid))
830 #endif
831  call dvdb%close()
832 
833  call wrtout(std_out, "dvqnu file written", do_flush=.True.)
834 
835 end subroutine ncwrite_v1qnu

m_gkk/v1atm_to_vqnu [ Functions ]

[ Top ] [ m_gkk ] [ Functions ]

NAME

  v1atm_to_vqnu

FUNCTION

  Receive potentials in atomic representation and return potential in phonon representation

INPUTS

OUTPUT

SOURCE

853 subroutine v1atm_to_vqnu(cplex, nfft, nspden, natom3, v1_atm, displ_red, v1_qnu)
854 
855 !Arguments ------------------------------------
856 !scalars
857  integer,intent(in) :: cplex, nfft, nspden, natom3
858 !arrays
859  real(dp),intent(in) :: v1_atm(cplex, nfft, nspden, natom3)
860  real(dp),intent(out) :: v1_qnu(2, nfft, nspden, natom3)
861  real(dp),intent(in) :: displ_red(2, natom3, natom3)
862 
863 !Local variables-------------------------------
864 !scalars
865  integer :: nu, ip, ispden
866 
867 !************************************************************************
868 
869  do nu=1,natom3
870    ! v1_qnu = \sum_{ka} phdispl{ka}(q,nu) D_{ka,q} V_scf(r)
871    ! NOTE: prefactor 1/sqrt(2 w(q,nu)) is not included in the potentials saved to file.
872    ! v1_qnu(2, nfft, nspden, natom3), v1_atm(cplex, nfft, nspden, natom3)
873    v1_qnu(:, :, :, nu) = zero
874    do ip=1,natom3
875      do ispden=1,nspden
876        if (cplex == 2) then
877          v1_qnu(1, :, ispden, nu) = v1_qnu(1, :, ispden, nu) + &
878            displ_red(1,ip,nu) * v1_atm(1,:,ispden,ip) - displ_red(2,ip,nu) * v1_atm(2,:,ispden,ip)
879          v1_qnu(2, :, ispden, nu) = v1_qnu(2, :, ispden, nu) + &
880            displ_red(2,ip,nu) * v1_atm(1,:,ispden,ip) + displ_red(1,ip,nu) * v1_atm(2,:,ispden,ip)
881        else
882          ! Gamma point. d(q) = d(-q)* --> d is real.
883          v1_qnu(1, :, ispden, nu) = v1_qnu(1, :, ispden, nu) + displ_red(1,ip,nu) * v1_atm(1,:,ispden,ip)
884        end if
885      end do
886    end do
887  end do
888 
889 end subroutine v1atm_to_vqnu