LCOV - code coverage report
Current view: top level - src/77_ddb - m_iogkk.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 83.1 % 744 618
Test Date: 2026-09-20 15:27:41 Functions: 90.9 % 11 10

            Line data    Source code
       1              : !!****m* ABINIT/m_iogkk
       2              : !! NAME
       3              : !!  m_iogkk
       4              : !!
       5              : !! FUNCTION
       6              : !!  IO routines for GKK files
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 2008-2026 ABINIT group (MVer)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~abinit/COPYING
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! SOURCE
      15              : 
      16              : #if defined HAVE_CONFIG_H
      17              : #include "config.h"
      18              : #endif
      19              : 
      20              : #include "abi_common.h"
      21              : 
      22              : module m_iogkk
      23              : 
      24              :  use defs_basis
      25              :  use defs_elphon
      26              :  use m_errors
      27              :  use m_abicore
      28              :  use m_xmpi
      29              :  use m_krank
      30              :  use m_hdr
      31              : 
      32              :  use defs_abitypes,     only : MPI_type
      33              :  use m_numeric_tools,   only : wrap2_pmhalf
      34              :  use m_io_tools,        only : open_file, get_unit
      35              :  use m_matrix,          only : mati3inv
      36              :  use m_symtk,           only : littlegroup_q
      37              :  use m_geometry,        only : phdispl_cart2red, littlegroup_pert
      38              :  use m_crystal,         only : crystal_t
      39              :  use m_ifc,             only : ifc_type
      40              :  use m_dynmat,          only : d2sym3
      41              :  use m_ebands,          only : ebands_t
      42              : 
      43              :  implicit none
      44              : 
      45              :  private
      46              : !!***
      47              : 
      48              :  public :: read_gkk
      49              :  public :: outgkk
      50              :  public :: read_el_veloc
      51              : !!***
      52              : 
      53              : contains
      54              : !!***
      55              : 
      56              : !!****f* m_iogkk/read_gkk
      57              : !!
      58              : !! NAME
      59              : !! read_gkk
      60              : !!
      61              : !! FUNCTION
      62              : !! This routine reads in elphon matrix elements and completes them
      63              : !! using the appropriate symmetries
      64              : !!
      65              : !! INPUTS
      66              : !!  elph_ds = datastructure containing elphon matrix elements
      67              : !!  Cryst<crystal_t>=Info on the crystal unit cell.
      68              : !!  Ifc<ifc_type>=Object containing the interatomic force constants.
      69              : !!  FSfullpqtofull = mapping of k+q to k
      70              : !!  n1wf = number of 1WF files to be read and analyzed
      71              : !!  nband = number of bands per kpoint
      72              : !!  unitgkk = unit of GKK file for reading
      73              : !!
      74              : !! OUTPUT
      75              : !!  elph_ds = modified gkq
      76              : !!  gkk_qpt = el-ph matrix elements for irreducible qpoints and
      77              : !!    kpoints (as a function of the reduced symmetry for the qpoint)
      78              : !!  gkk_flag = flag array:
      79              : !!       -1 -> element is missing
      80              : !!        0 -> element is from symmetric qpt (Now done in complete_gkk)
      81              : !!        1 -> element is from symmetric pert
      82              : !!        2 -> element is kptsym of gkk file
      83              : !!        3 -> element was read from gkk file
      84              : !!
      85              : !! SOURCE
      86              : 
      87           15 : subroutine read_gkk(elph_ds,Cryst,ifc,Bst,FSfullpqtofull,gkk_flag,n1wf,nband,ep_prt_yambo,unitgkk)
      88              : 
      89              : !Arguments ------------------------------------
      90              : !scalars
      91              :  integer,intent(in) :: n1wf,nband,unitgkk,ep_prt_yambo
      92              :  type(crystal_t),intent(in) :: Cryst
      93              :  type(ifc_type),intent(in) :: ifc
      94              :  type(ebands_t),intent(in) :: Bst
      95              :  type(elph_type),intent(inout) :: elph_ds
      96              : !arrays
      97              :  integer,intent(in) :: FSfullpqtofull(elph_ds%k_phon%nkpt,elph_ds%nqpt_full)
      98              :  integer,intent(out) :: gkk_flag(elph_ds%nbranch,elph_ds%nbranch,elph_ds%k_phon%my_nkpt,elph_ds%nsppol,elph_ds%nqpt_full)
      99              : 
     100              : !Local variables-------------------------------
     101              : !scalars
     102              :  integer :: nsppol,nbranch,nFSband,minFSband,comm,use_sym
     103              :  integer :: fform,i1wf,ikpt_phon,iatom1,iatom2
     104              :  integer :: ib,ib1,ib2,ibb,ibranch,idir,idir1,idir2,ierr,ii,ikpt1
     105              :  integer :: ipert,ipert1,ipert2,iqptirred,iqptfull,isppol,isym1
     106              :  integer :: itim1,jkpt_phon,new
     107              :  integer :: nsym1,qtimrev,syuse
     108              :  integer :: tdonecompl,test_flag,verify
     109              :  integer :: nqptirred_local
     110              :  integer :: master, me
     111              :  integer :: symrankkpt, ikpt1_phon, ik_this_proc
     112              :  real(dp) :: res,ss,timsign
     113              :  character(len=500) :: msg
     114           15 :  type(hdr_type) :: hdr1
     115              : !arrays
     116           30 :  integer :: FSirrtok(3,elph_ds%k_phon%nkpt)
     117           30 :  integer :: symaf1(Cryst%nsym),symq(4,2,Cryst%nsym)
     118           30 :  integer :: symrc1(3,3,Cryst%nsym),symrl1(3,3,Cryst%nsym)
     119           30 :  integer :: tmpflg(3,Cryst%natom+2,3,Cryst%natom+2)
     120           30 :  real(dp) :: displ_cart(2,3*Cryst%natom,3*Cryst%natom)
     121           30 :  real(dp) :: displ_red(2,3*Cryst%natom,3*Cryst%natom)
     122           45 :  real(dp) :: eigvec(2,3*Cryst%natom,3*Cryst%natom),kpt(3),phfrq_tmp(3*Cryst%natom),redkpt(3)
     123           30 :  real(dp) :: qptirred_local(3,n1wf)
     124           30 :  real(dp) :: tnons1(3,Cryst%nsym)
     125           15 :  real(dp),allocatable :: eigen1(:,:,:),gkk_qpt_tmp(:,:,:,:)
     126           15 :  real(dp),allocatable :: h1_mat_el(:,:,:,:,:),h1_mat_el_sq(:,:,:,:,:)
     127           15 :  real(dp),allocatable :: qdata(:,:,:),qdata_tmp(:,:,:,:)
     128              : 
     129              : ! *************************************************************************
     130              : 
     131              :  ABI_UNUSED(Bst%bantot)
     132              : 
     133           15 :  use_sym   = 1
     134           15 :  nsppol    = elph_ds%nsppol
     135           15 :  nbranch   = elph_ds%nbranch
     136           15 :  nFSband   = elph_ds%nFSband
     137           15 :  minFSband = elph_ds%minFSband
     138              : 
     139              : !init values for parallelization
     140           15 :  comm = xmpi_world
     141           15 :  me = xmpi_comm_rank(comm)
     142           15 :  master = 0
     143              : 
     144           90 :  ABI_MALLOC_OR_DIE(h1_mat_el,(2, nFSband**2, nbranch, elph_ds%k_phon%my_nkpt, nsppol), ierr)
     145       572815 :  h1_mat_el= zero
     146              : 
     147           90 :  ABI_MALLOC_OR_DIE(h1_mat_el_sq,(2, nFSband**2, nbranch**2,elph_ds%k_phon%my_nkpt, nsppol), ierr)
     148      2174527 :  h1_mat_el_sq = zero
     149              : 
     150           45 :  ABI_MALLOC(elph_ds%qirredtofull,(elph_ds%nqptirred))
     151              : 
     152              : !MG array to store the e-ph quantities calculated over the input Q-grid
     153           90 :  ABI_MALLOC(qdata_tmp,(elph_ds%nqptirred,nbranch,nsppol,3))
     154          846 :  qdata_tmp=zero
     155              : 
     156           15 :  nqptirred_local=0 !zero number of irred q-points found
     157          735 :  qptirred_local(:,:)=zero
     158              : 
     159       172103 :  gkk_flag = -1
     160              : 
     161           15 :  if (elph_ds%gkqwrite ==0) then
     162      4588187 :    elph_ds%gkk_qpt = zero
     163              : 
     164            1 :  else if (elph_ds%gkqwrite == 1) then
     165            5 :    ABI_MALLOC_OR_DIE(gkk_qpt_tmp,(2,elph_ds%ngkkband**2,nbranch**2,nsppol), ierr)
     166           38 :    gkk_qpt_tmp = zero
     167          193 :    do iqptirred=1,elph_ds%nqptirred*elph_ds%k_phon%nkpt
     168          193 :      write (elph_ds%unitgkq,REC=iqptirred) gkk_qpt_tmp
     169              :    end do
     170            1 :    ABI_FREE(gkk_qpt_tmp)
     171              : 
     172              :  else
     173            0 :    write (msg,'(a,i0)')' Wrong values for gkqwrite = ',elph_ds%gkqwrite
     174            0 :    ABI_BUG(msg)
     175              :  end if !gkqwrite
     176              : 
     177              : !===========================================================
     178              : !Loop over all files we have
     179              : !read in header for perturbation
     180              : !should check that all files are complete, have same header
     181              : !(taking into account the symmetries for the qpoint),
     182              : !represent the correct qpoints ...
     183              : !MG: this task should be performed in mrggkk
     184              : !===========================================================
     185              : 
     186           60 :  ABI_MALLOC(eigen1,(2,nband,nband))
     187          195 :  do i1wf=1,n1wf
     188              : 
     189          180 :    if (master == me) then
     190          180 :      write (msg,'(2a,i4,a,i4)')ch10,' read_gkk : reading 1WF header # ',i1wf,' /',n1wf
     191          180 :      call wrtout(std_out,msg,'COLL')
     192              : 
     193              : !    Could check for compatibility of natom, kpt grids, ecut, qpt with DDB grid...
     194              : !    MG: Also this task should be done in mrggkk
     195              : 
     196          180 :      call hdr1%fort_read(unitgkk, fform)
     197          180 :      if (fform == 0) then
     198            0 :        write (msg,'(a,i0,a)')' 1WF header number ',i1wf,' was mis-read. fform == 0'
     199            0 :        ABI_ERROR(msg)
     200              :      end if
     201              : 
     202          180 :      write(msg,'(a,i4)')' read_gkk : have read 1WF header #',i1wf
     203          180 :      call wrtout(std_out,msg,'COLL')
     204          180 :      write (msg,'(2a,i4,a)')ch10,' read_gkk : # of kpt for this perturbation: ',hdr1%nkpt,ch10
     205          180 :      call wrtout(std_out,msg,'COLL')
     206              : 
     207              :    end if
     208              : 
     209              :    ! broadcast data to all nodes:
     210          180 :    call hdr1%bcast(master, me, comm)
     211              : 
     212              : !  Find qpoint in full grid
     213          180 :    new=1
     214          504 :    do iqptfull=1,elph_ds%nqpt_full
     215         2016 :      kpt(:) = hdr1%qptn(:) - elph_ds%qpt_full(:,iqptfull)
     216          504 :      call wrap2_pmhalf(kpt(1),redkpt(1),res)
     217          504 :      call wrap2_pmhalf(kpt(2),redkpt(2),res)
     218          504 :      call wrap2_pmhalf(kpt(3),redkpt(3),res)
     219          504 :      ss=redkpt(1)**2+redkpt(2)**2+redkpt(3)**2
     220          504 :      if(ss < tol6) then
     221              :        new = 0
     222              :        exit !exit with iqptfull
     223              :      end if
     224              :    end do !iqptfull
     225              : 
     226          180 :    if (new == 1) then
     227              : !    Test should be at the end: dont care if there are additional
     228              : !    qpts in gkk file which are not on the main grid. Ignore them.
     229            0 :      write (msg,'(4a,3es16.6,2a)')ch10,&
     230            0 : &     ' read_gkk : WARNING-  ',ch10,&
     231            0 : &     ' qpoint = ',hdr1%qptn(:),ch10,&
     232            0 : &     ' not found in the input q-grid. Ignoring this point '
     233            0 :      call wrtout(ab_out,msg,'COLL')
     234            0 :      call wrtout(std_out,msg,'COLL')
     235            0 :      if (me == master) then
     236            0 :        do isppol=1,hdr1%nsppol
     237            0 :          do ikpt1=1,hdr1%nkpt
     238            0 :            read(unitgkk) ((eigen1(:,ii,ib),ii=1,nband),ib=1,nband)
     239              :          end do
     240              :        end do
     241              :      end if
     242              : 
     243              :      cycle !cycle the loop on i1wf
     244              :    end if !end if (new ==1)
     245              : 
     246              : 
     247              : !  Check whether other pieces of the DDB have used this qpt already
     248          180 :    new=1
     249          396 :    do iqptirred=1,nqptirred_local
     250         1392 :      kpt(:) = qptirred_local(:,iqptirred) - hdr1%qptn(:)
     251          348 :      call wrap2_pmhalf(kpt(1),redkpt(1),res)
     252          348 :      call wrap2_pmhalf(kpt(2),redkpt(2),res)
     253          348 :      call wrap2_pmhalf(kpt(3),redkpt(3),res)
     254          348 :      ss=redkpt(1)**2+redkpt(2)**2+redkpt(3)**2
     255          396 :      if(ss < tol6) then
     256              :        new=0
     257              :        exit  !MG We can use this information to avoid recalculating the dynamical matrix
     258              :      end if !but we need to use a fixed format in GKK!
     259              :    end do !iqptirred
     260              : 
     261          180 :    if (new==1) then  !we have a new valid irreducible qpoint, add it!
     262           48 :      nqptirred_local = nqptirred_local+1
     263           48 :      if (nqptirred_local > elph_ds%nqptirred) then
     264              :        write (msg, '(a,a,a,i6,i6)') &
     265            0 : &       'found too many qpoints in GKK file wrt anaddb input ', ch10, &
     266            0 : &       'nqpt_anaddb nqpt_gkk = ', elph_ds%nqptirred, nqptirred_local
     267            0 :        ABI_ERROR(msg)
     268              :      end if
     269          192 :      qptirred_local(:,nqptirred_local) = hdr1%qptn(:)
     270           48 :      iqptirred = nqptirred_local
     271           48 :      tdonecompl = 0
     272      1871523 :      h1_mat_el = zero
     273              :    end if
     274              : 
     275              : !  now iqptirred is the index of the present qpoint in the array qptirred_local
     276              : !  and iqptfull is the index in the full qpt_full array for future reference
     277          180 :    elph_ds%qirredtofull(iqptirred) = iqptfull
     278              : 
     279              :    write (msg,'(a,i5,a,3es16.8)')&
     280          180 : &   ' read_gkk : full zone qpt number ',iqptfull,' is ',elph_ds%qpt_full(:,iqptfull)
     281          180 :    call wrtout(std_out,msg,'COLL')
     282              : 
     283              : !  if this perturbation has already been filled (overcomplete gkk)
     284              : !  check only 1st kpoint and spinpol, then check others
     285          180 :    verify = 0
     286          180 :    if (gkk_flag(hdr1%pertcase,hdr1%pertcase,1,1,elph_ds%qirredtofull(iqptirred)) /= -1) then
     287              : !
     288            0 :      do isppol=1,nsppol
     289            0 :        do ik_this_proc=1,elph_ds%k_phon%my_nkpt
     290            0 :          if (gkk_flag(hdr1%pertcase,hdr1%pertcase,ik_this_proc,isppol,elph_ds%qirredtofull(iqptirred)) == -1) then
     291            0 :            write (std_out,*)" hdr1%pertcase,ik_this_proc,iqptirred",hdr1%pertcase,ik_this_proc,iqptirred
     292            0 :            ABI_ERROR('Partially filled perturbation ')
     293              :          end if
     294              :        end do ! ikpt_phon
     295              :      end do ! isppol
     296              : !
     297            0 :      ABI_WARNING(' gkk perturbation is already filled')
     298            0 :      write(std_out,*)' hdr1%pertcase,iqptirred,iqptfull = ',hdr1%pertcase,iqptirred,iqptfull,&
     299            0 : &     gkk_flag(hdr1%pertcase,hdr1%pertcase,1,1,elph_ds%qirredtofull(iqptirred))
     300            0 :      verify = 1
     301            0 :      write (125,*) '# matrix elements for symmetric perturbation'
     302              : !    Instead of reading eigen1 into void, verify == 1 checks them later on wrt values in memory
     303              :    end if !gkk_flag
     304              : 
     305              : !  Examine the symmetries of the q wavevector
     306              : !  these will be used to complete the perturbations for other atoms and idir
     307          180 :    if (ep_prt_yambo==1) then
     308              :      ! If one wants to print GKKs along phonon modes, it mean mixing of
     309              :      ! perturbations with differnt jauge. Symmetries must then be disable.
     310            9 :      call littlegroup_q(Cryst%nsym,qptirred_local(:,iqptirred),symq,Cryst%symrec,Cryst%symafm,qtimrev,prtvol=0,use_sym=0)
     311              :    else
     312          171 :      call littlegroup_q(Cryst%nsym,qptirred_local(:,iqptirred),symq,Cryst%symrec,Cryst%symafm,qtimrev,prtvol=0)
     313              :    end if
     314              : 
     315              :    ! Determine dynamical matrix, phonon frequencies and displacement vector for qpoint
     316              :    !call wrtout(std_out,' read_gkk: calling inpphon to calculate the dynamical matrix','COLL')
     317              : 
     318          180 :    call ifc%fourq(cryst,qptirred_local(:,iqptirred),phfrq_tmp,displ_cart,out_eigvec=eigvec)
     319              : 
     320              : !  Get displacement vectors for all branches in reduced coordinates
     321              : !  used in scalar product with H(1)_atom,idir  matrix elements
     322              : !  Calculate $displ_red = displ_cart \cdot gprimd$ for each phonon branch
     323              : 
     324          180 :    call phdispl_cart2red(Cryst%natom,Cryst%gprimd,displ_cart,displ_red)
     325              : 
     326              : !  prefactors for gk+q,n\prime;k,n matrix element
     327              : !  COMMENT : in decaft there is a weird term in the mass factor, of M-zval(species)
     328              : !  dont know why. Not needed to reproduce decaft results, though...
     329              : !  weight is squared in evaluation of
     330              : !  gamma_{k,q,j} = 2 \pi omega_{q,j} sum_{nu,nu\prime} |g^{q,j}_{k+q,nu\prime; k,nu}|^2
     331              : !  normally cancels with the 2 \pi omega_{q,j} factor in front of the sum...
     332              : 
     333              : !  hdr1%pertcase = idir + (ipert-1)*3 where ipert=iatom in the interesting cases
     334          180 :    idir = mod (hdr1%pertcase-1,3)+1
     335          180 :    ipert = int(dble(hdr1%pertcase-idir)/three)+1
     336              : 
     337          180 :    write (msg,'(4a,i3,a,i3,a,i4,a)')ch10,&
     338          180 : &   ' read_gkk : calling littlegroup_pert to examine the symmetries of the full perturbation ',ch10,&
     339          360 : &   ' idir = ',idir,' ipert = ',ipert,' and Q point = ',iqptirred,ch10
     340          180 :    call wrtout(std_out,msg,'COLL')
     341              : 
     342              : !  Examine the symmetries of the full perturbation these will be used to complete the kpoints
     343              : !  DOESNT USE TIME REVERSAL IN littlegroup_pert except for gamma
     344              : 
     345          180 :    syuse=0
     346              : 
     347              :    call littlegroup_pert(Cryst%gprimd,idir,Cryst%indsym,ab_out,ipert,Cryst%natom,Cryst%nsym,nsym1,2,Cryst%symafm,symaf1,&
     348          180 : &   symq,Cryst%symrec,Cryst%symrel,symrl1,syuse,Cryst%tnons,tnons1)
     349              : 
     350          599 :    do isym1=1,nsym1
     351          599 :      call mati3inv(symrl1(:,:,isym1),symrc1(:,:,isym1))
     352              :    end do
     353        56052 :    FSirrtok = 0
     354              : 
     355              : !  ========================================================
     356              : !  Loop over irred kpts in file, and fill the default gkk
     357              : !  ========================================================
     358              : 
     359              : !  MG NOTE : in the present implementation, if nsppol /=1 the code stops in rchkGSheader!
     360          369 :    do isppol=1,hdr1%nsppol !Loop over spins is trivial? Not tested.
     361          189 :      write (std_out,*) ' read_gkk : isppol = ', isppol
     362              : 
     363        14375 :      do ikpt1=1,hdr1%nkpt   !Loop over irred kpoints, WARNING  nkpt depends on qpoint and symmetry!
     364              : !
     365              : !      this is the main read of the gkk matrix elements from the file (eigen1 arrays)
     366              : !      it has to be done exactly nsppol*nkpt times, and the kpt_phon are completed
     367              : !      where appropriate in the loop below (normally succeeding only once for each kpt)
     368              : !
     369        14006 :        if (master == me) then
     370      1551074 :          read(unitgkk) ((eigen1(:,ii,ib),ii=1,nband),ib=1,nband)
     371              :        end if
     372              : 
     373              : !      MPI broadcast data to all nodes:
     374        14006 :        call xmpi_bcast(eigen1, master, comm, ierr)
     375              : 
     376              : !      find place of irred k in k_phon
     377              : !      the kpoints in the file (kptns) could be ordered arbitrarily
     378        56024 :        symrankkpt = elph_ds%k_phon%krank%get_rank (hdr1%kptns(:,ikpt1)-qptirred_local(:,iqptirred))
     379        14006 :        ikpt1_phon = elph_ds%k_phon%krank%invrank(symrankkpt)
     380        14006 :        if (ikpt1_phon < 0) then
     381            0 :          write (msg,'(a,3es16.6,a)')' irred k ',hdr1%kptns(:,ikpt1),' was not found in full grid'
     382            0 :          ABI_ERROR(msg)
     383              :        end if
     384              : !      find correspondence between this kpt_phon and the others
     385              : !      symrc1 conserves perturbation as well as qpoint
     386              : !      add to FSirrtok list
     387        47006 :        do isym1=1,nsym1
     388        96350 :          do itim1=0,qtimrev
     389        49344 :            timsign=one-two*itim1
     390      1430976 :            kpt(:) = timsign*matmul(symrc1(:,:,isym1), elph_ds%k_phon%kpt(:,ikpt1_phon))
     391              : 
     392        49344 :            symrankkpt = elph_ds%k_phon%krank%get_rank (kpt)
     393        49344 :            jkpt_phon = elph_ds%k_phon%krank%invrank(symrankkpt)
     394              : 
     395        82344 :            if (jkpt_phon > 0) then
     396        49344 :              FSirrtok(1,jkpt_phon) = ikpt1_phon
     397        49344 :              FSirrtok(2,jkpt_phon) = isym1
     398        49344 :              FSirrtok(3,jkpt_phon) = itim1
     399              :            else
     400              :              write (msg,'(a,3es16.6,a,i5,a,i4,a)')&
     401            0 : &             ' sym equivalent of kpt ',hdr1%kptns(:,ikpt1),' by sym ',&
     402            0 : &             isym1,' and itime ',itim1,' was not found'
     403            0 :              ABI_ERROR(msg)
     404              :            end if
     405              :          end do !itim1
     406              :        end do !isim1
     407              : 
     408              : 
     409              :        !
     410              :        !  Here check if the symmetry-copied gkk at new k point is equal to the one found in the file for non-irreducible point
     411              :        !  NB This is DEBUG code
     412              :        !
     413        14006 :        if (verify == 1 .and. elph_ds%k_phon%my_kpt(ikpt1_phon) == me) then
     414            0 :          do ik_this_proc = 1, elph_ds%k_phon%my_nkpt
     415            0 :            if (elph_ds%k_phon%my_ikpt(ik_this_proc) == ikpt1_phon) exit
     416              :          end do
     417            0 :          do ib1=1,nFSband
     418            0 :            do ib2=1,nFSband
     419            0 :              ibb = (ib1-1)*nFSband+ib2
     420            0 :              write (125,'(2(2E16.6,2x))') h1_mat_el(:,ibb,hdr1%pertcase,ik_this_proc,isppol),&
     421            0 : &             eigen1(:,minFSband-1+ib2,minFSband-1+ib1)
     422              :            end do
     423              :          end do
     424              :        end if !verify end DEBUG code
     425              : 
     426              : 
     427      1786457 :        do ik_this_proc = 1, elph_ds%k_phon%my_nkpt
     428              : !        should I be dealing with this k-point?
     429      1758256 :          jkpt_phon = elph_ds%k_phon%my_ikpt(ik_this_proc)
     430              : 
     431              : !        does present ikpt1 contribute to this k-point?
     432      1758256 :          if (FSirrtok(1,jkpt_phon) /= ikpt1_phon) cycle
     433              : 
     434              : !        if this kpoint has already been filled (overcomplete gkk)
     435        36428 :          if (gkk_flag(hdr1%pertcase,hdr1%pertcase,ik_this_proc,isppol,elph_ds%qirredtofull(iqptirred)) /= -1) then
     436        22388 :            ABI_WARNING("gkk element is already filled")
     437        22388 :            write(std_out,*)' hdr1%pertcase,ik_this_proc,isppol,iqptirred = ',&
     438        22388 : &           hdr1%pertcase,ik_this_proc,isppol,iqptirred,&
     439        44776 : &           gkk_flag(hdr1%pertcase,hdr1%pertcase,ik_this_proc,isppol,elph_ds%qirredtofull(iqptirred))
     440              : !           exit
     441              :          end if !gkk_flag
     442              : 
     443              : !        ===============================================================
     444              : !        TODO: if there is a phase factor in swapping k-points, insert it here in copy to h1_mat_el
     445              : !        as a function of symops in FSirrtok
     446              : !        complete gkk for symmetric ikpt_phon with sym1 which conserve
     447              : !        the full perturbation+qpoint
     448              : !        Not tested explicitly, but the results for Pb using reduced kpts look good
     449              : !        should do same RF calculation with nsym=1 and check
     450              : !        ===============================================================
     451              : 
     452              : !        save this kpoint
     453       269924 :          do ib1=1,nFSband
     454      1802356 :            do ib2=1,nFSband
     455      1532432 :              ibb = (ib1-1)*nFSband+ib2
     456              : 
     457              : !            real
     458      1532432 :              res=eigen1(1,minFSband-1+ib2,minFSband-1+ib1)
     459      1532432 :              h1_mat_el(1,ibb,hdr1%pertcase,ik_this_proc,isppol) = res
     460              : 
     461              : !            imag
     462      1532432 :              res=eigen1(2,minFSband-1+ib2,minFSband-1+ib1)
     463      1765928 :              h1_mat_el(2,ibb,hdr1%pertcase,ik_this_proc,isppol) = res
     464              :            end do !ib2
     465              :          end do !ib1
     466              : !        if jkpt is equal to ikpt1_phon (if clause above) flag == 3
     467        50434 :          if (FSirrtok(2,jkpt_phon) == 1) then
     468        11944 :            gkk_flag(hdr1%pertcase,hdr1%pertcase,ik_this_proc,isppol,elph_ds%qirredtofull(iqptirred)) = 3
     469              : !          if jkpt_phon comes from ikpt1_phon flag == 2 with some symop
     470              :          else
     471        24484 :            gkk_flag(hdr1%pertcase,hdr1%pertcase,ik_this_proc,isppol,elph_ds%qirredtofull(iqptirred)) = 2
     472              :          end if
     473              : 
     474              :        end do !jkpt_phon
     475              : 
     476              : !      ===============================================================
     477              : !      we now have contribution to g(k+q,k; \kappa,\alpha) from one
     478              : !      kpoint,and one perturbation,
     479              : !      NB: each perturbation will contribute to all the modes later!
     480              : !
     481              : !      SHOULD ONLY DO THIS FOR THE SYMS NEEDED
     482              : !      TO COMPLETE THE PERTURBATIONS!!!
     483              : !      ================================================================
     484              : 
     485              :      end do !ikpt1
     486              :    end do !isppol
     487              : 
     488              : ! 14 Jan 2014 removed test on verify - in new scheme full BZ is read in and should be used to avoid phase errors
     489              : !   if (verify == 1) cycle
     490              : 
     491              : !  Checks on irred grid provided and on gkk_flag accumulated up to now
     492          180 :    if (elph_ds%tuniformgrid == 1) then  ! check if irred kpoints found reconstitute the FS kpts
     493        14148 :      do ikpt_phon=1,elph_ds%k_phon%nkpt
     494        14148 :        if (FSirrtok(1,ikpt_phon) == 0) then
     495              :          write(msg,'(a,3es16.6,2a)')&
     496            0 : &         ' kpt = ',elph_ds%k_phon%kpt(:,ikpt_phon),ch10,&
     497            0 : &         ' is not the symmetric of one of those found in the GKK file'
     498            0 :          ABI_ERROR(msg)
     499              :        end if
     500              :      end do !ikpt_phon
     501              : 
     502              : !    normally at this point we have used all the gkk for all kpoints on the FS
     503              : !    for the given irred perturbation: check
     504        14148 :      do ik_this_proc = 1, elph_ds%k_phon%my_nkpt
     505        13968 :        ikpt_phon = elph_ds%k_phon%my_ikpt(ik_this_proc)
     506              : 
     507        14148 :        if (gkk_flag(hdr1%pertcase, hdr1%pertcase, ik_this_proc, 1, elph_ds%qirredtofull(iqptirred)) == -1) then
     508              :          write (msg,'(a,i3,a,3es18.6,2a,i3,a,i3,a,3es18.6,a,a,i4,a,a)')&
     509            0 : &         ' For irreducible qpt ', iqptirred,' = ',qptirred_local(:,iqptirred),ch10, &
     510            0 : &         ' the gkk element : pertcase = ',hdr1%pertcase,' ik_this_proc = ',ik_this_proc, &
     511            0 : &         ' kpt = ',elph_ds%k_phon%kpt(:,ikpt_phon),ch10,&
     512            0 : &         ' and isppol ',1,ch10,&
     513            0 : &         ' was not found by symmetry operations on the irreducible kpoints given'
     514            0 :          ABI_ERROR(msg)
     515              :        end if
     516              :      end do !ikpt_phon
     517              :    end if ! end elph_ds%tuniformgrid == 1 checks
     518              : 
     519          180 :    write(msg,'(a,i0)')' read_gkk : Done completing the kpoints for pertcase ',hdr1%pertcase
     520          180 :    call wrtout(std_out,msg,'COLL')
     521              : 
     522        28116 :    tmpflg(:,:,:,:) = 0
     523              : 
     524          720 :    do idir1=1,3
     525         1476 :      do iatom1=1,Cryst%natom
     526          756 :        ipert1 = (iatom1-1)*3+idir1
     527         3564 :        do idir2=1,3
     528         6588 :          do iatom2=1,Cryst%natom
     529         3564 :            ipert2 = (iatom2-1)*3+idir2
     530         3564 :            if (gkk_flag(ipert1,ipert1,1,1,elph_ds%qirredtofull(iqptirred)) >= 0 .and. &
     531         2268 : &           gkk_flag(ipert2,ipert2,1,1,elph_ds%qirredtofull(iqptirred)) >= 0) then
     532         1596 :              tmpflg(idir1,iatom1,idir2,iatom2) = 1
     533              :            end if
     534              :          end do
     535              :        end do
     536              :      end do
     537              :    end do
     538              : 
     539              : 
     540              : !  ===============================================
     541              : !  Full test: need all perturbations explicitly
     542              : !  ===============================================
     543              : 
     544          180 :    test_flag = 0
     545         5940 :    if (sum(tmpflg(:,1:Cryst%natom,:,1:Cryst%natom)) == (3*Cryst%natom)**2 .and. tdonecompl == 0) test_flag = 1
     546              : 
     547          180 :    write(std_out,*)'read_gkk: tdonecompl = ', tdonecompl
     548              : 
     549              : !  de-activate completion of perts by symmetry for now.
     550              : !  Must be called when all irreducible perturbations are in memory!!!!
     551          180 :    if (test_flag == 1 .and. tdonecompl == 0) then
     552              : 
     553              : !    write(std_out,*) ' read_gkk : enter fxgkkphase before completeperts'
     554              : !    call fxgkkphase(elph_ds,gkk_flag,h1_mat_el,iqptirred)
     555              : 
     556           48 :      if (ep_prt_yambo==1) then
     557            3 :        if (elph_ds%k_phon%my_nkpt /= elph_ds%k_phon%nkpt) then
     558            0 :          write (msg, '(a)') 'prt_gkk_yambo can not handle parallel anaddb yet'
     559            0 :          ABI_ERROR(msg)
     560              :        end if
     561              :        call prt_gkk_yambo(displ_cart,displ_red,elph_ds%k_phon%kpt,h1_mat_el,iqptirred,&
     562            3 : &       Cryst%natom,nFSband,elph_ds%k_phon%my_nkpt,phfrq_tmp,hdr1%qptn)
     563              :      end if
     564              : 
     565              : !    ========================================================================
     566              : !    Now use more general symops to complete the other equivalent
     567              : !    perturbations: the kpoints are also shuffled by these symops
     568              : !    afterwards h1_mat_el_sq contains gamma_\tau\alpha,\tau'\alpha' in reduced coordinates
     569              : !
     570              : !    \gamma_{\tau'\alpha',\tau\alpha} =
     571              : !    <psi_{k+q,ib2}| H(1)_{\tau'\alpha'}| psi_{k,ib1}>* \cdot
     572              : !    <psi_{k+q,ib2}| H(1)_{\tau \alpha }| psi_{k,ib1}>
     573              : !
     574              : !    ========================================================================
     575              : 
     576              :      call completeperts(Cryst,nbranch,nFSband,elph_ds%k_phon%my_nkpt,nsppol,&
     577           48 : &     gkk_flag(:,:,:,:,elph_ds%qirredtofull(iqptirred)),h1_mat_el,h1_mat_el_sq,qptirred_local(:,iqptirred),symq,qtimrev)
     578              : 
     579           48 :      tdonecompl = 1
     580              :    end if
     581              : 
     582              : !  ==============================================================
     583              : !  if we have all the perturbations for this qpoint, proceed
     584              : !  with scalar product, norm squared, and add weight factors
     585              : !
     586              : !  SHOULD HAVE A TEST SO h1_mat_el IS NOT OVERWRITTEN
     587              : !  BEFORE PREVIOUS QPOINT IS FINISHED!!!!!
     588              : !  ==============================================================
     589              : 
     590          180 :    test_flag = 1
     591          369 :    do isppol=1,nsppol
     592        14409 :      do ik_this_proc = 1, elph_ds%k_phon%my_nkpt
     593        47493 :        do ibranch=1,nbranch
     594        47304 :          if (gkk_flag (ibranch,ibranch,ik_this_proc,isppol,elph_ds%qirredtofull(iqptirred)) == -1) then
     595              :            test_flag = 0
     596              :            exit
     597              :          end if
     598              :        end do
     599              :      end do
     600              :    end do
     601              : 
     602          180 :    if (test_flag /= 0) then
     603           48 :      call wrtout(std_out,' read_gkk : enter normsq_gkq',"COLL")
     604              : 
     605              : !    MG temporary array to save ph-linewidths before Fourier interpolation
     606          240 :      ABI_MALLOC(qdata,(nbranch,nsppol,3))
     607          912 :      qdata(:,:,:)=zero
     608              : 
     609              :      call normsq_gkq(displ_red,eigvec,elph_ds,FSfullpqtofull,&
     610           48 : &     h1_mat_el_sq,iqptirred,phfrq_tmp,qptirred_local,qdata)
     611              : 
     612              : !    save gkk_qpt, eventually to disk, for bands up to ngkkband,
     613              : !    NB: if the sum over bands has been performed ngkkband is 1 instead of nFSband
     614           48 :      if (elph_ds%gkqwrite == 0) then
     615      4588173 :        elph_ds%gkk_qpt(:,:,:,:,:,iqptirred) = h1_mat_el_sq(:,1:elph_ds%ngkkband*elph_ds%ngkkband,:,:,:)
     616              :      else
     617              : !      write all kpoints to disk
     618            3 :        write (std_out,*) 'size of record to be written: ', 8  * 2*elph_ds%ngkkband*elph_ds%ngkkband*&
     619            6 : &       elph_ds%nbranch*elph_ds%nbranch*elph_ds%k_phon%my_nkpt*elph_ds%nsppol
     620            3 :        inquire(unit=elph_ds%unitgkq, recl=isppol)
     621            3 :        write (std_out,*) 'recl =', isppol
     622            3 :        write (std_out,*) 'iqptirred ', iqptirred
     623          195 :        do ik_this_proc = 1, elph_ds%k_phon%my_nkpt
     624              :          write (elph_ds%unitgkq,REC=((iqptirred-1)*elph_ds%k_phon%my_nkpt+ik_this_proc)) &
     625          195 : &         h1_mat_el_sq(:,1:elph_ds%ngkkband*elph_ds%ngkkband,:,ik_this_proc,:)
     626              :        end do
     627              :      end if
     628              : 
     629          912 :      qdata_tmp(iqptirred,:,:,:)=qdata(:,:,:)
     630           48 :      ABI_FREE(qdata)
     631              :    end if
     632              : 
     633          195 :    call hdr1%free()
     634              : 
     635              :  end do !of i1wf
     636              : 
     637              : !got all the gkk perturbations
     638              : 
     639           15 :  ABI_FREE(eigen1)
     640           15 :  ABI_FREE(h1_mat_el)
     641           15 :  ABI_FREE(h1_mat_el_sq)
     642              : 
     643           15 :  if (nqptirred_local /= elph_ds%nqptirred) then
     644              :    write (msg, '(3a,i0,i0)') &
     645            0 : &   ' Found wrong number of qpoints in GKK file wrt anaddb input ', ch10, &
     646            0 : &   ' nqpt_anaddb nqpt_gkk = ', elph_ds%nqptirred, nqptirred_local
     647            0 :    ABI_ERROR(msg)
     648              :  end if
     649              : 
     650              : !normally at this point we have the gkk for all kpoints on the FS
     651              : !for all the perturbations. Otherwise a 1WF file is missing.
     652              : !NOTE: still havent checked the qpoint grid completeness
     653           63 :  do iqptirred=1,elph_ds%nqptirred
     654          114 :    do isppol=1,nsppol
     655         4203 :      do ik_this_proc = 1, elph_ds%k_phon%my_nkpt
     656         4104 :        ikpt_phon = elph_ds%k_phon%my_ikpt(ik_this_proc)
     657        18195 :        do ipert=1,nbranch
     658        18144 :          if (gkk_flag(ipert,ipert,ik_this_proc,isppol,elph_ds%qirredtofull(iqptirred)) == -1) then
     659              :            write (msg,'(a,i5,1x,i5,1x,i5,1x,i5,a,a)')&
     660            0 : &           ' gkk element',ipert,ikpt_phon,isppol,iqptirred,' was not found by symmetry operations ',&
     661            0 : &           ' on the irreducible perturbations and qpoints given'
     662            0 :            ABI_ERROR(msg)
     663              :          end if
     664              :        end do !ipert
     665              :      end do !ik_this_proc
     666              :    end do !isppol
     667              :  end do !iqptirred
     668              : 
     669           15 :  call wrtout(std_out,'read_gkk : done completing the perturbations (and checked!)','COLL')
     670              : 
     671              : !MG save phonon frequencies, ph-linewidths and lambda(q,n) values before Fourier interpolation
     672           90 :  ABI_MALLOC(elph_ds%qgrid_data,(elph_ds%nqptirred,nbranch,nsppol,3))
     673              : 
     674           63 :  do iqptirred=1,elph_ds%nqptirred
     675          927 :    elph_ds%qgrid_data(iqptirred,:,:,:)=qdata_tmp(iqptirred,:,:,:)
     676              :  end do
     677              : 
     678           15 :  ABI_FREE(qdata_tmp)
     679              : 
     680           15 : end subroutine read_gkk
     681              : !!***
     682              : 
     683              : !!****f* m_iogkk/outgkk
     684              : !! NAME
     685              : !! outgkk
     686              : !!
     687              : !! FUNCTION
     688              : !! output gkk file for one perturbation (used for elphon calculations in anaddb)
     689              : !!
     690              : !! INPUTS
     691              : !!  bantot0 = total number of bands for all kpoints
     692              : !!  bantot1 = total number of matrix elements for 1st order eigenvalues
     693              : !!  eigen0 = GS eigenvalues
     694              : !!  eigen1 = response function 1st order eigenvalue matrix
     695              : !!  hdr0 = GS header
     696              : !!  hdr1 = RF header
     697              : !!  mpi_enreg=information about MPI parallelization
     698              : !!
     699              : !! SOURCE
     700              : 
     701           90 : subroutine outgkk(bantot0,bantot1,outfile,eigen0,eigen1,hdr0,hdr1,mpi_enreg,phasecg)
     702              : 
     703              : !Arguments ------------------------------------
     704              : !scalars
     705              :  integer,intent(in) :: bantot0,bantot1
     706              :  character(len=fnlen),intent(in) :: outfile
     707              :  type(MPI_type),intent(in) :: mpi_enreg
     708              :  type(hdr_type),intent(inout) :: hdr0,hdr1
     709              : !arrays
     710              :  real(dp),intent(in) :: eigen0(bantot0),eigen1(2*bantot1)
     711              :  real(dp),intent(in) :: phasecg(2,bantot1)
     712              : 
     713              : !Local variables-------------------------------
     714              : !scalars
     715              :  integer :: fform,iband,ikpt,isppol,me,ntot,unitout
     716              :  integer :: iband_off, mband, ierr
     717              :  character(len=500) :: msg
     718           90 :  real(dp), allocatable :: tmpeig(:)
     719              : 
     720              : ! *************************************************************************
     721              : 
     722              : !only master should be writing to disk
     723              : !Init me
     724           90 :  me=mpi_enreg%me_kpt
     725           90 :  if (me /= 0) return
     726              : 
     727           90 :  call wrtout(std_out,' writing gkk file: '//outfile,"COLL")
     728              : 
     729              : !initializations
     730           90 :  fform = 42
     731           90 :  ntot = 1
     732              : 
     733              : !open gkk file
     734           90 :  if (open_file(outfile, msg, newunit=unitout, form='unformatted', status='unknown', action="write") /= 0) then
     735            0 :    ABI_ERROR(msg)
     736              :  end if
     737              : 
     738              : !output GS header
     739           90 :  call hdr0%fort_write(unitout, fform, ierr)
     740           90 :  ABI_CHECK(ierr == 0 , "hdr_fort_write returned ierr != 0")
     741              : 
     742              : !output GS eigenvalues
     743           90 :  iband=0
     744          180 :  do isppol=1,hdr0%nsppol
     745         6468 :    do ikpt=1,hdr0%nkpt
     746         6288 :      write (unitout) eigen0(iband+1:iband+hdr0%nband(ikpt))
     747         6378 :      iband=iband+hdr0%nband(ikpt)
     748              :    end do
     749              :  end do
     750              : 
     751              : !output number of gkk in this file (1)
     752           90 :  write (unitout) ntot
     753              : 
     754              : !output RF header
     755           90 :  call hdr1%fort_write(unitout, fform, ierr)
     756           90 :  ABI_CHECK(ierr == 0 , "hdr_fort_write returned ierr != 0")
     757              : 
     758              : !output RF eigenvalues
     759         6378 :  mband = maxval(hdr1%nband(:))
     760          270 :  ABI_MALLOC(tmpeig,(2*mband**2))
     761           90 :  iband_off = 0
     762           90 :  tmpeig(1) = phasecg(1, 1)
     763          180 :  do isppol = 1, hdr1%nsppol
     764         6468 :    do ikpt = 1, hdr1%nkpt
     765      1177488 :      tmpeig = zero
     766       591888 :      do iband = 1, hdr1%nband(ikpt)**2
     767       585600 :        tmpeig (2*(iband-1)+1) = eigen1(2*(iband_off+iband-1)+1)
     768       591888 :        tmpeig (2*(iband-1)+2) = eigen1(2*(iband_off+iband-1)+2)
     769              :      end do
     770         6288 :      write (unitout) tmpeig(1:2*hdr1%nband(ikpt)**2)
     771         6378 :      iband_off = iband_off + hdr1%nband(ikpt)**2
     772              :    end do
     773              :  end do
     774           90 :  ABI_FREE(tmpeig)
     775              : 
     776              : !close gkk file
     777           90 :  close (unitout)
     778              : 
     779              : end subroutine outgkk
     780              : !!***
     781              : 
     782              : !!****f* m_iogkk/prt_gkk_yambo
     783              : !!
     784              : !! NAME
     785              : !! prt_gkk_yambo
     786              : !!
     787              : !! FUNCTION
     788              : !! This routine outputs el-phon related quantities for the yambo code at 1
     789              : !!   q-point
     790              : !!
     791              : !! INPUTS
     792              : !!  displ_cart = phonon displacement vectors for this q-point in Cartesian coordinates.
     793              : !!  displ_red = phonon displacement vectors for this q-point, in reduced coordinates
     794              : !!  elph_ds = datastructure containing elphon matrix elements
     795              : !!  h1_mat_el = matrix elements of first order hamiltonian for present q-point,
     796              : !!     all perturbations
     797              : !!  iqptfull = index of present q-point in full array of q-points
     798              : !!  irredpert = index of irreducible perturbation (atom displaced)
     799              : !!  natom = number of atoms
     800              : !!  phfrq = phonon frequencies at present q-point
     801              : !!  qptn = q-point we will print for
     802              : !!
     803              : !! OUTPUT
     804              : !!  only writes to a file
     805              : !!
     806              : !! NOTES
     807              : !!
     808              : !! SOURCE
     809              : 
     810            3 : subroutine prt_gkk_yambo(displ_cart,displ_red,kpt_phon,h1_mat_el,iqpt,&
     811            3 : &       natom,nFSband,nkpt_phon,phfrq,qptn)
     812              : 
     813              : !Arguments ------------------------------------
     814              : !scalars
     815              :  integer,intent(in) :: natom,iqpt
     816              :  integer,intent(in) :: nFSband,nkpt_phon
     817              :  !arrays
     818              :  real(dp),intent(in) :: kpt_phon(3,nkpt_phon)
     819              :  real(dp),intent(in) :: h1_mat_el(2,nFSband*nFSband,3*natom,nkpt_phon,1)
     820              :  real(dp),intent(in) :: phfrq(3*natom)
     821              :  real(dp),intent(in) :: displ_cart(2,3*natom,3*natom)
     822              :  real(dp),intent(in) :: displ_red(2,3*natom,3*natom)
     823              :  real(dp),intent(in) :: qptn(3)
     824              : 
     825              : !Local variables-------------------------------
     826              :  !scalars
     827              :  integer, save :: firsttime=1
     828              :  integer :: outunit,ikpt,imode,iband,ibandp,iatom,idir,ibandindex
     829              :  integer :: jmode, outunit2, outunit3
     830              :  !arrays
     831              :  real(dp) :: gkk_mode_dep(2)
     832              : ! *************************************************************************
     833              : 
     834              : !if first time round:
     835            3 :  if (firsttime==1) then
     836            1 :    firsttime=0
     837              : !  squash file
     838            1 :    outunit=get_unit()
     839            1 :    open (unit=outunit,file="yambo_elphon_data",status="REPLACE")
     840            1 :    outunit2=get_unit()
     841            1 :    open (unit=outunit2,file="yambo_elphon_gkk_bymode",status="replace")
     842            1 :    outunit3=get_unit()
     843            1 :    open (unit=outunit3,file="yambo_elphon_gkksqtw_bymode",status="replace")
     844              : 
     845              : !  write dimensions
     846            1 :    write (outunit,'(a,I6)') 'number of el atoms ', natom
     847            1 :    write (outunit2,'(a,I6)') 'number of el atoms ', natom
     848            1 :    write (outunit3,'(a,I6)') 'number of el atoms ', natom
     849            1 :    write (outunit,'(a,I6)') 'number of ph modes ', 3*natom
     850            1 :    write (outunit2,'(a,I6)') 'number of ph modes ', 3*natom
     851            1 :    write (outunit3,'(a,I6)') 'number of ph modes ', 3*natom
     852            1 :    write (outunit,'(a,I6)') 'number of el bands ', nFSband
     853            1 :    write (outunit2,'(a,I6)') 'number of el bands ', nFSband
     854            1 :    write (outunit3,'(a,I6)') 'number of el bands ', nFSband
     855              : 
     856              : !  write k-points
     857            1 :    write (outunit,'(a,I6)') 'number of k-points ', nkpt_phon
     858            1 :    write (outunit2,'(a,I6)') 'number of k-points ', nkpt_phon
     859            1 :    write (outunit3,'(a,I6)') 'number of k-points ', nkpt_phon
     860           65 :    do ikpt=1,nkpt_phon
     861           64 :      write (outunit,'(a,I6,3E20.10)') 'reduced coord kpoint no ', ikpt, kpt_phon(:,ikpt)
     862           64 :      write (outunit2,'(a,I6,3E20.10)') 'reduced coord kpoint no ', ikpt, kpt_phon(:,ikpt)
     863           65 :      write (outunit3,'(a,I6,3E20.10)') 'reduced coord kpoint no ', ikpt, kpt_phon(:,ikpt)
     864              :    end do
     865              : 
     866              : !  band energies are not accessible this deep in the code: simpler to get them
     867              : !  from elsewhere
     868              : 
     869            1 :    close (outunit)
     870            1 :    close (outunit2)
     871            1 :    close (outunit3)
     872              :  end if ! first time round
     873              : 
     874              : !open file
     875            3 :  outunit=get_unit()
     876            3 :  open (unit=outunit,file="yambo_elphon_data",status="unknown",position="append")
     877              : 
     878              : !qpoint
     879            3 :  write (outunit,'(a,I6,3E20.10)') 'reduced coord qpoint no ', iqpt, qptn(:)
     880              : 
     881              : !frequencies
     882           12 :  do imode=1,3*natom
     883           12 :    write (outunit,'(a,I6,3E20.10)') 'phonon freq no ', imode, phfrq(imode)
     884              :  end do
     885              : 
     886              : !displacement vector
     887           12 :  do imode=1,3*natom
     888            9 :    write (outunit,'(a,I6,3E20.10)') 'phonon displ vec no ', imode
     889           21 :    do iatom=1,natom
     890           18 :      write (outunit,'(3(2E20.10,2x))') displ_cart(:,(iatom-1)*3+1:iatom*3,imode)
     891              :    end do
     892              :  end do
     893              : 
     894              : !the beef: matrix elements of the first order hamiltonian for displacement of
     895              : !all atoms along all reduced directions
     896            3 :  write (outunit,'(a)') ' matrix elements of all perturbations for this q-point'
     897          195 :  do ikpt=1,nkpt_phon
     898          192 :    write (outunit,'(a,I6)') ' kpoint ', ikpt
     899          192 :    imode=0
     900          387 :    do iatom=1,natom
     901          960 :      do idir=1,3
     902          576 :        imode=imode+1
     903          576 :        write (outunit,'(a,I6,I6)') ' atom, direction = ', iatom,idir
     904          576 :        ibandindex=0
     905         6528 :        do iband=1,nFSband
     906        63936 :          do ibandp=1,nFSband
     907        57600 :            ibandindex=ibandindex+1
     908        57600 :            write (outunit,'(a,I6,I6,2E20.10)') ' mat el for n,np ', iband,ibandp,&
     909       120960 : &           h1_mat_el(:,ibandindex,imode,ikpt,1)
     910              :          end do !bandp
     911              :        end do !band
     912              :      end do !dir
     913              :    end do !atom
     914              :  end do
     915              : 
     916              : !blank line
     917            3 :  write (outunit,*)
     918            3 :  close (outunit)
     919              : 
     920            3 :  outunit2=get_unit()
     921            3 :  open (unit=outunit2,file="yambo_elphon_gkk_bymode",status="unknown",position="append")
     922            3 :  outunit3=get_unit()
     923            3 :  open (unit=outunit3,file="yambo_elphon_gkksqtw_bymode",status="unknown",position="append")
     924              : 
     925              : !qpoint
     926            3 :  write (outunit2,'(a,I6,3E20.10)') 'reduced coord qpoint no ', iqpt, qptn(:)
     927            3 :  write (outunit3,'(a,I6,3E20.10)') 'reduced coord qpoint no ', iqpt, qptn(:)
     928              : 
     929              : !print out mode-dependent matrix elements
     930            3 :  write (outunit2,'(a)') ' matrix elements of all phonon modes for this q-point'
     931            3 :  write (outunit3,'(a)') ' 1/w**1/2 times matrix elements of all phonon modes for this q-point'
     932          195 :  do ikpt=1,nkpt_phon
     933          192 :    write (outunit2,'(a,I6)') ' kpoint ', ikpt
     934          192 :    write (outunit3,'(a,I6)') ' kpoint ', ikpt
     935          192 :    ibandindex=0
     936         2115 :    do iband=1,nFSband
     937        21312 :      do ibandp=1,nFSband
     938        19200 :        ibandindex=ibandindex+1
     939        19200 :        write (outunit2,'(a,I6,I6)') ' el bands n,np ', iband,ibandp
     940        19200 :        write (outunit3,'(a,I6,I6)') ' el bands n,np ', iband,ibandp
     941        78720 :        do imode=1,3*natom
     942              : !        gkk_mode_dep = cg_zdotc(3*natom,displ_red(:,:,imode),h1_mat_el(:,ibandindex,:,ikpt,1))
     943        57600 :          gkk_mode_dep = zero
     944       230400 :          do jmode=1,3*natom
     945              :            gkk_mode_dep(1) = gkk_mode_dep(1) &
     946              : &           + displ_red(1,jmode,imode)*h1_mat_el(1,ibandindex,jmode,ikpt,1) &
     947       172800 : &           + displ_red(2,jmode,imode)*h1_mat_el(2,ibandindex,jmode,ikpt,1)
     948              :            gkk_mode_dep(2) = gkk_mode_dep(2) &
     949              : &           + displ_red(1,jmode,imode)*h1_mat_el(2,ibandindex,jmode,ikpt,1) &
     950       230400 : &           - displ_red(2,jmode,imode)*h1_mat_el(1,ibandindex,jmode,ikpt,1)
     951              :          end do
     952        57600 :          write (outunit2,'(a,I6,2E20.10)') ' mat el for phonon mode num = ', imode, gkk_mode_dep
     953        57600 :          write (outunit3,'(a,I6,2E20.10)') ' 1/w**1/2 * mat el for phonon mode num = ', &
     954       249600 : &         imode, gkk_mode_dep/sqrt(two*abs(phfrq(imode))+tol10)
     955              :        end do !imode
     956              :      end do !bandp
     957              :    end do !band
     958              :  end do
     959              : !blank line
     960            3 :  write (outunit2,*)
     961            3 :  write (outunit3,*)
     962              : 
     963            3 :  close (outunit2)
     964            3 :  close (outunit3)
     965              : 
     966            3 : end subroutine prt_gkk_yambo
     967              : !!***
     968              : 
     969              : !!****f* m_iogkk/read_el_veloc
     970              : !!
     971              : !! NAME
     972              : !! read_el_veloc
     973              : !!
     974              : !! FUNCTION
     975              : !! This routine reads the velocities of the electronic GS
     976              : !! for all kpts and bands
     977              : !! then maps them into the FS kpt states
     978              : !!
     979              : !! COPYRIGHT
     980              : !! Copyright (C) 2002-2026 ABINIT group (JPCroc) based on conducti
     981              : !! This file is distributed under the terms of the
     982              : !! GNU General Public License, see ~abinit/COPYING
     983              : !! or http://www.gnu.org/copyleft/gpl.txt .
     984              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
     985              : !!
     986              : !! INPUTS
     987              : !! nkpt_in = number of kpoints according to parent routine
     988              : !! nband_in = number of bands according to parent routine
     989              : !! nsppol_in = number of spin polarizations
     990              : !!
     991              : !! OUTPUT
     992              : !! el_veloc(nkpt_in,nband_in,3)
     993              : !!
     994              : !! SOURCE
     995              : 
     996            5 : subroutine read_el_veloc(nband_in,nkpt_in,kpt_in,nsppol_in,elph_tr_ds)
     997              : 
     998              : !Arguments -----------------------------------
     999              : !scalars
    1000              :  integer, intent(in) :: nband_in,nkpt_in,nsppol_in
    1001              :  type(elph_tr_type), intent(inout) :: elph_tr_ds
    1002              :  real(dp), intent(in) :: kpt_in(3,nkpt_in)
    1003              : 
    1004              : !Local variables-------------------------------
    1005              : !scalars
    1006              :  integer :: bd2tot_index, iband,ii,ikpt, ikpt_ddk, isppol,l1,mband
    1007              :  integer :: bantot1, unit_ddk, symrankkpt
    1008              :  character(len=fnlen) :: filnam1,filnam2,filnam3
    1009              :  character(len=500) :: msg
    1010            5 :  type(hdr_type) :: hdr1
    1011            5 :  type(krank_t) :: krank
    1012              : !arrays
    1013              :  real(dp) :: im_el_veloc(3)
    1014            5 :  real(dp),allocatable :: eig1_k(:,:), eigen11(:),eigen12(:),eigen13(:)
    1015              : ! *********************************************************************************
    1016              : 
    1017              : !Read data file name
    1018              : !TODO: this should be standardized and read in anaddb always, not
    1019              : !conditionally. Otherwise when new files are added to the anaddb files
    1020              : !file...  Catastrophe!
    1021              : 
    1022            5 :  write(std_out,*)'enter read_el_veloc '
    1023              : 
    1024              : !Read data file
    1025            5 :  if (open_file(elph_tr_ds%ddkfilename,msg,newunit=unit_ddk,form='formatted') /= 0) then
    1026            0 :    ABI_ERROR(msg)
    1027              :  end if
    1028              : 
    1029            5 :  rewind(unit_ddk)
    1030            5 :  read(unit_ddk,'(a)')filnam1       ! first ddk file
    1031            5 :  read(unit_ddk,'(a)')filnam2       ! second ddk file
    1032            5 :  read(unit_ddk,'(a)')filnam3       ! third ddk file
    1033            5 :  close (unit_ddk)
    1034              : 
    1035            5 :  bantot1 = 2*nband_in**2*nkpt_in*nsppol_in
    1036              : 
    1037            5 :  call inpgkk(eigen11,filnam1,hdr1)
    1038            5 :  call hdr1%free()
    1039              : 
    1040            5 :  call inpgkk(eigen12,filnam2,hdr1)
    1041            5 :  call hdr1%free()
    1042              : 
    1043              : !we use the hdr1 from the last call - should add some consistency
    1044              : !testing here, we are trusting users not to mix different ddk files...
    1045            5 :  call inpgkk(eigen13,filnam3,hdr1)
    1046              : 
    1047              : !Extract info from the header
    1048            5 :  if(hdr1%nsppol /= nsppol_in) then
    1049            0 :    ABI_ERROR('nsspol /= input nsppol')
    1050              :  end if
    1051              : 
    1052              : !Get mband, as the maximum value of nband(nkpt)
    1053          429 :  mband=maxval(hdr1%nband(1:hdr1%nkpt))
    1054            5 :  if (mband /= nband_in) then
    1055            0 :    ABI_ERROR('nband_in input to read_el_veloc is inconsistent with mband')
    1056              :  end if
    1057              : 
    1058            5 :  write(std_out,*)
    1059            5 :  write(std_out,*)                     'readings from read_el_veloc header'
    1060            5 :  write(std_out,'(a,i8)')              ' natom                =',hdr1%natom
    1061            5 :  write(std_out,'(a,3i8)')             ' nkpt,nband_in,mband  =',hdr1%nkpt,nband_in,mband
    1062            5 :  write(std_out,'(a, f10.5,a)' )      ' ecut                 =',hdr1%ecut,' Ha'
    1063            5 :  write(std_out,'(a,e15.5,a,e15.5,a)' )' fermie               =',hdr1%fermie,' Ha ',hdr1%fermie*Ha_eV,' eV'
    1064              : 
    1065           20 :  ABI_MALLOC(eig1_k,(2*nband_in**2,3))
    1066            5 :  bd2tot_index = 0
    1067        12793 :  elph_tr_ds%el_veloc=zero
    1068              : 
    1069              : !need correspondence between the DDK kpoints and the kpt_phon
    1070            5 :  call krank%init(hdr1%nkpt, hdr1%kptns)
    1071              : 
    1072           10 :  do isppol=1,nsppol_in
    1073              :    im_el_veloc(:)=zero
    1074          434 :    do ikpt=1,nkpt_in
    1075          424 :     symrankkpt = krank%get_rank (kpt_in(:,ikpt))
    1076          424 :      ikpt_ddk = krank%invrank(symrankkpt)
    1077          424 :      if (ikpt_ddk == -1) then
    1078            0 :        write(std_out,*)'read_el_veloc ******** error in correspondence between ddk and gkk kpoint sets'
    1079            0 :        write(std_out,*)' kpt sets in gkk and ddk files must agree.'
    1080            0 :        ABI_ERROR("Aborting now")
    1081              :      end if
    1082          424 :      bd2tot_index=2*nband_in**2*(ikpt_ddk-1)
    1083              : 
    1084              : !    first derivative eigenvalues for k-point
    1085        84072 :      eig1_k(:,1)=eigen11(1+bd2tot_index:2*nband_in**2+bd2tot_index)
    1086        84072 :      eig1_k(:,2)=eigen12(1+bd2tot_index:2*nband_in**2+bd2tot_index)
    1087        84072 :      eig1_k(:,3)=eigen13(1+bd2tot_index:2*nband_in**2+bd2tot_index)
    1088              : 
    1089              : !    turn el_veloc to cartesian coordinates
    1090         4637 :      do iband=1,nband_in
    1091        17256 :        do l1=1,3
    1092        54704 :          do ii=1,3
    1093              :            elph_tr_ds%el_veloc(ikpt,iband,l1,isppol)=elph_tr_ds%el_veloc(ikpt,iband,l1,isppol)+&
    1094        37872 : &           hdr1%rprimd(l1,ii)*eig1_k(2*iband-1+(iband-1)*2*nband_in,ii)/two_pi
    1095              :            im_el_veloc(l1)=im_el_veloc(l1)+&
    1096        12624 : &           hdr1%rprimd(l1,ii)*eig1_k(2*iband+(iband-1)*2*nband_in,ii)/two_pi
    1097              :          end do
    1098              :        end do ! l1
    1099              :      end do
    1100              :    end do
    1101              :  end do ! end isppol
    1102              : 
    1103            5 :  call krank%free()
    1104            5 :  ABI_FREE(eig1_k)
    1105            5 :  ABI_FREE(eigen11)
    1106            5 :  ABI_FREE(eigen12)
    1107            5 :  ABI_FREE(eigen13)
    1108              : 
    1109            5 :  call hdr1%free()
    1110              : 
    1111            5 :  write(std_out,*)'out of read_el_veloc '
    1112              : 
    1113            5 : end subroutine read_el_veloc
    1114              : !!***
    1115              : 
    1116              : !!****f* m_iogkk/inpgkk
    1117              : !! NAME
    1118              : !! inpgkk
    1119              : !!
    1120              : !! FUNCTION
    1121              : !! read in gkk file and return eigenvalue matrix
    1122              : !! Only works for a single gkk matrix (1 perturbation and qpoint) in the file
    1123              : !! like the files produced by outgkk
    1124              : !!
    1125              : !! INPUTS
    1126              : !!
    1127              : !!  filegkk= filename
    1128              : !!
    1129              : !! OUTPUT
    1130              : !!  eigen1 = response function 1st order eigenvalue matrix
    1131              : !!
    1132              : !! SOURCE
    1133              : 
    1134           15 : subroutine inpgkk(eigen1,filegkk,hdr1)
    1135              : 
    1136              : !Arguments ------------------------------------
    1137              : !scalars
    1138              :  character(len=fnlen),intent(in) :: filegkk
    1139              :  type(hdr_type), intent(out) :: hdr1
    1140              : !arrays
    1141              :  real(dp),allocatable,intent(out) :: eigen1(:)
    1142              : 
    1143              : !Local variables-------------------------------
    1144              : !scalars
    1145              :  integer :: bantot1
    1146              :  integer :: isppol, ikpt, mband, ikb
    1147              :  integer :: unitgkk, fform, ierr, n1wf, i1wf
    1148           15 :  type(hdr_type) :: hdr0
    1149           15 :  real(dp), allocatable :: eigen(:)
    1150              :  character(len=500) :: message
    1151              : 
    1152              : ! *************************************************************************
    1153              : 
    1154           15 :  if (open_file(filegkk,message,newunit=unitgkk,form='unformatted',status='old') /= 0) then
    1155            0 :    ABI_ERROR(message)
    1156              :  end if
    1157              : 
    1158              : !read in header of GS file and eigenvalues
    1159           15 :  call hdr0%fort_read(unitgkk, fform)
    1160           15 :  ABI_CHECK(fform /= 0, "hdr_fort_read returned fform == 0")
    1161              : 
    1162         1287 :  mband = maxval(hdr0%nband(:))
    1163           45 :  ABI_MALLOC(eigen,(mband))
    1164           15 :  call wrtout(std_out,'inpgkk : try to reread GS eigenvalues','COLL')
    1165              : 
    1166           30 :  do isppol=1,hdr0%nsppol
    1167         1302 :    do ikpt=1,hdr0%nkpt
    1168         1272 :      read (unitgkk,IOSTAT=ierr) eigen(1:hdr0%nband(ikpt))
    1169         1287 :      ABI_CHECK(ierr==0,'reading eigen from gkk file')
    1170              :    end do
    1171              :  end do
    1172              : 
    1173           15 :  read(unitgkk,IOSTAT=ierr) n1wf
    1174           15 :  ABI_CHECK(ierr==0,"reading n1wf from gkk file")
    1175              : 
    1176           15 :  ABI_FREE(eigen)
    1177           15 :  call hdr0%free()
    1178              : 
    1179           15 :  if (n1wf > 1) then
    1180              :    write(message,'(3a)')&
    1181            0 : &   'several 1wf records were found in the file,',ch10, &
    1182            0 : &   'which is not allowed for reading with this routine'
    1183            0 :    ABI_ERROR(message)
    1184              :  end if
    1185              : 
    1186              : !read in header of 1WF file
    1187           15 :  call hdr1%fort_read(unitgkk, fform)
    1188           15 :  if (fform == 0) then
    1189            0 :    write(message,'(a,i0,a)')' 1WF header number ',i1wf,' was mis-read. fform == 0'
    1190            0 :    ABI_ERROR(message)
    1191              :  end if
    1192              : 
    1193           15 :  bantot1 = 2*hdr1%nsppol*hdr1%nkpt*mband**2
    1194           45 :  ABI_MALLOC(eigen1, (bantot1))
    1195              : 
    1196              : 
    1197              : !retrieve 1WF <psi_k+q | H | psi_k> from gkk file and echo to output
    1198           15 :  ikb = 0
    1199           30 :  do isppol=1,hdr1%nsppol
    1200         1302 :    do ikpt=1,hdr1%nkpt
    1201         1272 :      read (unitgkk,IOSTAT=ierr) eigen1(ikb+1:ikb+2*hdr1%nband(ikpt)**2)
    1202         1272 :      ikb = ikb + 2*hdr1%nband(ikpt)**2
    1203         1287 :      if (ierr /= 0) then
    1204            0 :        write(message,'(a,2i0)')'reading eigen1 from gkk file, spin, kpt_idx',isppol,ikpt
    1205            0 :        ABI_ERROR(message)
    1206              :      end if
    1207              :    end do
    1208              :  end do
    1209              : 
    1210           15 :  close(unitgkk)
    1211              : 
    1212           15 : end subroutine inpgkk
    1213              : !!***
    1214              : 
    1215              : !!****f* m_iogkk/completeperts
    1216              : !!
    1217              : !! NAME
    1218              : !! completeperts
    1219              : !!
    1220              : !! FUNCTION
    1221              : !!  Complete perturbations wrt atoms and reduced directions
    1222              : !!  for a fixed qpoint. Normally there is a test in read_gkk which guarantees
    1223              : !!  that enough irreducible perturbations are present to generate everything.
    1224              : !!  h1_mat_el is first squared, making a (ipert,jpert) matrix which has the same
    1225              : !!  symmetry properties as the dynamical matrix.
    1226              : !!
    1227              : !! INPUTS
    1228              : !!  Cryst<crystal_t>=Info on the unit cell and symmetries.
    1229              : !!   nbranch=Number of phonon branches.
    1230              : !!   nFSband=Number of bands in H1 matrix elements.
    1231              : !!   nkpt=Number of k-points in matrix elements.
    1232              : !!   nsppol=Number of independent spin polarizations.
    1233              : !!   gkk_flag = flags for presence of gkk matrix elements
    1234              : !!   h1_mat_el = irreducible matrix elements to be completed and squared
    1235              : !!   qpt = qpoint
    1236              : !!   symq = flags for symmetry elements conserving the present qpoint
    1237              : !!   tnons = translation vectors associated with symops
    1238              : !!
    1239              : !! OUTPUT
    1240              : !!   h1_mat_el_sq = irreducible matrix elements squared and completed
    1241              : !!   gkk_flag = changed on output
    1242              : !!
    1243              : !! SOURCE
    1244              : 
    1245           48 : subroutine completeperts(Cryst,nbranch,nFSband,nkpt,nsppol,gkk_flag,h1_mat_el,h1_mat_el_sq,&
    1246           48 : &   qpt,symq,qtimrev)
    1247              : 
    1248              : !Arguments ------------------------------------
    1249              : !scalars
    1250              :  integer,intent(in) :: qtimrev,nbranch,nFSband,nkpt,nsppol
    1251              :  type(crystal_t),intent(in) :: Cryst
    1252              : !arrays
    1253              :  integer,intent(in) :: symq(4,2,Cryst%nsym)
    1254              :  integer,intent(inout) :: gkk_flag(nbranch,nbranch,nkpt,nsppol)
    1255              :  real(dp),intent(in) :: qpt(3)
    1256              :  real(dp),intent(in) :: h1_mat_el(2,nFSband**2,nbranch,nkpt,nsppol)
    1257              :  real(dp),intent(out) :: h1_mat_el_sq(2,nFSband**2,nbranch**2,nkpt,nsppol)
    1258              : 
    1259              : !Local variables-------------------------------
    1260              : !scalars
    1261              :  integer :: ikpt_phon,iatom1,iatom2,ibb,idir1,idir2,ipert1,ipert2,isppol,mpert,natom
    1262              :  real(dp) :: im1,im2,re1,re2,res
    1263              :  character(len=500) :: msg
    1264              : !arrays
    1265              :  integer,allocatable :: tmpflg(:,:,:,:)
    1266           48 :  real(dp),allocatable :: tmpval(:,:,:,:,:)
    1267              : 
    1268              : ! *************************************************************************
    1269              : 
    1270              : !WARNING! Stupid patch in d2sym3 imposes these matrices to have size natom+2
    1271           48 :  natom = Cryst%natom
    1272           48 :  mpert = natom+2
    1273              : 
    1274          240 :  ABI_MALLOC(tmpflg,(3,mpert,3,mpert))
    1275          240 :  ABI_MALLOC(tmpval,(2,3,mpert,3,mpert))
    1276              : 
    1277      7441299 :  h1_mat_el_sq = zero
    1278              : 
    1279          288 :  write (std_out,*) ' completeperts: shape(h1_mat_el_sq) = ', shape(h1_mat_el_sq)
    1280              : 
    1281           99 :  do isppol=1,nsppol
    1282           51 :    write(std_out,*)'completeperts: isppol = ', isppol
    1283              : !
    1284         4203 :    do ikpt_phon=1,nkpt
    1285       176232 :      do ibb=1,nFSband**2
    1286              : !
    1287     55943712 :        tmpval = zero
    1288     23801184 :        tmpflg = 0
    1289              :        ! for a fixed k (q) band and sppol construct the gamma matrix for (3 natom)^2 perturbation pairs
    1290       378048 :        do iatom1=1,natom
    1291       995808 :          do idir1=1,3
    1292       617760 :            ipert1 = (iatom1-1)*3+idir1
    1293       617760 :            if (gkk_flag(ipert1,ipert1,ikpt_phon,isppol) < 0) cycle
    1294       617760 :            re1 = h1_mat_el(1,ibb,ipert1,ikpt_phon,isppol)
    1295       617760 :            im1 = h1_mat_el(2,ibb,ipert1,ikpt_phon,isppol)
    1296              : 
    1297      1644192 :            do iatom2=1,natom
    1298      3899808 :              do idir2=1,3
    1299      2461536 :                ipert2 = (iatom2-1)*3+idir2
    1300      2461536 :                if (gkk_flag(ipert2,ipert2,ikpt_phon,isppol) < 0) cycle
    1301      2461536 :                tmpflg(idir1,iatom1,idir2,iatom2) = 1
    1302      2461536 :                re2 = h1_mat_el(1,ibb,ipert2,ikpt_phon,isppol)
    1303      2461536 :                im2 = h1_mat_el(2,ibb,ipert2,ikpt_phon,isppol)
    1304              : !
    1305              : !              conjg(h1_mat_el_2) * h1_mat_el_1
    1306      2461536 :                res =  re1*re2 + im1*im2
    1307      2461536 :                tmpval(1,idir1,iatom1,idir2,iatom2) =  res
    1308      2461536 :                res =  re1*im2 - im1*re2
    1309      3282048 :                tmpval(2,idir1,iatom1,idir2,iatom2) = res
    1310              : 
    1311              :              end do !idir2
    1312              :            end do !iatom2
    1313              :          end do !idir1
    1314              :        end do !iatom1
    1315              : 
    1316              :        ! matrix is symmetrized like a dynamical matrix. No change of band or k
    1317              :        !  in here. This should be checked (if we have to restrict further the symmetry operations)
    1318       172128 :        call d2sym3(tmpflg,tmpval,Cryst%indsym,mpert,natom,Cryst%nsym,qpt,symq,Cryst%symrec,Cryst%symrel,qtimrev,1)
    1319      4277856 :        if (sum(tmpflg(:,1:natom,:,1:natom)) /= 3*natom*3*natom) then
    1320              :          write(msg,'(3a,4i0)')&
    1321            0 : &         'A perturbation is missing after completion with d2sym3',ch10,&
    1322            0 : &         'tmpflg, ikpt_phon, isppol: ',tmpflg,ikpt_phon,isppol
    1323            0 :          ABI_ERROR(msg)
    1324              :        end if
    1325              : !
    1326              : !      Save values for calculation of |gkk|^2
    1327       382152 :        do iatom1=1,natom
    1328       995808 :          do idir1=1,3
    1329       617760 :            ipert1 = (iatom1-1)*3+idir1
    1330      1644192 :            do iatom2=1,natom
    1331      3899808 :              do idir2=1,3
    1332              : !
    1333              : !              mjv 29/10/2007 ipert2 now contains the composite index ip1*nperts+ip2
    1334      2461536 :                ipert2 = (iatom2-1)*3 + idir2 + (ipert1-1)*3*natom
    1335      2461536 :                h1_mat_el_sq(1,ibb,ipert2,ikpt_phon,isppol) = pi*tmpval(1,idir2,iatom2,idir1,iatom1)
    1336      3282048 :                h1_mat_el_sq(2,ibb,ipert2,ikpt_phon,isppol) = pi*tmpval(2,idir2,iatom2,idir1,iatom1)
    1337              :              end do
    1338              :            end do
    1339              :          end do
    1340              :        end do
    1341              : !
    1342              :      end do !end ibb band dos
    1343              : !
    1344              : !    Set flags.
    1345        18195 :      do ipert1=1,3*natom
    1346        70632 :        do ipert2=1,3*natom
    1347        66528 :          if (gkk_flag(ipert2,ipert1,ikpt_phon,isppol) < 0) gkk_flag(ipert2,ipert1,ikpt_phon,isppol) = 1
    1348              :        end do
    1349              :      end do
    1350              : 
    1351              :    end do !end kpt_phon do
    1352              :  end do !end sppol do
    1353              : 
    1354           48 :  ABI_FREE(tmpflg)
    1355           48 :  ABI_FREE(tmpval)
    1356              : 
    1357           48 : end subroutine completeperts
    1358              : !!***
    1359              : 
    1360              : !!****f* ABINIT/normsq_gkq
    1361              : !!
    1362              : !! NAME
    1363              : !! normsq_gkq
    1364              : !!
    1365              : !! FUNCTION
    1366              : !! This routine takes the gkq matrix elements for a given qpoint,
    1367              : !!   does the scalar product with the phonon displacement vector,
    1368              : !!   squares the gkq matrix elements multiplies by the appropriate weights
    1369              : !!   and puts them in a uniform (atom,icart) basis
    1370              : !!
    1371              : !! INPUTS
    1372              : !!   displ_red = phonon mode displacement vectors in reduced coordinated.
    1373              : !!   eigvec = eigenvectors of phonons (to turn to cartesian coord frame)
    1374              : !!   elph_ds = datastructure with gkk matrix elements
    1375              : !!   FSfullpqtofull = mapping of k + q to k
    1376              : !!   h1_mat_el_sq = matrix elements $<psi_{k+q,m} | H^{1} | psi_{k,n}>$ matrix-squared
    1377              : !!   iqptirred = index of present qpoint
    1378              : !!   phfrq_tmp = phonon frequencies
    1379              : !!   qpt_irred = array of qpoint coordinates
    1380              : !!
    1381              : !! OUTPUT
    1382              : !!   elph_ds%gkq filled
    1383              : !!   qdata(elph_ds%nbranch,elph_ds%nsppol,3) = array containing the phonon frequency, the linewidth and $\lambda_{q,\nu}$.
    1384              : !!
    1385              : !! SOURCE
    1386              : 
    1387           48 : subroutine normsq_gkq(displ_red,eigvec,elph_ds,FSfullpqtofull,&
    1388           48 : &    h1_mat_el_sq,iqptirred,phfrq_tmp,qpt_irred,qdata)
    1389              : 
    1390              : !Arguments ------------------------------------
    1391              : !scalars
    1392              :  integer,intent(in) :: iqptirred
    1393              :  type(elph_type),intent(inout) :: elph_ds
    1394              : !arrays
    1395              :  integer,intent(in) :: FSfullpqtofull(elph_ds%k_phon%nkpt,elph_ds%nqpt_full)
    1396              :  real(dp),intent(in) :: displ_red(2,elph_ds%nbranch,elph_ds%nbranch)
    1397              :  real(dp),intent(in) :: eigvec(2,elph_ds%nbranch,elph_ds%nbranch)
    1398              :  real(dp),intent(inout) :: &
    1399              : & h1_mat_el_sq(2,elph_ds%nFSband*elph_ds%nFSband,elph_ds%nbranch*elph_ds%nbranch,elph_ds%k_phon%my_nkpt,elph_ds%nsppol)
    1400              :  real(dp),intent(in) :: phfrq_tmp(elph_ds%nbranch),qpt_irred(3,elph_ds%nqptirred)
    1401              :  real(dp),intent(out) :: qdata(elph_ds%nbranch,elph_ds%nsppol,3)
    1402              : 
    1403              : !Local variables-------------------------------
    1404              : !scalars
    1405              :  integer :: i1,i2,ier,ii,isppol,jbranch,comm
    1406              :  real(dp) :: lambda_tot
    1407              :  character(len=500) :: message
    1408              : !arrays
    1409           96 :  real(dp) :: accum_mat(2,elph_ds%nbranch,elph_ds%nbranch,elph_ds%nsppol)
    1410           96 :  real(dp) :: accum_mat2(2,elph_ds%nbranch,elph_ds%nbranch,elph_ds%nsppol)
    1411           96 :  real(dp) :: gam_now2(2,elph_ds%nbranch,elph_ds%nbranch)
    1412           96 :  real(dp) :: lambda(elph_ds%nsppol)
    1413           48 :  real(dp),allocatable :: matrx(:,:),val(:),vec(:,:,:)
    1414           48 :  real(dp),allocatable :: zhpev1(:,:),zhpev2(:)
    1415              : 
    1416              : ! *************************************************************************
    1417              : 
    1418              :  DBG_ENTER("COLL")
    1419              : 
    1420         2637 :  accum_mat  = zero
    1421         2637 :  accum_mat2 = zero
    1422           48 :  comm = xmpi_world
    1423              : 
    1424           48 :  if (elph_ds%ep_scalprod == 1) then
    1425              : !
    1426           15 :    if (elph_ds%ep_keepbands == 0) then
    1427            0 :      call wrtout(std_out,' normsq_gkq : calling nmsq_gam_sumFS',"COLL")
    1428              :      call nmsq_gam_sumFS (accum_mat,accum_mat2,displ_red,eigvec,elph_ds,FSfullpqtofull,&
    1429            0 : &     h1_mat_el_sq,iqptirred)
    1430              : 
    1431           15 :    else if (elph_ds%ep_keepbands == 1) then
    1432           15 :      call wrtout(std_out,' normsq_gkq : calling nmsq_gam',"COLL")
    1433              :      call nmsq_gam (accum_mat,accum_mat2,displ_red,eigvec,elph_ds,FSfullpqtofull,&
    1434           15 : &     h1_mat_el_sq,iqptirred)
    1435              : 
    1436              :    else
    1437            0 :      write (message,'(a,i0)')' Wrong value for elph_ds%ep_keepbands = ',elph_ds%ep_keepbands
    1438            0 :      ABI_BUG(message)
    1439              :    end if
    1440              : !
    1441           33 :  else if (elph_ds%ep_scalprod == 0) then  ! Interpolate on the pure "matrix of matrix elements" and do the scalar products later.
    1442              : !
    1443           33 :    if (elph_ds%ep_keepbands == 0) then
    1444           30 :      call wrtout(std_out,' normsq_gkq : calling nmsq_pure_gkk_sumFS',"COLL")
    1445              :      call nmsq_pure_gkk_sumFS (accum_mat,accum_mat2,displ_red,elph_ds,FSfullpqtofull,&
    1446           30 : &     h1_mat_el_sq,iqptirred)
    1447              : 
    1448            3 :    else if (elph_ds%ep_keepbands == 1) then
    1449            3 :      call wrtout(std_out,' normsq_gkq : calling nmsq_pure_gkk',"COLL")
    1450              : 
    1451              :      call nmsq_pure_gkk (accum_mat,accum_mat2,displ_red,elph_ds,FSfullpqtofull,&
    1452            3 : &     h1_mat_el_sq,iqptirred)
    1453              :    else
    1454            0 :      write (message,'(a,i0)')' Wrong value for elph_ds%ep_keepbands = ',elph_ds%ep_keepbands
    1455            0 :      ABI_BUG(message)
    1456              :    end if
    1457              : !
    1458              :  else
    1459            0 :    write (message,'(a,i0)')' Wrong value for elph_ds%ep_scalprod = ',elph_ds%ep_scalprod
    1460            0 :    ABI_BUG(message)
    1461              :  end if
    1462              : !end if flag for doing scalar product now.
    1463              : 
    1464              : 
    1465              : !MG: values without the good prefactor
    1466         2637 :  accum_mat = accum_mat * elph_ds%occ_factor/elph_ds%k_phon%nkpt
    1467              : 
    1468              : !MG: accum_mat2 contains the line-widhts before the Fourier interpolation
    1469         2637 :  accum_mat2 = accum_mat2 * elph_ds%occ_factor/elph_ds%k_phon%nkpt
    1470              : 
    1471              : !mpi sum over procs for accum_mat2
    1472           48 :  call xmpi_sum (accum_mat, comm, ier)
    1473           48 :  call xmpi_sum (accum_mat2, comm, ier)
    1474              : 
    1475              : !MG20060531i
    1476              : !write e-ph quantities before Fourier interpolation
    1477              : !save e-ph values in the temporary array qdata that will be copied into elph_ds%qgrid_data
    1478              : 
    1479           48 :  write (message,'(4a,3es16.6,63a)')ch10,                  &
    1480           48 : & ' Phonon linewidths before interpolation ',ch10,        &
    1481         2976 : & ' Q point = ',qpt_irred(:,iqptirred),ch10,('=',ii=1,60),ch10,&
    1482         3024 : & ' Mode          Frequency (Ha)  Linewidth (Ha)  Lambda '
    1483           48 :  call wrtout(std_out,message,'COLL')
    1484              : 
    1485           48 :  lambda_tot = zero
    1486           99 :  do isppol=1,elph_ds%nsppol
    1487          288 :    do ii=1,elph_ds%nbranch
    1488          189 :      lambda(isppol)=zero
    1489              : !    MG: the tolerance factor is somehow arbitrary
    1490          189 :      if (abs(phfrq_tmp(ii)) > tol10) lambda(isppol)=accum_mat2(1,ii,ii,isppol)/&
    1491          141 : &     (pi*elph_ds%n0(isppol)*phfrq_tmp(ii)**2)
    1492          189 :      lambda_tot=lambda_tot+lambda(isppol)
    1493          189 :      write(message,'(i8,es20.6,2es16.6)' )ii,phfrq_tmp(ii),accum_mat2(1,ii,ii,isppol),lambda(isppol)
    1494          189 :      call wrtout(std_out,message,'COLL')
    1495              : !    save values
    1496          189 :      qdata(ii,isppol,1)=phfrq_tmp(ii)
    1497          189 :      qdata(ii,isppol,2)=accum_mat2(1,ii,ii,isppol)
    1498          240 :      qdata(ii,isppol,3)=lambda(isppol)
    1499              :    end do !loop over branch
    1500              :  end do !loop over sppol
    1501              : 
    1502              : !normalize for number of spins
    1503           48 :  lambda_tot = lambda_tot / elph_ds%nsppol
    1504              : 
    1505         5808 :  write(message,'(61a,44x,es16.6,62a)' )('=',ii=1,60),ch10,lambda_tot,ch10,('=',ii=1,60),ch10
    1506           48 :  call wrtout(std_out,message,'COLL')
    1507              : !ENDMG20060531
    1508              : 
    1509              : !immediately calculate linewidths:
    1510           48 :  write(std_out,*) 'summed accum_mat = '
    1511           48 :  write(std_out,'(3(2E18.6,1x))') accum_mat(:,:,:,1)
    1512           48 :  write(std_out,*) 'summed accum_mat2 = '
    1513          228 :  write(std_out,'(3(2E18.6,1x))')  (accum_mat2(:,ii,ii,1),ii=1,elph_ds%nbranch)
    1514           48 :  write(std_out,*) 'displ_red  = '
    1515           48 :  write(std_out,'(3(2E18.6,1x))') displ_red
    1516              : 
    1517           48 :  if (elph_ds%ep_scalprod == 1) then
    1518           30 :    do isppol=1,elph_ds%nsppol
    1519              : !    Diagonalize gamma matrix at qpoint (complex matrix). Copied from dfpt_phfrq
    1520           15 :      ier=0
    1521           15 :      ii=1
    1522           45 :      ABI_MALLOC(matrx,(2,(elph_ds%nbranch*(elph_ds%nbranch+1))/2))
    1523           96 :      do i2=1,elph_ds%nbranch
    1524          366 :        do i1=1,i2
    1525          270 :          matrx(1,ii)=accum_mat2(1,i1,i2,isppol)
    1526          270 :          matrx(2,ii)=accum_mat2(2,i1,i2,isppol)
    1527          351 :          ii=ii+1
    1528              :        end do
    1529              :      end do
    1530           45 :      ABI_MALLOC(zhpev1,(2,2*elph_ds%nbranch-1))
    1531           45 :      ABI_MALLOC(zhpev2,(3*elph_ds%nbranch-2))
    1532           45 :      ABI_MALLOC(val,(elph_ds%nbranch))
    1533           60 :      ABI_MALLOC(vec,(2,elph_ds%nbranch,elph_ds%nbranch))
    1534           15 :      call ZHPEV ('V','U',elph_ds%nbranch,matrx,val,vec,elph_ds%nbranch,zhpev1,zhpev2,ier)
    1535              : 
    1536           15 :      write (std_out,*) ' normsq_gkq : accumulated eigenvalues isppol ',isppol, ' = '
    1537           15 :      write (std_out,'(3E18.6)') val
    1538           15 :      ABI_FREE(matrx)
    1539           15 :      ABI_FREE(zhpev1)
    1540           15 :      ABI_FREE(zhpev2)
    1541           15 :      ABI_FREE(vec)
    1542           30 :      ABI_FREE(val)
    1543              :    end do ! isppol
    1544              : 
    1545           33 :  else if (elph_ds%ep_scalprod == 0) then
    1546              : 
    1547              : 
    1548           69 :    do isppol=1,elph_ds%nsppol
    1549           36 :      call gam_mult_displ(elph_ds%nbranch, displ_red, accum_mat(:,:,:,isppol), gam_now2)
    1550              : 
    1551           36 :      write (std_out,*) ' normsq_gkq : accumulated eigenvalues isppol ', isppol, ' = '
    1552          144 :      write (std_out,'(3(E14.6,1x))') (gam_now2(1,jbranch,jbranch), jbranch=1,elph_ds%nbranch)
    1553           36 :      write (std_out,*) ' normsq_gkq : imag part = '
    1554          177 :      write (std_out,'(3(E14.6,1x))') (gam_now2(2,jbranch,jbranch), jbranch=1,elph_ds%nbranch)
    1555              :    end do ! isppol
    1556              : 
    1557              :  end if
    1558              : 
    1559              :  DBG_EXIT("COLL")
    1560              : 
    1561           48 : end subroutine normsq_gkq
    1562              : !!***
    1563              : 
    1564              : !!****f* ABINIT/nmsq_gam
    1565              : !!
    1566              : !! NAME
    1567              : !! nmsq_gam
    1568              : !!
    1569              : !! FUNCTION
    1570              : !!  Calculate gamma matrices keeping full dependence on bands
    1571              : !!  from original h1_mat_el_sq matrix elements (no averaging over
    1572              : !!  bands near the Fermi surface)
    1573              : !!
    1574              : !! INPUTS
    1575              : !!   displ_red = phonon mode displacement vectors, post-multiplied by gprim matrix
    1576              : !!     (ie. turned to reduced coordinates)
    1577              : !!   eigvec = phonon eigenvectors
    1578              : !!   elph_ds = datastructure with gkk matrix elements
    1579              : !!   FSfullpqtofull = mapping of k+q to k
    1580              : !!   kpt_phon = coordinates of kpoints near to FS
    1581              : !!   h1_mat_el_sq = matrix elements $<psi_{k+q,m} | H^{1} | psi_{k,n}>$ squared
    1582              : !!   iqptirred = index of present qpoint
    1583              : !!
    1584              : !! OUTPUT
    1585              : !!   accum_mat = matrix for accumulating FS average of gkk (gamma matrix -> linewidths)
    1586              : !!   accum_mat2 = matrix for accumulating FS average of gamma matrix with good prefactors
    1587              : !!
    1588              : !! SOURCE
    1589              : 
    1590           15 : subroutine nmsq_gam (accum_mat,accum_mat2,displ_red,eigvec,elph_ds,FSfullpqtofull,&
    1591           15 : &  h1_mat_el_sq,iqptirred)
    1592              : 
    1593              : !Arguments ------------------------------------
    1594              : !scalars
    1595              :  integer,intent(in) :: iqptirred
    1596              :  type(elph_type),intent(inout) :: elph_ds
    1597              : !arrays
    1598              :  integer,intent(in) :: FSfullpqtofull(elph_ds%k_phon%nkpt,elph_ds%nqpt_full)
    1599              :  real(dp),intent(in) :: displ_red(2,elph_ds%nbranch,elph_ds%nbranch)
    1600              :  real(dp),intent(in) :: eigvec(2,elph_ds%nbranch,elph_ds%nbranch)
    1601              :  real(dp),intent(inout) :: &
    1602              : & h1_mat_el_sq(2,elph_ds%nFSband*elph_ds%nFSband,elph_ds%nbranch*elph_ds%nbranch,elph_ds%k_phon%my_nkpt,elph_ds%nsppol)
    1603              :  real(dp),intent(inout) :: accum_mat(2,elph_ds%nbranch,elph_ds%nbranch,elph_ds%nsppol)
    1604              :  real(dp),intent(inout) :: accum_mat2(2,elph_ds%nbranch,elph_ds%nbranch,elph_ds%nsppol)
    1605              : 
    1606              : !Local variables-------------------------------
    1607              : ! tmp variables for diagonalization
    1608              : !scalars
    1609              :  integer :: ikpt_phon,ikpt_phonq,ib1,ib2,ibeff,ibranch,isppol,ipert1
    1610              :  integer :: jbranch
    1611              :  integer :: iqpt_fullbz
    1612              :  integer :: ik_this_proc
    1613              :  real(dp) :: sd1,sd2
    1614              :  character(len=500) :: message
    1615              : !arrays
    1616           30 :  real(dp) :: gkq_1band(2,elph_ds%nbranch,elph_ds%nbranch)
    1617           30 :  real(dp) :: tmp_mat2(2,elph_ds%nbranch,elph_ds%nbranch)
    1618           30 :  real(dp) :: zgemm_tmp_mat(2,elph_ds%nbranch,elph_ds%nbranch)
    1619              : 
    1620              : ! *************************************************************************
    1621              : 
    1622           15 :  if (elph_ds%ep_keepbands == 0) then
    1623            0 :    write (message,'(a,i0)')' elph_ds%ep_keepbands should be 1 while is ',elph_ds%ep_keepbands
    1624            0 :    ABI_ERROR(message)
    1625              :  end if
    1626              : 
    1627              : !MG20060603 NOTE:
    1628              : !accum_mat and accum_mat2 are real, the imaginary part is used for debugging purpose
    1629              : !accum_mat2 is used to store the phonon-linewidhts before interpolation
    1630              : 
    1631           15 :  iqpt_fullbz = elph_ds%qirredtofull(iqptirred)
    1632           15 :  write(std_out,*) 'nmsq_gam : iqptirred = ', iqptirred
    1633              : 
    1634           30 :  do isppol=1,elph_ds%nsppol
    1635          798 :    do ik_this_proc =1, elph_ds%k_phon%my_nkpt
    1636          768 :      ikpt_phon = elph_ds%k_phon%my_ikpt(ik_this_proc)
    1637              : 
    1638          768 :      ikpt_phonq = FSfullpqtofull(ikpt_phon,iqpt_fullbz)
    1639              : 
    1640         6287 :      do ib1=1,elph_ds%nFSband
    1641         5504 :        sd1 = elph_ds%k_phon%wtk(ib1,ikpt_phon,isppol) !weights for distance from the fermi surface
    1642              : 
    1643        46976 :        do ib2=1,elph_ds%nFSband
    1644        40704 :          sd2 = elph_ds%k_phon%wtk(ib2,ikpt_phonq,isppol) !weights for distance from the fermi surface
    1645        40704 :          ibeff = ib2+elph_ds%nFSband*(ib1-1)
    1646              : 
    1647      4100352 :          gkq_1band(:,:,:) = zero
    1648              : 
    1649       162816 :          zgemm_tmp_mat= reshape (h1_mat_el_sq(:,ibeff,:,ik_this_proc,isppol),(/2,elph_ds%nbranch,elph_ds%nbranch/))
    1650              : 
    1651        40704 :          call gam_mult_displ(elph_ds%nbranch, displ_red, zgemm_tmp_mat, tmp_mat2)
    1652              : 
    1653              : !        sum over bands
    1654       264192 :          do ipert1=1,elph_ds%nbranch
    1655       264192 :            gkq_1band(1,ipert1,ipert1) = gkq_1band(1,ipert1,ipert1) + tmp_mat2(1,ipert1,ipert1)
    1656              :          end do
    1657              : 
    1658              : !        summing over k points and bands, still diagonal in jbranch
    1659      4100352 :          accum_mat(:,:,:,isppol) = accum_mat(:,:,:,isppol) + gkq_1band(:,:,:)*sd1*sd2
    1660              : 
    1661              : !        MG20060603 : summing over bands and kpoints with weights to calculate the phonon linewidth
    1662       264192 :          do jbranch=1,elph_ds%nbranch
    1663       711168 :            accum_mat2(:,jbranch,jbranch,isppol) = accum_mat2(:,jbranch,jbranch,isppol) + gkq_1band(:,jbranch,jbranch)*sd1*sd2
    1664              :          end do
    1665              : !        END MG
    1666              : 
    1667              : 
    1668              : !        now turn to cartesian coordinates
    1669              : 
    1670              : !        Final Gamma matrix (hermitian) = E * D_g * E^{+}
    1671              : !        Where E^{+} is the hermitian conjugate of the eigenvector matrix E
    1672              : !        And D_g is the diagonal matrix of values of gamma for this qpoint
    1673              : 
    1674              : !        Here gkq_1band is indexed with real phonon modes (not atom+idir)
    1675              : !        turn gkq_1band to atom+cartesian coordinates (instead of normal coordinates for qpoint)
    1676      4100352 :          tmp_mat2(:,:,:) = zero
    1677       264192 :          do ibranch =1,elph_ds%nbranch
    1678      1542912 :            do jbranch =1,elph_ds%nbranch
    1679              :              tmp_mat2(1,ibranch,jbranch) = tmp_mat2(1,ibranch,jbranch) + &
    1680      1278720 : &             eigvec(1,ibranch,jbranch) * gkq_1band(1,jbranch,jbranch)
    1681              :              tmp_mat2(2,ibranch,jbranch) = tmp_mat2(2,ibranch,jbranch) + &
    1682      1502208 : &             eigvec(2,ibranch,jbranch) * gkq_1band(1,jbranch,jbranch)
    1683              :            end do
    1684              :          end do
    1685      4100352 :          gkq_1band(:,:,:) = zero
    1686              : 
    1687              : !        here eigvec is transposed and complexconjugated.
    1688      4100352 :          zgemm_tmp_mat=zero
    1689              :          call zgemm('n','c',elph_ds%nbranch,elph_ds%nbranch,elph_ds%nbranch,cone,&
    1690        40704 : &         tmp_mat2,elph_ds%nbranch,eigvec,elph_ds%nbranch,czero,zgemm_tmp_mat,elph_ds%nbranch)
    1691              : 
    1692      4100352 :          gkq_1band = zgemm_tmp_mat
    1693              : 
    1694              : !        gamma matrix contribution in cartesian coordinates (ie interpolatable form)
    1695      3963776 :          h1_mat_el_sq(:,ibeff,:,ik_this_proc,isppol) = reshape(gkq_1band,(/2,elph_ds%nbranch*elph_ds%nbranch/))
    1696              : 
    1697              :        end do
    1698              :      end do
    1699              : !    END loop over bands ib1 ib2
    1700              : 
    1701              :    end do
    1702              : !  END loop over kpt_phon
    1703              :  end do
    1704              : !END loop over nsppol
    1705              : 
    1706              : 
    1707           15 : end subroutine nmsq_gam
    1708              : !!***
    1709              : 
    1710              : !!****f* ABINIT/nmsq_gam_sumfs
    1711              : !!
    1712              : !! NAME
    1713              : !! nmsq_gam_sumfs
    1714              : !!
    1715              : !! FUNCTION
    1716              : !!  Calculate gamma matrices from original h1_mat_el_sq matrix
    1717              : !!  elements averaging over bands near the Fermi surface
    1718              : !!
    1719              : !! INPUTS
    1720              : !!   displ_red = phonon mode displacement vectors, post-multiplied by gprim matrix
    1721              : !!     (ie. turned to reduced coordinates)
    1722              : !!   eigvec = eigenvectors of phonons (to turn to cartesian coord frame)
    1723              : !!   elph_ds = datastructure with gkk matrix elements
    1724              : !!   FSfullpqtofull = mapping of k+q to k
    1725              : !!   kpt_phon = coordinates of kpoints near to FS
    1726              : !!   h1_mat_el_sq = matrix elements $<psi_{k+q,m} | H^{1} | psi_{k,n}>$ squared
    1727              : !!   iqptirred = index of present qpoint
    1728              : !!
    1729              : !! OUTPUT
    1730              : !!   accum_mat = matrix for accumulating FS average of gkk (gamma matrix -> linewidths)
    1731              : !!   accum_mat2 = matrix for accumulating FS average of gamma matrix with good prefactors
    1732              : !!
    1733              : !! SOURCE
    1734              : 
    1735            0 : subroutine nmsq_gam_sumFS(accum_mat,accum_mat2,displ_red,eigvec,elph_ds,FSfullpqtofull,&
    1736            0 : &   h1_mat_el_sq,iqptirred)
    1737              : 
    1738              : !Arguments ------------------------------------
    1739              : !scalars
    1740              :  integer,intent(in) :: iqptirred
    1741              :  type(elph_type),intent(inout) :: elph_ds
    1742              : !arrays
    1743              :  integer,intent(in) :: FSfullpqtofull(elph_ds%k_phon%nkpt,elph_ds%nqpt_full)
    1744              :  real(dp),intent(in) :: displ_red(2,elph_ds%nbranch,elph_ds%nbranch)
    1745              :  real(dp),intent(in) :: eigvec(2,elph_ds%nbranch,elph_ds%nbranch)
    1746              :  real(dp),intent(inout) :: &
    1747              : & h1_mat_el_sq(2,elph_ds%nFSband*elph_ds%nFSband,elph_ds%nbranch*elph_ds%nbranch,elph_ds%k_phon%my_nkpt,elph_ds%nsppol)
    1748              :  real(dp),intent(inout) :: accum_mat(2,elph_ds%nbranch,elph_ds%nbranch,elph_ds%nsppol)
    1749              :  real(dp),intent(inout) :: accum_mat2(2,elph_ds%nbranch,elph_ds%nbranch,elph_ds%nsppol)
    1750              : 
    1751              : !Local variables-------------------------------
    1752              : !scalars
    1753              :  integer :: ikpt_phon,ikpt_phonq,ib1,ib2,ibeff,ibranch,ipert1,isppol,jbranch,iqpt_fullbz
    1754              :  integer :: ik_this_proc
    1755              :  real(dp) :: sd1,sd2
    1756              :  character(len=500) :: message
    1757              : !arrays
    1758            0 :  real(dp) :: gkq_sum_bands(2,elph_ds%nbranch,elph_ds%nbranch)
    1759            0 :  real(dp) :: tmp_gkq_sum_bands(2,elph_ds%nbranch,elph_ds%nbranch)
    1760            0 :  real(dp) :: tmp_mat2(2,elph_ds%nbranch,elph_ds%nbranch)
    1761            0 :  real(dp),allocatable :: zgemm_tmp_mat(:,:,:)
    1762              : 
    1763              : ! *************************************************************************
    1764              : 
    1765            0 :  if (elph_ds%ep_keepbands /= 0) then
    1766            0 :    write (message,'(a,i0)')' elph_ds%ep_keepbands should be 0 in order to average over bands!',elph_ds%ep_keepbands
    1767            0 :    ABI_ERROR(message)
    1768              :  end if
    1769              : 
    1770            0 :  iqpt_fullbz = elph_ds%qirredtofull(iqptirred)
    1771              : 
    1772              : 
    1773              : !MG20060603 NOTE:
    1774              : !accum_mat and accum_mat2 are real, the imaginary part is used for debugging purpose
    1775              : !accum_mat2 is used to store the phonon-linewidhts before interpolation
    1776              : 
    1777            0 :  ABI_MALLOC(zgemm_tmp_mat ,(2,elph_ds%nbranch,elph_ds%nbranch))
    1778              : 
    1779            0 :  do isppol=1,elph_ds%nsppol
    1780            0 :    do ik_this_proc =1, elph_ds%k_phon%my_nkpt
    1781            0 :      ikpt_phon = elph_ds%k_phon%my_ikpt(ik_this_proc)
    1782              : 
    1783            0 :      ikpt_phonq = FSfullpqtofull(ikpt_phon,iqpt_fullbz)
    1784              : 
    1785            0 :      gkq_sum_bands = zero
    1786            0 :      tmp_gkq_sum_bands = zero
    1787              : 
    1788              : 
    1789            0 :      do ib1=1,elph_ds%nFSband
    1790              : !      weights for distance from the fermi surface
    1791            0 :        sd1 = elph_ds%k_phon%wtk(ib1,ikpt_phon,isppol)
    1792              : 
    1793            0 :        do ib2=1,elph_ds%nFSband
    1794              : !        weights for distance from the fermi surface
    1795            0 :          sd2 = elph_ds%k_phon%wtk(ib2,ikpt_phonq,isppol)
    1796            0 :          ibeff=ib2+(ib1-1)*elph_ds%nFSband
    1797              : 
    1798            0 :          zgemm_tmp_mat = reshape(h1_mat_el_sq(:,ibeff,:,ik_this_proc,isppol),(/2,elph_ds%nbranch,elph_ds%nbranch/))
    1799              : 
    1800            0 :          call gam_mult_displ(elph_ds%nbranch, displ_red, zgemm_tmp_mat, tmp_mat2)
    1801              : 
    1802              : !        sum over bands in gkq_sum_bands
    1803            0 :          do ipert1=1,elph_ds%nbranch
    1804            0 :            gkq_sum_bands(1,ipert1,ipert1) = gkq_sum_bands(1,ipert1,ipert1) + sd1*sd2*tmp_mat2(1,ipert1,ipert1)
    1805              :          end do
    1806              : 
    1807              : 
    1808              : 
    1809              :        end do
    1810              :      end do
    1811              : !    END loop over bands
    1812              : 
    1813              : !    summing over k points, still diagonal in jbranch
    1814            0 :      accum_mat(:,:,:,isppol) = accum_mat(:,:,:,isppol) + gkq_sum_bands(:,:,:)
    1815            0 :      accum_mat2(:,:,:,isppol) = accum_mat2(:,:,:,isppol) + gkq_sum_bands(:,:,:)
    1816              : 
    1817              : !    summed over bands, now turn to cartesian coordinates
    1818              : 
    1819              : !    Final Gamma matrix (hermitian) = E * D_g * E^{+}
    1820              : !    Where E^{+} is the hermitian conjugate of the eigenvector matrix E
    1821              : !    And D_g is the diagonal matrix of values of gamma for this qpoint
    1822              : 
    1823              : !    Here gkq_sum_bands is indexed with real phonon modes (not atom+idir)
    1824              : !    turn gkq_sum_bands to atom+cartesian coordinates (instead of normal coordinates for qpoint)
    1825              : !    This is not a full matrix multiplication, just vector one, by
    1826              : !    gkq_sum_bands(1,jbranch,jbranch)
    1827            0 :      tmp_mat2(:,:,:) = zero
    1828            0 :      do ibranch =1,elph_ds%nbranch
    1829            0 :        do jbranch =1,elph_ds%nbranch
    1830              :          tmp_mat2(1,ibranch,jbranch) = tmp_mat2(1,ibranch,jbranch) + &
    1831              : &         eigvec(1,ibranch,jbranch) * &
    1832            0 : &         gkq_sum_bands(1,jbranch,jbranch)
    1833              :          tmp_mat2(2,ibranch,jbranch) = tmp_mat2(2,ibranch,jbranch) + &
    1834              : &         eigvec(2,ibranch,jbranch) * &
    1835            0 : &         gkq_sum_bands(1,jbranch,jbranch)
    1836              :        end do
    1837              :      end do
    1838              : 
    1839              : !    here eigvec is transposed and complex conjugated.
    1840            0 :      zgemm_tmp_mat=zero
    1841              :      call zgemm('n','c',elph_ds%nbranch,elph_ds%nbranch,elph_ds%nbranch,cone,&
    1842            0 : &     tmp_mat2,elph_ds%nbranch,eigvec,elph_ds%nbranch,czero,zgemm_tmp_mat,elph_ds%nbranch)
    1843              : 
    1844            0 :      gkq_sum_bands = zgemm_tmp_mat
    1845              : 
    1846              : !    ! gamma matrix contribution in cartesian coordinates (ie interpolatable form)
    1847              : !    gamma matrix contribution in reduced coordinates (ie interpolatable form)
    1848            0 :      h1_mat_el_sq(:,1,:,ik_this_proc,isppol) = reshape(gkq_sum_bands(:,:,:),(/2,elph_ds%nbranch*elph_ds%nbranch/))
    1849              : 
    1850              : !    accum_mat(:,:,:,isppol) = accum_mat(:,:,:,isppol) + gkq_sum_bands(:,:,:)
    1851              :    end do
    1852              : !  END loop over kpt_phon
    1853              :  end do
    1854              : !END loop over sppol
    1855              : 
    1856            0 :  ABI_FREE(zgemm_tmp_mat)
    1857              : 
    1858            0 : end subroutine nmsq_gam_sumFS
    1859              : !!***
    1860              : 
    1861              : 
    1862              : !!****f* ABINIT/nmsq_pure_gkk
    1863              : !!
    1864              : !! NAME
    1865              : !! nmsq_pure_gkk
    1866              : !!
    1867              : !! FUNCTION
    1868              : !!  Calculate gamma matrices for pure gkk case, ie when the
    1869              : !!  scalar product with the displacement vector is done later
    1870              : !!  Sum over bands is carried out later.
    1871              : !!
    1872              : !! INPUTS
    1873              : !!   displ_red = phonon displacement in reduced coordinates (used to calculate the ph linewidth)
    1874              : !!   elph_ds = datastructure with gkk matrix elements
    1875              : !!   FSfullpqtofull = mapping of k+q to k
    1876              : !!   kpt_phon = coordinates of kpoints near to FS
    1877              : !!   h1_mat_el_sq = matrix elements $<psi_{k+q,m} | H^{1} | psi_{k,n}>$ squared
    1878              : !!   iqptirred = index of present qpoint
    1879              : !!
    1880              : !! OUTPUT
    1881              : !!   elph_ds%gkq filled
    1882              : !!   accum_mat = matrix for accumulating FS average of gkk (gamma matrix -> linewidths)
    1883              : !!   accum_mat2 = complex array whose real part contains the phonon linewidth
    1884              : !!
    1885              : !! SOURCE
    1886              : 
    1887            3 : subroutine nmsq_pure_gkk(accum_mat,accum_mat2,displ_red,elph_ds,FSfullpqtofull,&
    1888            3 : &   h1_mat_el_sq,iqptirred)
    1889              : 
    1890              : !Arguments ------------------------------------
    1891              : !scalars
    1892              :  integer,intent(in) :: iqptirred
    1893              :  type(elph_type),intent(inout) :: elph_ds
    1894              : !arrays
    1895              :  integer,intent(in) :: FSfullpqtofull(elph_ds%k_phon%nkpt,elph_ds%nqpt_full)
    1896              :  real(dp),intent(in) :: displ_red(2,elph_ds%nbranch,elph_ds%nbranch)
    1897              :  real(dp),intent(inout) :: &
    1898              : & h1_mat_el_sq(2,elph_ds%nFSband*elph_ds%nFSband,elph_ds%nbranch*elph_ds%nbranch,elph_ds%k_phon%my_nkpt,elph_ds%nsppol)
    1899              :  real(dp),intent(inout) :: accum_mat(2,elph_ds%nbranch,elph_ds%nbranch,elph_ds%nsppol)
    1900              :  real(dp),intent(inout) :: accum_mat2(2,elph_ds%nbranch,elph_ds%nbranch,elph_ds%nsppol)
    1901              : 
    1902              : !Local variables-------------------------------
    1903              : !scalars
    1904              :  integer :: ikpt_phon,ikpt_phonq,ib1,ib2,ibeff,ipert1,isppol
    1905              :  integer :: iqpt_fullbz
    1906              :  integer :: ik_this_proc
    1907              :  real(dp) :: sd1,sd2
    1908              :  character(len=500) :: message
    1909              : !arrays
    1910            6 :  real(dp) :: gkq_sum_bands(2,elph_ds%nbranch,elph_ds%nbranch)
    1911            6 :  real(dp) :: tmp_mat2(2,elph_ds%nbranch,elph_ds%nbranch)
    1912            6 :  real(dp) :: zgemm_tmp_mat(2,elph_ds%nbranch,elph_ds%nbranch)
    1913              : 
    1914              : ! *************************************************************************
    1915              : 
    1916            3 :  if (elph_ds%ep_keepbands /= 1) then
    1917            0 :    message = ' elph_ds%ep_keepbands should be 1 to keep bands!'
    1918            0 :    ABI_ERROR(message)
    1919              :  end if
    1920              : 
    1921            3 :  iqpt_fullbz = elph_ds%qirredtofull(iqptirred)
    1922              : 
    1923              : !h1_mat_el_sq is already fine here - nothing to do
    1924              : 
    1925              : 
    1926              : !MG20060603 NOTE:
    1927              : !accum_mat and accum_mat2 are real, the imaginary part is used for debugging purpose
    1928              : !accum_mat2 is used to store the phonon-linewidhts before interpolation
    1929              : 
    1930              : !MJV 20070525 NOTE:
    1931              : !in some of the nmsq routines, in particular this one, the work done to
    1932              : !calculate accum_mat,accum_mat2 is completely superfluous and will be re-done
    1933              : !on the interpolated values.
    1934              : !MG uses them for the QPT output, however, so keep it for consistency for the
    1935              : !moment.
    1936              : 
    1937            6 :  do isppol=1,elph_ds%nsppol
    1938          651 :    do ik_this_proc =1, elph_ds%k_phon%my_nkpt
    1939          648 :      ikpt_phon = elph_ds%k_phon%my_ikpt(ik_this_proc)
    1940              : 
    1941          648 :      ikpt_phonq = FSfullpqtofull(ikpt_phon,iqpt_fullbz)
    1942              : 
    1943        20088 :      gkq_sum_bands(:,:,:) = zero
    1944              : 
    1945              : !    gkq_sum_bands = \sum_{ib1,ib2} \langle k+q \mid H^{(1)}_{q,\tau_i,\alpha_i} \mid k   \rangle
    1946              : !    \cdot \langle k   \mid H^{(1)}_{q,\tau_j,\alpha_j} \mid k+q \rangle
    1947              : !    where ibranch -> \tau_i,\alpha_i  and  jbranch -> \tau_j,\alpha_j
    1948              : 
    1949         4536 :      do ib1=1,elph_ds%nFSband
    1950              : 
    1951         3888 :        sd1 = elph_ds%k_phon%wtk(ib1,ikpt_phon,isppol)      !  weights for distance from the fermi surface
    1952              : 
    1953        27864 :        do ib2=1,elph_ds%nFSband
    1954              : 
    1955        23328 :          sd2 = elph_ds%k_phon%wtk(ib2,ikpt_phonq,isppol)  !  weights for distance from the fermi surface
    1956        23328 :          ibeff = ib2+(ib1-1)*elph_ds%nFSband
    1957              : 
    1958              :          gkq_sum_bands = gkq_sum_bands + &
    1959       797040 : &         sd1*sd2*reshape(h1_mat_el_sq(:,ibeff,:,ik_this_proc,isppol),(/2,elph_ds%nbranch,elph_ds%nbranch/))
    1960              : 
    1961              :        end do !ib2
    1962              :      end do !ib1
    1963              : !    END loops over bands
    1964              : 
    1965              : 
    1966        20091 :      accum_mat(:,:,:,isppol) = accum_mat(:,:,:,isppol) + gkq_sum_bands(:,:,:)
    1967              :    end do
    1968              : !  END loop over kpt_phon
    1969              : 
    1970              : !  MG20060603
    1971              : !  do scalar product with the displ_red to calculate the ph lwdth before interpolation (stored in accum_mat2)
    1972              : 
    1973           93 :    zgemm_tmp_mat = accum_mat(:,:,:,isppol)
    1974              : 
    1975            3 :    call gam_mult_displ(elph_ds%nbranch, displ_red, zgemm_tmp_mat, tmp_mat2)
    1976              : 
    1977           15 :    do ipert1=1,elph_ds%nbranch
    1978           12 :      accum_mat2(1,ipert1,ipert1,isppol) = accum_mat2(1,ipert1,ipert1,isppol) + tmp_mat2(1,ipert1,ipert1)
    1979              :    end do
    1980              : 
    1981              : !  ENDMG
    1982              : 
    1983              :  end do ! isppol
    1984              : 
    1985            3 : end subroutine nmsq_pure_gkk
    1986              : !!***
    1987              : 
    1988              : !!****f* ABINIT/nmsq_pure_gkk_sumfs
    1989              : !!
    1990              : !! NAME
    1991              : !! nmsq_pure_gkk_sumfs
    1992              : !!
    1993              : !! FUNCTION
    1994              : !!  Calculate gamma matrices for pure gkk case, i.e, when the
    1995              : !!  scalar product with the displacement vector is done later
    1996              : !!  Sum over bands is carried out now.
    1997              : !!
    1998              : !! INPUTS
    1999              : !!   displ_red = phonon displacement in reduced coordinates (used to calculate the ph linewidth)
    2000              : !!   elph_ds = datastructure with gkk matrix elements
    2001              : !!   FSfullpqtofull = mapping of k+q to k
    2002              : !!   kpt_phon = coordinates of kpoints near to FS
    2003              : !!   h1_mat_el_sq = matrix elements $<psi_{k+q,m} | H^{1} | psi_{k,n}>$ squared
    2004              : !!   iqptirred = index of present qpoint
    2005              : !!
    2006              : !! OUTPUT
    2007              : !!   accum_mat = matrix for accumulating FS average of gkk (gamma matrix -> linewidths)
    2008              : !!   accum_mat2 = complex array whose real part contains the phonon linewidth
    2009              : !!
    2010              : !! SOURCE
    2011              : 
    2012           30 : subroutine nmsq_pure_gkk_sumfs(accum_mat,accum_mat2,displ_red,elph_ds,FSfullpqtofull,h1_mat_el_sq,iqptirred)
    2013              : 
    2014              : !Arguments ------------------------------------
    2015              : !scalars
    2016              :  integer,intent(in) :: iqptirred
    2017              :  type(elph_type),intent(in) :: elph_ds
    2018              : !arrays
    2019              :  integer,intent(in) :: FSfullpqtofull(elph_ds%k_phon%nkpt,elph_ds%nqpt_full)
    2020              :  real(dp),intent(in) :: displ_red(2,elph_ds%nbranch,elph_ds%nbranch)
    2021              :  real(dp),intent(inout) :: &
    2022              : & h1_mat_el_sq(2,elph_ds%nFSband*elph_ds%nFSband,elph_ds%nbranch*elph_ds%nbranch,elph_ds%k_phon%my_nkpt,elph_ds%nsppol)
    2023              :  real(dp),intent(inout) :: accum_mat(2,elph_ds%nbranch,elph_ds%nbranch,elph_ds%nsppol)
    2024              :  real(dp),intent(inout) :: accum_mat2(2,elph_ds%nbranch,elph_ds%nbranch,elph_ds%nsppol)
    2025              : 
    2026              : !Local variables-------------------------------
    2027              : !scalars
    2028              :  integer :: ikpt_phon,ikpt_phonq,ib1,ib2,ibeff,ipert1,isppol,iqpt_fullbz
    2029              :  integer :: nbranch,nsppol,nFSband,nkpt_phon
    2030              :  integer :: ik_this_proc
    2031              :  real(dp) :: sd1,sd2
    2032              :  !character(len=500) :: message
    2033              : !arrays
    2034           60 :  real(dp) :: gkq_sum_bands(2,elph_ds%nbranch,elph_ds%nbranch)
    2035           60 :  real(dp) :: tmp_mat2(2,elph_ds%nbranch,elph_ds%nbranch)
    2036           60 :  real(dp) :: zgemm_tmp_mat(2,elph_ds%nbranch,elph_ds%nbranch)
    2037              : 
    2038              : ! *************************************************************************
    2039              : 
    2040           30 :  if (elph_ds%ep_keepbands /= 0) then
    2041            0 :    ABI_BUG('ep_keepbands should be 0 to average over bands!')
    2042              :  end if
    2043              : 
    2044           30 :  nbranch   = elph_ds%nbranch
    2045           30 :  nsppol    = elph_ds%nsppol
    2046           30 :  nFSband   = elph_ds%nFSband
    2047           30 :  nkpt_phon = elph_ds%k_phon%nkpt
    2048              : 
    2049           30 :  iqpt_fullbz = elph_ds%qirredtofull(iqptirred)
    2050              : 
    2051              : !MG20060603 NOTE:
    2052              : !accum_mat and accum_mat2 are real, the imaginary part is used for debugging purpose
    2053              : !accum_mat2 is used to store the phonon-linewidhts before interpolation
    2054              : 
    2055           63 :  do isppol=1,nsppol
    2056         2751 :    do ik_this_proc =1, elph_ds%k_phon%my_nkpt
    2057         2688 :      ikpt_phon = elph_ds%k_phon%my_ikpt(ik_this_proc)
    2058              : 
    2059              : !
    2060              : !    The index of k+q in the BZ.
    2061         2688 :      ikpt_phonq = FSfullpqtofull(ikpt_phon,iqpt_fullbz)
    2062              : !
    2063              : !    gkq_sum_bands =
    2064              : !    \sum_{ib1,ib2} <k+q| H^{(1)}_{q,\tau_i,\alpha_i} |k> \cdot <k| H^{(1)}_{q,\tau_j,\alpha_j}|k+q>
    2065              : !
    2066              : !    where ibranch = (\tau_i,\alpha_i) and  jbranch = (\tau_j,\alpha_j).
    2067        83328 :      gkq_sum_bands(:,:,:) = zero
    2068              : 
    2069        19488 :      do ib1=1,nFSband
    2070        16800 :        sd1 = elph_ds%k_phon%wtk(ib1,ikpt_phon,isppol)      !  weights for distance from the fermi surface
    2071              : 
    2072       127584 :        do ib2=1,nFSband
    2073       108096 :          sd2 = elph_ds%k_phon%wtk(ib2,ikpt_phonq,isppol)  !  weights for distance from the fermi surface
    2074       108096 :          ibeff=ib2+(ib1-1)*nFSband
    2075              : 
    2076              :          gkq_sum_bands = gkq_sum_bands + &
    2077      3692064 : &         sd1*sd2* reshape(h1_mat_el_sq(:,ibeff,:,ik_this_proc,isppol),(/2,nbranch,nbranch/))
    2078              :        end do !ib2
    2079              :      end do !ib1
    2080              : !
    2081              : !    gamma matrix contribution in reduced coordinates (ie interpolatable form)
    2082              : !    The sum over Fermi surface bands is done here, and fed into (ib1,ib2)=(1,1)
    2083        80640 :      h1_mat_el_sq(:,1,:,ik_this_proc,isppol) = reshape(gkq_sum_bands,(/2,nbranch**2/))
    2084              : 
    2085        83361 :      accum_mat(:,:,:,isppol) = accum_mat(:,:,:,isppol) + gkq_sum_bands(:,:,:)
    2086              :    end do ! kpt_phon
    2087              :  end do ! isppol
    2088              : !
    2089              : !MG20060603
    2090              : !do scalar product wit displ_red to calculate the ph lwdth before interpolation (stored in accum_mat2)
    2091           63 :  do isppol=1,nsppol
    2092         1023 :    zgemm_tmp_mat = accum_mat(:,:,:,isppol)
    2093              : !
    2094           33 :    call gam_mult_displ(nbranch, displ_red, zgemm_tmp_mat, tmp_mat2)
    2095              : 
    2096          162 :    do ipert1=1,nbranch
    2097          132 :      accum_mat2(1,ipert1,ipert1,isppol) = accum_mat2(1,ipert1,ipert1,isppol) + tmp_mat2(1,ipert1,ipert1)
    2098              :    end do
    2099              : !
    2100              :  end do
    2101              : 
    2102           30 : end subroutine nmsq_pure_gkk_sumfs
    2103              : !!***
    2104              : 
    2105              : end module m_iogkk
    2106              : !!***
        

Generated by: LCOV version 2.3-1