LCOV - code coverage report
Current view: top level - src/78_eph - m_gkk.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.7 % 294 249
Test Date: 2026-09-21 22:40:37 Functions: 66.7 % 3 2

            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              : !!***
        

Generated by: LCOV version 2.3-1