LCOV - code coverage report
Current view: top level - src/71_bse - m_hexc.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 86.4 % 469 405
Test Date: 2026-09-19 15:24:51 Functions: 66.7 % 15 10

            Line data    Source code
       1              : !!****m* ABINIT/m_hexc
       2              : !! NAME
       3              : !! m_hexc
       4              : !!
       5              : !! FUNCTION
       6              : !! Module for excitonic hamiltonian for Haydock
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 2014-2026 ABINIT group (M.Giantomassi, Y. Gillet)
      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_hexc
      23              : 
      24              :  use defs_basis
      25              :  use m_abicore
      26              :  use m_bs_defs
      27              :  use m_xmpi
      28              :  use m_errors
      29              :  use m_haydock_io
      30              :  use m_linalg_interfaces
      31              :  use netcdf
      32              :  use m_nctk
      33              : 
      34              :  use m_time,              only : timab
      35              :  use m_fstrings,          only : indent, strcat, sjoin, itoa
      36              :  use defs_datatypes,      only : pseudopotential_type
      37              :  use m_hide_blas,         only : xdotc, xgemv
      38              :  use m_numeric_tools,     only : print_arr, symmetrize, hermitianize, wrap2_pmhalf
      39              :  use m_crystal,           only : crystal_t
      40              :  use m_bz_mesh,           only : kmesh_t, findqg0
      41              :  use m_double_grid,       only : double_grid_t, get_kpt_from_indices_coarse, compute_corresp
      42              :  use m_wfd,               only : wfdgw_t
      43              :  use m_bse_io,            only : exc_read_rcblock, exc_write_optme, exc_ham_ncwrite
      44              :  use m_pawtab,            only : pawtab_type
      45              :  use m_vcoul,             only : vcoul_t
      46              :  use m_bseinterp,         only : interpolator_t
      47              :  use m_ebands,            only : ebands_t
      48              : 
      49              :  implicit none
      50              : 
      51              :  private
      52              : !!***
      53              : 
      54              : !!****t* m_haydock/hexc_t
      55              : !! NAME
      56              : !! hexc_t
      57              : !!
      58              : !! FUNCTION
      59              : !!  Store the excitonic hamiltonian and other related information
      60              : !!
      61              : !! SOURCE
      62              : 
      63              :  type, public :: hexc_t
      64              : 
      65              :    !scalars
      66              :    integer :: comm
      67              :    ! MPI communicator
      68              : 
      69              :    integer :: hsize_coarse
      70              :    ! Size of the coarse hamiltonian
      71              : 
      72              :    integer :: hsize
      73              :    ! Size of the hamiltonian and the kets
      74              :    ! (= hsize_coarse without interpolation, = hsize_dense with interpolation)
      75              : 
      76              :    integer :: nbz
      77              :    ! Number of kpoints for the full problem
      78              :    ! (= nbz_coarse without interpolation, = nbz_dense with interpolation)
      79              : 
      80              :    integer :: my_t1
      81              :    ! Lower limit of MPI paral
      82              : 
      83              :    integer :: my_t2
      84              :    ! Upper limit of MPI paral
      85              : 
      86              :    integer :: my_nt
      87              :    ! Number of transitions treat by node
      88              :    ! = my_t2 - my_t1 + 1
      89              : 
      90              :    integer :: nbnd_coarse
      91              :    ! Product of number of bands conduction X valence
      92              : 
      93              :    ! Pointers to data that are already in memory
      94              :    type(excparam),pointer :: bsp => null()
      95              :    ! parameters for BS
      96              : 
      97              :    type(excfiles),pointer :: bs_files => null()
      98              :    ! files for BSE
      99              : 
     100              :    type(crystal_t),pointer :: crystal => null()
     101              :    ! crystal info
     102              : 
     103              :    type(kmesh_t),pointer :: kmesh_coarse => null()
     104              :    ! kmesh of the coarse mesh
     105              : 
     106              :    type(kmesh_t),pointer :: kmesh => null()
     107              :    ! kmesh of the full problem
     108              : 
     109              :    type(ebands_t),pointer :: ks_bst => null()
     110              :    type(ebands_t),pointer :: qp_bst => null()
     111              :    ! band structures of the full problem
     112              : 
     113              :    type(wfdgw_t),pointer :: wfd_coarse => null()
     114              :    ! Wfd of the coarse problem
     115              : 
     116              :    type(wfdgw_t),pointer :: wfd => null()
     117              :    ! wfd of the full problem
     118              : 
     119              :    !arrays
     120              :    complex(dp),allocatable :: hreso(:,:)
     121              :    ! Resonant part of the hamiltonian
     122              : 
     123              :    complex(dp),allocatable :: hcoup(:,:)
     124              :    ! Coupling part of the hamiltonian
     125              : 
     126              :    complex(dp),allocatable :: diag_coarse(:)
     127              :    ! Diagonal part of the hamiltonian with transition energies
     128              : 
     129              :  contains
     130              :    procedure :: init => hexc_init           ! Construct the object
     131              :    procedure :: free => hexc_free           ! Free memory
     132              :    procedure :: build_hinterp => hexc_build_hinterp  ! Interpolate the Hamiltonian and store it in memory
     133              :    procedure :: matmul_tda => hexc_matmul_tda     ! Matrix-vector multiplication (TDA)
     134              :    procedure :: matmul_full => hexc_matmul_full    ! Matrix-vector multiplication (TDA + Coupling)
     135              :    procedure :: matmul_elphon => hexc_matmul_elphon  ! Matrix-vector multiplication (TDA + elphon)
     136              :  end type hexc_t
     137              : !!***
     138              : 
     139              : !----------------------------------------------------------------------
     140              : 
     141              : !!****t* m_hexc/hexc_interp_t
     142              : !! NAME
     143              : !! hexc_interp_t
     144              : !!
     145              : !! FUNCTION
     146              : !!  Store information about interpolation of excitonic hamiltonian
     147              : !!
     148              : !! SOURCE
     149              : 
     150              :  type,public :: hexc_interp_t
     151              : 
     152              :    !scalars
     153              :    integer :: hsize_dense
     154              :    ! Size of the dense hamiltonian
     155              : 
     156              :    real(dp) :: m3_width
     157              :    ! Width of the region where M3 is applied instead of M1
     158              : 
     159              :    type(interpolator_t) :: interpolator
     160              :    ! Interpolator containing overlaps and interpolation info
     161              : 
     162              :    ! Pointers to datatypes that are already in memory
     163              :    type(kmesh_t),pointer :: kmesh_dense => null()
     164              :    ! kmesh of the dense mesh
     165              : 
     166              :    type(vcoul_t),pointer :: vcp_dense => null()
     167              :    ! coulomb interaction on the dense mesh
     168              : 
     169              :    !arrays
     170              :    integer,allocatable :: kdense2div(:)
     171              :    ! kdense2div(nbz_dense)
     172              :    ! Index of kpoint -> Index of division
     173              : 
     174              :    integer,allocatable :: div2kdense(:,:)
     175              :    ! div2kdense(nbz_coarse,ndiv)
     176              :    ! Index of kpoint coarse + Index of division -> Index of kdense
     177              : 
     178              :    complex(dp),allocatable :: diag_dense(:)
     179              :    ! diag_dense(hsize_dense)
     180              :    ! Diagonal part of the dense hamiltonian
     181              : 
     182              :    complex(dp),allocatable :: hinterp(:,:)
     183              :    ! hinterp(hsize_dense,hsize_dense)
     184              :    ! Interpolated hamiltonian
     185              : 
     186              :    complex(dp),allocatable :: all_hmat(:,:)
     187              :    ! all_hmat,(hsize,hsize))
     188              :    ! Coarse excitonic matrix in a format suitable for interpolation in k-space
     189              : 
     190              :    complex(dp),allocatable :: all_acoeffs(:,:)
     191              :    ! all_acoeffs(hsize,hsize))
     192              :    ! a coefficients in a format suitable for interpolation in k-space
     193              : 
     194              :    complex(dp),allocatable :: all_bcoeffs(:,:)
     195              :    ! all_bcoeffs(hsize,hsize))
     196              :    ! b coefficients in a format suitable for interpolation in k-space
     197              : 
     198              :    complex(dp),allocatable :: all_ccoeffs(:,:)
     199              :    ! all_ccoeffs(hsize,hsize))
     200              :    ! c coefficients in a format suitable for interpolation in k-space
     201              : 
     202              :  contains
     203              :    procedure :: init => hexc_interp_init    ! Construct the object for interpolated ham
     204              :    procedure :: free => hexc_interp_free    ! Free memory for interpolated ham
     205              :  end type hexc_interp_t
     206              : !!***
     207              : 
     208              : !----------------------------------------------------------------------
     209              : 
     210              : CONTAINS  !=======================================================================
     211              : !!***
     212              : 
     213              : !!****f* m_hexc/hexc_init
     214              : !! NAME
     215              : !! hexc_init
     216              : !!
     217              : !! FUNCTION
     218              : !! Construct the hexc object
     219              : !!
     220              : !! INPUTS
     221              : !! BSp<excparam>=Parameters of BS
     222              : !! BS_files<excparam>=Files for BS
     223              : !! Cryst<crystal_t>=Info on the crystalline structure
     224              : !! Kmesh_coarse<kmesh_t>=Kmesh info
     225              : !! Wfd_coarse<wfdgw_t>=Wavefunction descriptor
     226              : !! KS_BSt<ebands_t>=Kohn-Sham band structure
     227              : !! QP_BSt<ebands_t>=Quasi-Particle band structure
     228              : !! comm=communicator
     229              : !!
     230              : !! OUTPUT
     231              : !! hexc<hexc_t>=Excitonic Hamiltonian
     232              : !!
     233              : !! SOURCE
     234              : 
     235           23 : subroutine hexc_init(hexc, BSp, BS_files, Cryst, Kmesh_coarse, Wfd_coarse, KS_BSt, QP_BSt, comm)
     236              : 
     237              : !Arguments ---------------------------
     238              : !scalars
     239              :  class(hexc_t),intent(inout) :: hexc
     240              :  integer,intent(in) :: comm
     241              :  type(excparam),intent(in),target :: BSp
     242              :  type(excfiles),intent(in),target :: BS_files
     243              :  type(crystal_t),intent(in),target :: Cryst
     244              :  type(kmesh_t),intent(in),target :: Kmesh_coarse
     245              :  type(wfdgw_t),intent(in),target :: Wfd_coarse
     246              :  type(ebands_t),intent(in),target :: KS_BSt, QP_BSt
     247              : 
     248              : !Local variables ---------------------
     249              : !scalars
     250              :  integer :: ierr,ncid,ncerr, max_r, max_c, hsize, spin, spad, itt ! For diagonal !
     251              :  logical :: is_resonant, diago_is_real, use_mpio=.FALSE.
     252              :  character(len=fnlen) :: hreso_fname, hcoup_fname
     253              :  !character(len=500) :: msg
     254              : !arrays
     255           23 :  complex(dp),allocatable :: test(:,:)
     256              : !*****************************************************************************
     257              : 
     258           23 :  hexc%bsp => BSp
     259           23 :  hexc%bs_files => BS_files
     260           23 :  hexc%crystal => Cryst
     261           23 :  hexc%kmesh_coarse => Kmesh_coarse
     262              : 
     263           23 :  hexc%comm = comm
     264           46 :  hsize = SUM(BSp%nreh)
     265              : 
     266           23 :  hexc%ks_bst => KS_BSt
     267           23 :  hexc%qp_bst => QP_BSt
     268           23 :  hexc%wfd => Wfd_coarse
     269           23 :  hexc%wfd_coarse => Wfd_coarse
     270           23 :  hexc%kmesh => Kmesh_coarse
     271           23 :  hexc%hsize_coarse = hsize
     272           23 :  hexc%hsize = hsize
     273           23 :  hexc%nbz = Kmesh_coarse%nbz
     274              : 
     275           23 :  hexc%nbnd_coarse = BSp%maxnbndv*BSp%maxnbndc
     276              : 
     277              :  ! Divide the columns of the Hamiltonian among the nodes.
     278           23 :  call xmpi_split_work(hsize,comm,hexc%my_t1,hexc%my_t2)
     279              : 
     280           23 :  hexc%my_nt = hexc%my_t2 - hexc%my_t1 + 1
     281           23 :  ABI_CHECK(hexc%my_nt>0,"found processor with 0 rows")
     282              : 
     283           92 :  ABI_MALLOC_OR_DIE(hexc%hreso,(hsize,hexc%my_t1:hexc%my_t2), ierr)
     284              : 
     285              :  ! Read the resonant block from file.
     286           23 :  if (BS_files%in_hreso /= BSE_NOFILE) then
     287            5 :    hreso_fname = BS_files%in_hreso
     288              :  else
     289           18 :    hreso_fname = BS_files%out_hreso
     290              :  end if
     291              : 
     292           23 :  is_resonant=.TRUE.; diago_is_real=(.not.BSp%have_complex_ene)
     293              :  call exc_read_rcblock(hreso_fname,Bsp,is_resonant,diago_is_real,BSp%nsppol,BSp%nreh,hsize,&
     294           23 : &   hexc%my_t1,hexc%my_t2,hexc%hreso,use_mpio,comm)
     295              : 
     296              :  !BEGIN DEBUG
     297           23 :  if (use_mpio) then
     298            0 :    ABI_WARNING("Testing MPI-IO routines")
     299            0 :    ABI_MALLOC_OR_DIE(test,(hsize,hexc%my_t1:hexc%my_t2), ierr)
     300            0 :    diago_is_real=(.not.BSp%have_complex_ene)
     301              :    call exc_read_rcblock(hreso_fname,Bsp,is_resonant,diago_is_real,Bsp%nsppol,Bsp%nreh,hsize,&
     302            0 :                          hexc%my_t1,hexc%my_t2,test,.FALSE.,comm)
     303            0 :    test = test-hexc%hreso
     304            0 :    write(std_out,*)"DEBUG: Diff MPI-IO - Fortran ",MAXVAL(ABS(test))
     305            0 :    max_r=20; max_c=10
     306            0 :    write(std_out,*)" **** Testing resonant block **** "
     307            0 :    call print_arr([std_out], test,max_r=max_r,max_c=max_c)
     308            0 :    if (BSp%nsppol==2) then
     309            0 :      write(std_out,*)" **** D down down ****"
     310            0 :      call print_arr([std_out], test(hsize/2+1:,hsize/2+1:),max_r=max_r,max_c=max_c)
     311            0 :      write(std_out,*)" **** V up down ****"
     312            0 :      call print_arr([std_out], test(1:hsize/2,hsize/2+1:),max_r=max_r,max_c=max_c)
     313            0 :      write(std_out,*)" **** V down up ****"
     314            0 :      call print_arr([std_out], test(hsize/2+1:,1:hsize/2),max_r=max_r,max_c=max_c)
     315              :    end if
     316            0 :    ABI_FREE(test)
     317              :  end if
     318              :  !END DEBUG
     319              : 
     320              :  !
     321              :  ! Read coupling block.
     322           23 :  if (BSp%use_coupling>0) then
     323            0 :    ABI_CHECK(.not. Bsp%use_interp,"interpolation with coupling not coded!")
     324            0 :    if (BS_files%in_hcoup /= BSE_NOFILE) then
     325            0 :      hcoup_fname = BS_files%in_hcoup
     326              :    else
     327            0 :      hcoup_fname = BS_files%out_hcoup
     328              :    end if
     329              : 
     330            0 :    ABI_MALLOC_OR_DIE(hexc%hcoup,(hsize,hexc%my_t1:hexc%my_t2), ierr)
     331            0 :    is_resonant=.FALSE.; diago_is_real=.FALSE.
     332              :    call exc_read_rcblock(hcoup_fname,Bsp,is_resonant,diago_is_real,BSp%nsppol,BSp%nreh,hsize,&
     333            0 :                          hexc%my_t1,hexc%my_t2,hexc%hcoup,use_mpio,comm)
     334              :    !call symmetrize(hcoup,"ALL")
     335              : 
     336            0 :    if (use_mpio) then
     337            0 :      ABI_WARNING("Testing MPI-IO routines")
     338            0 :      ABI_MALLOC_OR_DIE(test,(hsize,hexc%my_t1:hexc%my_t2), ierr)
     339            0 :      diago_is_real=.FALSE.
     340            0 :      call exc_read_rcblock(hcoup_fname,Bsp,is_resonant,diago_is_real,BSp%nsppol,Bsp%nreh,hsize,hexc%my_t1,hexc%my_t2,test,.FALSE.,comm)
     341            0 :      test = test-hexc%hcoup
     342            0 :      write(std_out,*)"DEBUG: Diff MPI-IO - Fortran ",MAXVAL(ABS(test))
     343            0 :      max_r=20; max_c=10
     344            0 :      write(std_out,*)" **** Testing coupling block **** "
     345            0 :      call print_arr([std_out], test,max_r=max_r,max_c=max_c)
     346            0 :      if (BSp%nsppol==2) then
     347            0 :        write(std_out,*)" **** D down down ****"
     348            0 :        call print_arr([std_out], test(hsize/2+1:,hsize/2+1:),max_r=max_r,max_c=max_c)
     349            0 :        write(std_out,*)" **** V up down ****"
     350            0 :        call print_arr([std_out], test(1:hsize/2,hsize/2+1:),max_r=max_r,max_c=max_c)
     351            0 :        write(std_out,*)" **** V down up ****"
     352            0 :        call print_arr([std_out], test(hsize/2+1:,1:hsize/2),max_r=max_r,max_c=max_c)
     353              :      end if
     354            0 :      ABI_FREE(test)
     355              :    end if
     356              :  end if
     357              : 
     358           23 :  if(BSp%prt_ncham .or. BSp%use_interp) then
     359              :    ! I want to store the diagonal part for future use (printing or interpolation) !
     360           12 :    ABI_MALLOC(hexc%diag_coarse,(hexc%hsize_coarse))
     361            4 :    spad=0
     362            8 :    do spin=1,BSp%nsppol
     363            4 :      if(spin==2) spad=BSp%nreh(1)
     364          392 :      do itt=1,BSp%nreh(spin) ! 1 is for spin 1
     365          388 :        hexc%diag_coarse(spad+itt) = Bsp%Trans(itt,spin)%en
     366              :      end do
     367              :    end do
     368              : 
     369            4 :    if (BSp%prt_ncham) then
     370            0 :      ncerr = nctk_open_create(ncid, trim(hexc%BS_files%out_basename)//"_HEXC.nc", xmpi_comm_self)
     371            0 :      NCF_CHECK_MSG(ncerr, "Creating HEXC file")
     372              :      call exc_ham_ncwrite(ncid, hexc%Kmesh_coarse, hexc%BSp, hexc%hsize_coarse, hexc%BSp%nreh, &
     373            0 : &         hexc%BSp%vcks2t,hexc%hreso,hexc%diag_coarse)
     374            0 :      NCF_CHECK(nf90_close(ncid))
     375              :    end if
     376              :  end if
     377              : 
     378           23 : end subroutine hexc_init
     379              : !!***
     380              : 
     381              : !-------------------------------------------------------------------
     382              : 
     383              : !!****f* m_hexc/hexc_interp_init
     384              : !! NAME
     385              : !! hexc_interp_init
     386              : !!
     387              : !! FUNCTION
     388              : !! Construct the hexc_interp object
     389              : !!
     390              : !! INPUTS
     391              : !! hexc<hexc_t>=Excitonic hamiltonian
     392              : !! Kmesh_dense<kmesh_t>=Kmesh info
     393              : !! Vcp_dense<vcoul_t>=Dense mesh info about coulomb
     394              : !! double_grid<double_grid_t>=Link between dense and coarse mesh
     395              : !! Wfd_dense<wfdgw_t>=Wavefunction descriptor
     396              : !! KS_BSt_dense<ebands_t>=Kohn-Sham band structure
     397              : !! QP_BSt_dense<ebands_t>=Quasi-Particle band structure
     398              : !! Psps <type(pseudopotential_type)>=variables related to pseudopotentials.
     399              : !! Pawtab(Cryst%ntypat*usepaw)<pawtab_type>=PAW tabulated starting data.
     400              : !! comm=communicator
     401              : !!
     402              : !! OUTPUT
     403              : !! hexc_i<hexc_interp_t>=Interpolated excitonic hamiltonian
     404              : !!
     405              : !! SIDE EFFECTS
     406              : !! hexc
     407              : !!   Will be modified so that the size of the problem is full interpolated hamiltonian
     408              : !! Wfd, Wfd_dense
     409              : !!   The memory might be modified by computing wavefunctions
     410              : !!
     411              : !! SOURCE
     412              : 
     413            4 : subroutine hexc_interp_init(hexc_i, hexc, m3_width, method, Kmesh_dense, Vcp_dense, &
     414            4 :                             double_grid, Wfd_dense, KS_BSt_dense, QP_BSt_dense, Psps, Pawtab)
     415              : 
     416              : !Arguments ---------------------------
     417              : !scalars
     418              :  class(hexc_interp_t),intent(inout) :: hexc_i
     419              :  integer,intent(in) :: method
     420              :  real(dp),intent(in) :: m3_width
     421              :  type(hexc_t),intent(inout) :: hexc
     422              :  type(double_grid_t),intent(in),target :: double_grid
     423              :  type(wfdgw_t),intent(inout),target :: Wfd_dense !, Wfd
     424              :  type(kmesh_t),intent(in),target :: Kmesh_dense
     425              :  type(pseudopotential_type),intent(in) :: Psps
     426              :  type(vcoul_t),intent(in),target :: Vcp_dense
     427              :  type(ebands_t),intent(in),target :: KS_BSt_dense, QP_BSt_dense
     428              : !arrays
     429              :  type(pawtab_type),intent(in) :: Pawtab(hexc%crystal%ntypat*hexc%Wfd_coarse%usepaw)
     430              : 
     431              : !Local variables ---------------------
     432              : !scalars
     433              :  integer,parameter :: spin1 = 1
     434              :  integer :: nsppol,ierr,ii,itt,nproc, my_rank,hsize
     435              :  real(dp),parameter :: threshold = 0.1_dp
     436            4 :  type(excparam) :: BSp
     437              :  logical :: is_resonant, diago_is_real, use_mpio
     438              : !arrays
     439              :  character(len=fnlen) :: tmpfname, hreso_fname
     440              : !*****************************************************************************
     441              : 
     442            4 :  BSp = hexc%bsp
     443            4 :  ABI_CHECK(BSp%nsppol == 1,"nsppol > 1 not implemented yet")
     444              : 
     445            4 :  hsize = hexc%hsize_coarse
     446              : 
     447            4 :  nproc  = xmpi_comm_size(hexc%comm); my_rank= xmpi_comm_rank(hexc%comm)
     448            4 :  nsppol = hexc%Bsp%nsppol
     449              : 
     450            4 :  ABI_CHECK(nproc == 1,"Parallelization not available in interpolation")
     451              : 
     452            4 :  hexc_i%m3_width = m3_width
     453              : 
     454            4 :  hexc_i%kmesh_dense => Kmesh_dense
     455            4 :  hexc_i%vcp_dense => Vcp_dense
     456            8 :  hexc_i%hsize_dense = SUM(BSp%nreh_interp)
     457            4 :  hexc%hsize = hexc_i%hsize_dense
     458            4 :  hexc%nbz = Kmesh_dense%nbz
     459              : 
     460            4 :  hexc%ks_bst => KS_BSt_dense
     461            4 :  hexc%qp_bst => QP_BSt_dense
     462            4 :  hexc%wfd => Wfd_dense
     463            4 :  hexc%kmesh => Kmesh_dense
     464              : 
     465              :  ! No parallelization !
     466            4 :  hexc%my_t1 = 1
     467            4 :  hexc%my_t2 = hexc_i%hsize_dense
     468              : 
     469              :  ! Initialize the interpolator
     470              :  call hexc_i%interpolator%init(double_grid, Wfd_dense, hexc%Wfd_coarse, Kmesh_dense, &
     471            4 :     hexc%Kmesh_coarse, hexc%BSp, hexc%crystal, Psps, Pawtab, method)
     472              : 
     473            4 :  if (BSp%sum_overlaps) call hexc_i%interpolator%normalize()
     474              : 
     475           12 :  ABI_MALLOC(hexc_i%kdense2div,(double_grid%nbz_dense))
     476           16 :  ABI_MALLOC(hexc_i%div2kdense,(double_grid%nbz_coarse,double_grid%ndiv))
     477              : 
     478            4 :  call compute_corresp(double_grid,hexc_i%div2kdense,hexc_i%kdense2div)
     479              : 
     480            4 :  if (any(BSp%interp_mode == [2,3])) then
     481              :    ! Read a, b, c coefficient matrices from file.
     482              :    ! For the time being, we read the full matrix in a temporary array, and
     483              :    ! then we store the data in a form suitable for the interpolation.
     484            2 :    is_resonant=.TRUE.; diago_is_real=(.not.BSp%have_complex_ene); use_mpio=.FALSE.
     485              : 
     486            2 :    if (hexc%bs_files%in_hreso /= BSE_NOFILE) then
     487            2 :      hreso_fname = hexc%bs_files%in_hreso
     488              :    else
     489            0 :      hreso_fname = hexc%bs_files%out_hreso
     490              :    end if
     491              : 
     492            2 :    tmpfname = hreso_fname; ii = LEN_TRIM(hreso_fname)
     493              : 
     494              :    ! TODO: Write new IO routines to read MPI-distributed data in a format suitable for the interpolation
     495            2 :    tmpfname(ii-2:ii+1) = 'ABSR'
     496            8 :    ABI_MALLOC_OR_DIE(hexc_i%all_acoeffs,(hsize,hsize), ierr)
     497              :    call exc_read_rcblock(tmpfname,Bsp,is_resonant,diago_is_real,nsppol,BSp%nreh,hsize,1,hsize,&
     498            2 :                          hexc_i%all_acoeffs,use_mpio,hexc%comm)
     499              : 
     500            2 :    tmpfname(ii-2:ii+1) = 'BBSR'
     501            6 :    ABI_MALLOC_OR_DIE(hexc_i%all_bcoeffs,(hsize,hsize), ierr)
     502              :    call exc_read_rcblock(tmpfname,Bsp,is_resonant,diago_is_real,nsppol,BSp%nreh,hsize,1,hsize,&
     503            2 :                          hexc_i%all_bcoeffs,use_mpio,hexc%comm)
     504              : 
     505            2 :    tmpfname(ii-2:ii+1) = 'CBSR'
     506            6 :    ABI_MALLOC_OR_DIE(hexc_i%all_ccoeffs,(hsize,hsize), ierr)
     507              :    call exc_read_rcblock(tmpfname,Bsp,is_resonant,diago_is_real,nsppol,BSp%nreh,hsize,1,hsize,&
     508            2 :                          hexc_i%all_ccoeffs,use_mpio,hexc%comm)
     509              :  end if
     510              : 
     511              :  ! Compute overlaps & compute all hmat
     512           16 :  ABI_MALLOC_OR_DIE(hexc_i%all_hmat,(hsize,hsize), ierr)
     513              : 
     514        37252 :  hexc_i%all_hmat(:,:) = hexc%hreso(:,:)
     515              : 
     516          388 :  do itt=1,hsize
     517          388 :    hexc_i%all_hmat(itt,itt) = hexc_i%all_hmat(itt,itt) - hexc%diag_coarse(itt)
     518              :  end do
     519              : 
     520              :  ! I don't need the diag_coarse any more
     521            4 :  ABI_FREE(hexc%diag_coarse)
     522              : 
     523              :  ! Compute diagonal part of the dense Ham
     524           12 :  ABI_MALLOC(hexc_i%diag_dense,(hexc_i%hsize_dense))
     525         3076 :  do itt=1,BSp%nreh_interp(spin1) ! 1 is for spin 1
     526         3076 :    hexc_i%diag_dense(itt) = Bsp%Trans_interp(itt,spin1)%en
     527              :  end do
     528              : 
     529            4 : end subroutine hexc_interp_init
     530              : !!***
     531              : 
     532              : !-------------------------------------------------------------------
     533              : 
     534              : !!****f* m_hexc/hexc_build_hinterp
     535              : !! NAME
     536              : !! hexc_build_hinterp
     537              : !!
     538              : !! FUNCTION
     539              : !! Pre-compute interpolated hamiltonian and store it in memory
     540              : !!
     541              : !! SIDE EFFECTS
     542              : !! hexc, hexc_i
     543              : !!   Pre-compute info to save CPU time when computing matmul
     544              : !!
     545              : !! SOURCE
     546              : 
     547            2 : subroutine hexc_build_hinterp(hexc, hexc_i)
     548              : 
     549              : !Arguments ---------------------------
     550              :  class(hexc_t),intent(inout) :: hexc
     551              :  class(hexc_interp_t),intent(inout) :: hexc_i
     552              : 
     553              : !Local variables ---------------------
     554              :  integer :: ierr,ncerr,ncid
     555              :  character(len=500) :: msg
     556              : !*****************************************************************************
     557              : 
     558            2 :  write(msg,"(a,f8.1,a)")"Memory needed for hinterp = ",one*(hexc_i%hsize_dense**2)*2*dp*b2Mb," Mb"
     559            2 :  call wrtout(std_out,msg,"COLL")
     560              : 
     561            8 :  ABI_MALLOC_OR_DIE(hexc_i%hinterp,(hexc_i%hsize_dense,hexc_i%hsize_dense), ierr)
     562              : 
     563              :  call hexc_compute_hinterp(hexc%BSp, hexc%hsize_coarse, hexc_i%hsize_dense, hexc_i%all_hmat, &
     564              :    hexc_i%interpolator%double_grid,hexc%nbnd_coarse, hexc_i%interpolator, &
     565              :    hexc_i%kdense2div, hexc_i%all_acoeffs,hexc_i%all_bcoeffs, hexc_i%all_ccoeffs, &
     566            2 :    hexc_i%Kmesh_dense, hexc_i%Vcp_dense, hexc%crystal%gmet, hexc_i%hinterp, hexc_i%m3_width)
     567              : 
     568            2 :  ABI_SFREE(hexc_i%all_acoeffs)
     569            2 :  ABI_SFREE(hexc_i%all_bcoeffs)
     570            2 :  ABI_SFREE(hexc_i%all_ccoeffs)
     571              : 
     572              : 
     573            2 :  if (hexc%BSp%prt_ncham) then
     574            0 :    ABI_COMMENT("Printing HEXC_I.nc file")
     575            0 :    ncerr = nctk_open_create(ncid, trim(hexc%BS_files%out_basename)//"_HEXC_I.nc", xmpi_comm_self)
     576            0 :    NCF_CHECK_MSG(ncerr, "Creating HEXC_I file")
     577              :    call exc_ham_ncwrite(ncid, hexc_i%Kmesh_dense, hexc%BSp, hexc_i%hsize_dense, hexc%BSp%nreh_interp, &
     578            0 :                         hexc%BSp%vcks2t_interp, hexc_i%hinterp, hexc_i%diag_dense)
     579            0 :    NCF_CHECK(nf90_close(ncid))
     580              :  end if
     581              : 
     582            2 : end subroutine hexc_build_hinterp
     583              : !!***
     584              : 
     585              : !-------------------------------------------------------------------
     586              : 
     587              : !!****f* m_hexc/hexc_compute_subhinterp
     588              : !! NAME
     589              : !! hexc_compute_subhinterp
     590              : !!
     591              : !! FUNCTION
     592              : !! Compute the interpolation for work_coeffs in dense mesh
     593              : !!
     594              : !! INPUTS
     595              : !! BSp<excparam>=Parameters for BS run
     596              : !! grid<double_grid_t>=Double grid info
     597              : !! nbnd_coarse=Number of bands (= nbndv * nbndc)
     598              : !! interpolator<interpolator_t>=Interpolation info
     599              : !! kdense2div=Mapping between dense point and coarse point
     600              : !! work_coeffs=Coefficients to be interpolated
     601              : !! ikp_dense=Current kpoint
     602              : !! overlaps=Wavefunction overlaps
     603              : !!
     604              : !! OUTPUT
     605              : !! Cmat(nbnd_coarse) = Interpolated coefficients
     606              : !!
     607              : !! SOURCE
     608              : 
     609      1397760 : subroutine hexc_compute_subhinterp(BSp,grid,nbnd_coarse,&
     610      1397760 :   interpolator,kdense2div,work_coeffs,Cmat,ikp_dense,overlaps)
     611              : 
     612              : !Arguments ------------------------------------
     613              : !scalars
     614              :  type(excparam),intent(in) :: BSp
     615              :  integer,intent(in) :: nbnd_coarse
     616              :  integer,intent(in) :: ikp_dense
     617              :  type(double_grid_t),intent(in) :: grid
     618              :  type(interpolator_t),target,intent(inout) :: interpolator
     619              : !arrays
     620              :  integer,intent(in) :: kdense2div(grid%nbz_dense)
     621              :  complex(gwp),intent(in) :: overlaps(interpolator%mband_coarse,interpolator%mband_dense,interpolator%nvert)
     622              :  complex(dp),intent(in) :: work_coeffs(nbnd_coarse,interpolator%nvert)
     623              :  complex(dp),intent(out) :: Cmat(nbnd_coarse)
     624              : 
     625              : !Local variables ------------------------------
     626              : !scalars
     627              :  integer,parameter :: spin1=1,spin2=1
     628              :  integer :: iv1,ic1
     629              :  integer :: icp,ivp,idivp,ibndp_coarse,ibndp_coarse1,ineighbourp
     630              :  integer :: indwithnb
     631              :  integer :: lumo2,lomo2,humo2,homo2
     632              :  complex(dp) :: tmp_val, tmp2, tmp4
     633              : !arrays
     634      1397760 :  complex(dp),contiguous, pointer :: btemp(:),ctemp(:)
     635              : !*********************************************************************
     636              : 
     637      1397760 :  btemp => interpolator%btemp
     638      1397760 :  ctemp => interpolator%ctemp
     639              : 
     640    135582720 :  btemp = czero
     641    135582720 :  ctemp = czero
     642              : 
     643      1397760 :  lumo2 = BSp%lumo_spin(spin2)
     644      1397760 :  lomo2 = BSp%lomo_spin(spin2)
     645      1397760 :  humo2 = BSp%humo_spin(spin2)
     646      1397760 :  homo2 = BSp%homo_spin(spin2)
     647              : 
     648     18170880 :  Cmat = czero
     649              : 
     650      1397760 :  idivp = kdense2div(ikp_dense)
     651              : 
     652     12579840 :  do ineighbourp = 1,interpolator%nvert
     653              : 
     654              :    btemp(((ineighbourp-1)*nbnd_coarse+1):(ineighbourp*nbnd_coarse)) = &
     655    146764800 :            interpolator%interp_factors(ineighbourp,idivp)*work_coeffs(:,ineighbourp)
     656              : 
     657              :  end do !ineighbourp
     658              : 
     659              :  ! Loop over the (c', v') part of the right transition
     660      5591040 :  do ivp = lomo2,homo2
     661     22364160 :    do icp = lumo2,humo2
     662              : 
     663     16773120 :      ibndp_coarse = (ivp-lomo2)*BSp%maxnbndc+(icp-lumo2+1)
     664              :      ! Now we now it_dense, and itp_dense
     665              : 
     666    150958080 :      do ineighbourp = 1,interpolator%nvert
     667    553512960 :        do iv1 = lomo2, homo2
     668              :          ! BSp%lumo_spin(spin2),BSp%humo_spin(spin2)
     669    402554880 :          tmp4 = overlaps(iv1,ivp,ineighbourp)
     670              : 
     671   2146959360 :          do ic1 = lumo2,humo2
     672   1610219520 :            tmp2 = GWPC_CONJG(overlaps(ic1,icp,ineighbourp))
     673              :            ! BSp%lomo_spin(spin2),BSp%homo_spin(spin2)
     674              : 
     675   1610219520 :            ibndp_coarse1 = (iv1-lomo2)*BSp%maxnbndc+(ic1-lumo2+1)
     676   1610219520 :            indwithnb = (ineighbourp-1)*nbnd_coarse+ibndp_coarse1
     677              : 
     678   2012774400 :            ctemp(indwithnb) = tmp4 * tmp2
     679              :          end do ! iv1
     680              :        end do ! ic1
     681              :      end do ! ineighbourp
     682              : 
     683     16773120 :      tmp_val = xdotc(interpolator%nvert*nbnd_coarse,ctemp,1,btemp,1)
     684              :      !tmp_val = DOT_PRODUCT(ctemp,btemp)
     685              : 
     686     20966400 :      Cmat(ibndp_coarse) = tmp_val
     687              :    end do !ivp
     688              :  end do !icp
     689              : 
     690      1397760 :  nullify(btemp)
     691      1397760 :  nullify(ctemp)
     692              : 
     693      1397760 : end subroutine hexc_compute_subhinterp
     694              : !!***
     695              : 
     696              : !----------------------------------------------------------------------
     697              : 
     698              : !!****f* m_hexc/hexc_compute_hinterp
     699              : !! NAME
     700              : !! hexc_compute_hinterp
     701              : !!
     702              : !! FUNCTION
     703              : !! Compute interpolated matrix elements for methods 2 and 3
     704              : !!
     705              : !! INPUTS
     706              : !! BSp<type(excparam)=The parameter for the Bethe-Salpeter run.
     707              : !! hsize_coarse=Size of the coarse Hamiltonian
     708              : !! hsize_dense=Size of the dense Hamiltonian
     709              : !! hmat(hsize_coarse,hsize_coarse,8)=Excitonic matrix
     710              : !! grid<double_grid_t> = Correspondence between coarse and dense k-mesh.
     711              : !! nbnd_coarse = Total number of bands
     712              : !! interpolator<interpolator_t> = Interpolator
     713              : !! kdense2div = Mapping kdense2div
     714              : !! acoeffs, bcoeffs, ccoeffs = decomposition "W = a/q^2 + b/q + c"
     715              : !! Kmesh_dense<type(kmesh_t)>=The list of k-points in the BZ, IBZ and symmetry tables.
     716              : !! Vcp_dense<vcoul_t>=Coulomb interation in G-space on the dense Q-mesh
     717              : !! gmet(3,3)=Metric tensor in G-space
     718              : !!
     719              : !! OUTPUT
     720              : !!   hinterp = Interpolated hamiltonian
     721              : !!
     722              : !! SOURCE
     723              : 
     724            2 : subroutine hexc_compute_hinterp(BSp,hsize_coarse,hsize_dense,hmat,grid,nbnd_coarse,&
     725            2 : &  interpolator,kdense2div,acoeffs,bcoeffs,ccoeffs,Kmesh_dense,Vcp_dense,gmet,hinterp,&
     726              : &  m3_width)
     727              : 
     728              : !Arguments ------------------------------------
     729              : !scalars
     730              :  integer,intent(in) :: hsize_coarse,hsize_dense,nbnd_coarse !,ntrans
     731              :  real(dp),intent(in) :: m3_width
     732              :  type(excparam),intent(in) :: BSp
     733              :  type(double_grid_t),intent(in) :: grid
     734              :  type(vcoul_t),intent(in) :: Vcp_dense
     735              :  type(kmesh_t),intent(in) :: Kmesh_dense
     736              :  type(interpolator_t),target,intent(inout) :: interpolator
     737              : !arrays
     738              :  integer,intent(in) :: kdense2div(grid%nbz_dense)
     739              :  real(dp),intent(in) :: gmet(3,3)
     740              :  complex(dp),intent(in) :: hmat(hsize_coarse,hsize_coarse)
     741              :  complex(dp),intent(in) :: acoeffs(hsize_coarse,hsize_coarse)
     742              :  complex(dp),intent(in) :: bcoeffs(hsize_coarse,hsize_coarse)
     743              :  complex(dp),intent(in) :: ccoeffs(hsize_coarse,hsize_coarse)
     744              :  complex(dp),intent(out) :: hinterp(hsize_dense,hsize_dense)
     745              : 
     746              : !Local variables ------------------------------
     747              : !scalars
     748              :  integer,parameter :: spin1=1, spin2=1
     749              :  integer :: ic,iv,iv1,ic1,ik_dense,ik_coarse,it_coarse,it_dense,idiv,ibnd_coarse,ibnd_coarse1,ineighbour
     750              :  integer :: icp,ivp,ikp_dense,ikp_coarse,itp_coarse,itp_dense,idivp,ibndp_coarse,ibndp_coarse1,ineighbourp,itp_coarse1
     751              :  integer :: itc,it_dense1,indwithnb, corresp_ind, limitnbz, inb,ierr
     752              :  real(dp) :: factor,vc_sqrt_qbz,qnorm
     753              :  complex(dp) :: term
     754              :  logical :: newway, use_herm
     755              : !arrays
     756              :  real(dp) :: kmkp(3),q2(3),shift(3),qinred(3),tsec(2)
     757            2 :  complex(dp),allocatable :: Cmat(:,:,:) !Temp matrices for optimized version
     758            2 :  complex(dp),allocatable :: tmp_Cmat(:)
     759            2 :  complex(dp),allocatable :: work_coeffs(:,:)
     760            2 :  integer,allocatable :: band2it(:)
     761            2 :  complex(dp),contiguous, pointer :: btemp(:),ctemp(:)
     762              : !************************************************************************
     763              : 
     764            2 :  call timab(696,1,tsec)
     765              : 
     766            2 :  newway = .True.
     767            2 :  use_herm = .True.
     768              : 
     769            2 :  if (any(BSp%interp_mode == [2,3])) then
     770            2 :    if (Vcp_dense%mode /= 'CRYSTAL' .and. Vcp_dense%mode /= 'AUXILIARY_FUNCTION') then
     771            0 :      ABI_ERROR('Vcp_dense%mode not implemented yet !')
     772              :    end if
     773              :  end if
     774              : 
     775            2 :  if (BSp%nsppol > 1) then
     776            0 :    ABI_ERROR("nsppol > 1 not yet implemented")
     777              :  end if
     778              : 
     779            2 :  factor = one/grid%ndiv
     780              : 
     781      1181186 :  hinterp = czero; term = czero
     782              : 
     783           10 :  ABI_MALLOC_OR_DIE(Cmat,(nbnd_coarse,nbnd_coarse,interpolator%nvert), ierr)
     784         2514 :  Cmat = czero
     785              : 
     786            6 :  ABI_MALLOC(band2it,(nbnd_coarse))
     787            2 :  call interpolator%alloc_work(nbnd_coarse*interpolator%nvert)
     788              : 
     789            2 :  btemp => interpolator%btemp
     790            2 :  ctemp => interpolator%ctemp
     791              : 
     792              :  if(newway) then
     793            6 :    ABI_MALLOC(tmp_Cmat,(nbnd_coarse))
     794            8 :    ABI_MALLOC(work_coeffs,(nbnd_coarse,interpolator%nvert))
     795              :  end if
     796              : 
     797          130 :  do ik_dense = 1,grid%nbz_dense
     798          128 :    write(std_out,*) "Kdense = ",ik_dense,"/",grid%nbz_dense
     799          128 :    ik_coarse = grid%dense_to_coarse(ik_dense)
     800              :    if(use_herm) then
     801              :      limitnbz = ik_dense
     802              :    else
     803              :      limitnbz = grid%nbz_dense
     804              :    end if
     805              : 
     806         4290 :    do ikp_dense = 1,limitnbz
     807         4160 :      ikp_coarse = grid%dense_to_coarse(ikp_dense)
     808              : 
     809        16640 :      do iv1 = BSp%lomo_spin(spin2),BSp%homo_spin(spin2)
     810        66560 :        do ic1 = BSp%lumo_spin(spin2),BSp%humo_spin(spin2)
     811        49920 :          itp_coarse1 = BSp%vcks2t(iv1,ic1,ikp_coarse,spin2)
     812        49920 :          ibndp_coarse1 = (iv1-BSp%lomo_spin(spin2))*BSp%maxnbndc+(ic1-BSp%lumo_spin(spin2)+1)
     813              : 
     814        62400 :          band2it(ibndp_coarse1) = itp_coarse1
     815              :        end do
     816              :      end do
     817              : 
     818              : 
     819         4160 :      if (any(BSp%interp_mode == [2,3])) then
     820              :        ! Check if we are along the diagonal
     821        16640 :        kmkp = Kmesh_dense%bz(:,ik_dense) - Kmesh_dense%bz(:,ikp_dense)
     822              : 
     823        16640 :        call wrap2_pmhalf(kmkp(:),q2(:),shift(:))
     824       104000 :        qinred = MATMUL(grid%kptrlatt_coarse,q2)
     825              : 
     826              :        ! We are outside the diagonal
     827        16640 :        if (BSp%interp_mode==3 .and. ANY((ABS(qinred)-tol7) > m3_width)) cycle
     828              : 
     829        66560 :        qnorm = two_pi*SQRT(DOT_PRODUCT(q2,MATMUL(gmet,q2)))
     830              : 
     831         5696 :        if(ALL(ABS(q2(:)) < 1.e-3)) then
     832          128 :          vc_sqrt_qbz = SQRT(Vcp_dense%i_sz)
     833              :        else
     834         4032 :          vc_sqrt_qbz = SQRT(four_pi/qnorm**2)
     835              :        end if
     836              : 
     837              :        !!DEBUG CHK !
     838              :        !!COMPUTE Qpoint
     839              :        !call findqg0(iq_bz,g0,kmkp,Qmesh_dense%nbz,Qmesh_dense%bz,BSp%mG0)
     840              : 
     841              :        !! * Get iq_ibz, and symmetries from iq_bz
     842              :        !call qmesh_dense%get_BZ_item(Qmesh_dense,iq_bz,qbz,iq_ibz,isym_q,itim_q)
     843              : 
     844              :        !if(iq_ibz > 1 .and. ABS(vc_sqrt_qbz - Vcp_dense%vc_sqrt(1,iq_ibz)) > 1.e-3) then
     845              :        !   write(*,*) "vc_sqrt_qbz = ",vc_sqrt_qbz
     846              :        !   write(*,*) "Vcp_dense%vc_sqrt(1,iq_ibz) = ",Vcp_dense%vc_sqrt(1,iq_ibz)
     847              :        !   ABI_ERROR("vcp are not the same !")
     848              :        !else if(iq_ibz == 1 .and. ABS(vc_sqrt_qbz - SQRT(Vcp_dense%i_sz)) > 1.e-3) then
     849              :        !   write(*,*) "vc_sqrt_qbz = ",vc_sqrt_qbz
     850              :        !   write(*,*) "SQRT(Vcp_dense%i_sz) = ",SQRT(Vcp_dense%i_sz)
     851              :        !   ABI_ERROR("vcp are not the same !")
     852              :        !end if
     853              :        !!END DEBUG CHK !
     854              :      end if
     855              : 
     856              :      if(newway) then
     857              : 
     858      5229120 :        Cmat = czero
     859              : 
     860       436800 :        work_coeffs = czero
     861              : 
     862        37440 :        do ineighbour = 1,interpolator%nvert
     863              : 
     864              :          ! Loop over the (c, v) part of the left transition
     865       137280 :          do iv = BSp%lomo_spin(spin1),BSp%homo_spin(spin1)
     866       532480 :            do ic = BSp%lumo_spin(spin1),BSp%humo_spin(spin1)
     867              : 
     868       399360 :              it_dense = BSp%vcks2t_interp(iv,ic,ik_dense,spin1)
     869       399360 :              it_coarse = BSp%vcks2t(iv,ic,ik_coarse,spin1)
     870       399360 :              ibnd_coarse = (iv-BSp%lomo_spin(spin1))*BSp%maxnbndc+(ic-BSp%lumo_spin(spin1)+1)
     871              : 
     872       399360 :              itc = interpolator%corresp(it_coarse,ineighbour,spin1)
     873              : 
     874       399360 :              if (any(BSp%interp_mode == [1,3,4])) then
     875              : 
     876              :                !work_coeffs(:,:) = hmat(itc,band2it(:),:)
     877      1797120 :                do inb = 1,interpolator%nvert
     878     40135680 :                  work_coeffs(:,inb) = hmat(itc,interpolator%corresp(band2it(:),inb,spin2))
     879              :                end do
     880              : 
     881              :                call hexc_compute_subhinterp(BSp,grid,nbnd_coarse,&
     882              : &        interpolator,kdense2div,&
     883              : &        work_coeffs,tmp_Cmat,ikp_dense,&
     884       199680 : &        interpolator%overlaps(:,:,:,ikp_dense,spin2))
     885              : 
     886       199680 :                if(any(BSp%interp_mode == [1,4])) then
     887            0 :                  Cmat(ibnd_coarse,:,ineighbour) = tmp_Cmat
     888       199680 :                else if (BSp%interp_mode == 3) then
     889      2595840 :                  Cmat(ibnd_coarse,:,ineighbour) = -tmp_Cmat
     890              :                end if
     891              :              end if
     892              : 
     893              : 
     894       399360 :              if (any(BSp%interp_mode == [2,3])) then
     895              :                !work_coeffs(:,:) = acoeffs(itc,band2it(:),:)
     896      3594240 :                do inb = 1,interpolator%nvert
     897     80271360 :                  work_coeffs(:,inb) = acoeffs(itc,interpolator%corresp(band2it(:),inb,spin2))
     898              :                end do
     899              : 
     900              :                call hexc_compute_subhinterp(BSp,grid,nbnd_coarse,&
     901              : &        interpolator,kdense2div,&
     902              : &        work_coeffs,tmp_Cmat,ikp_dense,&
     903       399360 : &        interpolator%overlaps(:,:,:,ikp_dense,spin2))
     904              : 
     905      5191680 :                tmp_Cmat = tmp_Cmat * (vc_sqrt_qbz**2)
     906      5191680 :                Cmat(ibnd_coarse,:,ineighbour) = Cmat(ibnd_coarse,:,ineighbour) + tmp_Cmat
     907              :              end if
     908              : 
     909              : 
     910       399360 :              if (any(BSp%interp_mode == [2,3])) then
     911              :                !work_coeffs(:,:) = bcoeffs(itc,band2it(:),:)
     912      3594240 :                do inb = 1,interpolator%nvert
     913     80271360 :                  work_coeffs(:,inb) = bcoeffs(itc,interpolator%corresp(band2it(:),inb,spin2))
     914              :                end do
     915              : 
     916              :                call hexc_compute_subhinterp(BSp,grid,nbnd_coarse,&
     917              : &        interpolator,kdense2div,&
     918              : &        work_coeffs,tmp_Cmat,ikp_dense,&
     919       399360 : &        interpolator%overlaps(:,:,:,ikp_dense,spin2))
     920              : 
     921      5191680 :                tmp_Cmat = tmp_Cmat * (vc_sqrt_qbz)
     922      5191680 :                Cmat(ibnd_coarse,:,ineighbour) = Cmat(ibnd_coarse,:,ineighbour) + tmp_Cmat
     923              :              end if
     924              : 
     925              : 
     926       499200 :              if (any(BSp%interp_mode == [2,3])) then
     927              :                !work_coeffs(:,:) = ccoeffs(itc,band2it(:),:)
     928      3594240 :                do inb = 1,interpolator%nvert
     929     80271360 :                  work_coeffs(:,inb) = ccoeffs(itc,interpolator%corresp(band2it(:),inb,spin2))
     930              :                end do
     931              : 
     932              :                call hexc_compute_subhinterp(BSp,grid,nbnd_coarse,&
     933              : &        interpolator,kdense2div,&
     934              : &        work_coeffs,tmp_Cmat,ikp_dense,&
     935       399360 : &        interpolator%overlaps(:,:,:,ikp_dense,spin2))
     936              : 
     937      5191680 :                Cmat(ibnd_coarse,:,ineighbour) = Cmat(ibnd_coarse,:,ineighbour) + tmp_Cmat
     938              :              end if
     939              :            end do ! ic
     940              :          end do ! iv
     941              :        end do ! ineighbour
     942              : 
     943              :      else
     944              :        ! Loop over the (c, v) part of the left transition
     945              :        do iv = BSp%lomo_spin(spin1),BSp%homo_spin(spin1)
     946              :          do ic = BSp%lumo_spin(spin1),BSp%humo_spin(spin1)
     947              : 
     948              :            it_dense = BSp%vcks2t_interp(iv,ic,ik_dense,spin1)
     949              :            it_coarse = BSp%vcks2t(iv,ic,ik_coarse,spin1)
     950              :            ibnd_coarse = (iv-BSp%lomo_spin(spin1))*BSp%maxnbndc+(ic-BSp%lumo_spin(spin1)+1)
     951              : 
     952              :            ! Loop over the (c', v') part of the right transition
     953              :            do ivp = BSp%lomo_spin(spin2),BSp%homo_spin(spin2)
     954              :              do icp = BSp%lumo_spin(spin2),BSp%humo_spin(spin2)
     955              : 
     956              :                itp_dense = BSp%vcks2t_interp(ivp,icp,ikp_dense,spin2)
     957              :                itp_coarse = BSp%vcks2t(ivp,icp,ikp_coarse,spin2)
     958              :                ibndp_coarse = (ivp-Bsp%lomo_spin(spin2))*BSp%maxnbndc+(icp-BSp%lumo_spin(spin2)+1)
     959              :                ! Now we now it_dense, and itp_dense
     960              : 
     961              :                idivp = kdense2div(ikp_dense)
     962              : 
     963              :                btemp = czero; ctemp = czero
     964              : 
     965              :                ! MG TODO: This way of looping is not optimal
     966              :                do ineighbour = 1,interpolator%nvert
     967              :                  itc = interpolator%corresp(it_coarse,ineighbour,spin1)
     968              : 
     969              :                  do ineighbourp = 1,interpolator%nvert
     970              : 
     971              :                    do iv1 = BSp%lomo_spin(spin2),BSp%homo_spin(spin2)
     972              :                      do ic1 = BSp%lumo_spin(spin2),BSp%humo_spin(spin2)
     973              : 
     974              :                        ibndp_coarse1 = (iv1-BSp%lomo_spin(spin2))*BSp%maxnbndc+(ic1-BSp%lumo_spin(spin2)+1)
     975              :                        indwithnb = (ineighbourp-1)*nbnd_coarse+ibndp_coarse1
     976              :                        itp_coarse1 = BSp%vcks2t(iv1,ic1,ikp_coarse,spin2)
     977              :                        corresp_ind = interpolator%corresp(itp_coarse1,ineighbourp,spin2)
     978              : 
     979              :                        select case (BSp%interp_mode)
     980              :                        case (1,4)
     981              :                          interpolator%btemp(indwithnb) = hmat(itc,corresp_ind)
     982              :                        case (2)
     983              :                          interpolator%btemp(indwithnb) = acoeffs(itc,corresp_ind)*(vc_sqrt_qbz**2) &
     984              : &                                         + bcoeffs(itc,corresp_ind)*(vc_sqrt_qbz) &
     985              : &                                         + ccoeffs(itc,corresp_ind)
     986              :                        case (3)
     987              :                          ! Diff between divergence and hmat
     988              :                          interpolator%btemp(indwithnb) = acoeffs(itc,corresp_ind)*(vc_sqrt_qbz**2) &
     989              : &                                         + bcoeffs(itc,corresp_ind)*(vc_sqrt_qbz) &
     990              : &                                         + ccoeffs(itc,corresp_ind) &
     991              : &                                         - hmat(itc,corresp_ind)
     992              :                        case default
     993              :                          ABI_ERROR("Wrong Bsp%interp_mode")
     994              :                        end select
     995              : 
     996              :                        ctemp(indwithnb) = &
     997              : &                        interpolator%overlaps(iv1,ivp,ineighbourp,ikp_dense,spin2) &
     998              : &                        * GWPC_CONJG(interpolator%overlaps(ic1,icp,ineighbourp,ikp_dense,spin2)) &
     999              : &                        *interpolator%interp_factors(ineighbourp,idivp)
    1000              :                      end do ! ic1
    1001              :                    end do !iv1
    1002              : 
    1003              :                  end do !ineighbourp
    1004              :                  Cmat(ibnd_coarse,ibndp_coarse,ineighbour) = xdotc(interpolator%nvert*nbnd_coarse,&
    1005              : &                                   ctemp,1,btemp,1)
    1006              :                end do !ineighbour
    1007              : 
    1008              :              end do !icp
    1009              :            end do !ivp
    1010              : 
    1011              :          end do !ic
    1012              :        end do !iv
    1013              : 
    1014              :      end if
    1015              : 
    1016        16768 :      do iv = BSp%lomo_spin(spin1),BSp%homo_spin(spin1)
    1017        66560 :        do ic = BSp%lumo_spin(spin1),BSp%humo_spin(spin1)
    1018        49920 :          it_dense = BSp%vcks2t_interp(iv,ic,ik_dense,spin1)
    1019        49920 :          it_coarse = BSp%vcks2t(iv,ic,ik_coarse,spin1)
    1020        49920 :          ibnd_coarse = (iv-BSp%lomo_spin(spin1))*BSp%maxnbndc+(ic-BSp%lumo_spin(spin1)+1)
    1021              : 
    1022        49920 :          idiv = kdense2div(ik_dense)
    1023              : 
    1024       212160 :          do ivp = BSp%lomo_spin(spin2),BSp%homo_spin(spin2)
    1025       798720 :            do icp = BSp%lumo_spin(spin2),BSp%humo_spin(spin2)
    1026       599040 :              itp_dense = BSp%vcks2t_interp(ivp,icp,ikp_dense,spin2)
    1027       599040 :              itp_coarse = BSp%vcks2t(ivp,icp,ikp_coarse,spin2)
    1028       599040 :              ibndp_coarse = (ivp-Bsp%lomo_spin(spin2))*BSp%maxnbndc+(icp-BSp%lumo_spin(spin2)+1)
    1029              : 
    1030              :              ! Hermicity
    1031              :              if(use_herm .and. it_dense < itp_dense) then
    1032              :                continue
    1033              :              end if
    1034              : 
    1035              :              !btemp = czero; ctemp = czero
    1036              : 
    1037      5391360 :              do ineighbour = 1,interpolator%nvert
    1038     19768320 :                do iv1 = BSp%lomo_spin(spin1),BSp%homo_spin(spin1)
    1039     76677120 :                  do ic1 = BSp%lumo_spin(spin1),BSp%humo_spin(spin1)
    1040     57507840 :                    ibnd_coarse1 = (iv1-BSp%lomo_spin(spin1))*BSp%maxnbndc+(ic1-BSp%lumo_spin(spin1)+1)
    1041     57507840 :                    it_dense1 = BSp%vcks2t_interp(iv1,ic1,ik_dense,spin1)
    1042     57507840 :                    indwithnb = (ineighbour-1)*nbnd_coarse+ibnd_coarse1
    1043              : 
    1044     57507840 :                    btemp(indwithnb) = Cmat(ibnd_coarse1,ibndp_coarse,ineighbour)
    1045              : 
    1046              :                    ctemp(indwithnb) = GWPC_CONJG(interpolator%overlaps(iv1,iv,ineighbour,ik_dense,spin1)) &
    1047              : &                                    *interpolator%overlaps(ic1,ic,ineighbour,ik_dense,spin1) &
    1048     71884800 : &                                    *interpolator%interp_factors(ineighbour,idiv)
    1049              :                  end do !ic1
    1050              :                end do !iv1
    1051              :              end do !ineighbour
    1052              : 
    1053              :              ! Save interpolated value.
    1054       748800 :              hinterp(it_dense,itp_dense) = xdotc(interpolator%nvert*nbnd_coarse,ctemp,1,btemp,1)
    1055              :              !DOT_PRODUCT(ctemp,btemp)
    1056              : 
    1057              :            end do !icp
    1058              :          end do !ivp
    1059              : 
    1060              :        end do !ic
    1061              :      end do !iv
    1062              : 
    1063              :    end do !ikp
    1064              :  end do !ik
    1065              : 
    1066              :  ! Enforce hermiticity
    1067              :  if(use_herm) then
    1068         1538 :    do itp_dense = 1,BSp%nreh_interp(spin2)
    1069       592130 :      do it_dense = itp_dense,BSp%nreh_interp(spin1)
    1070       592128 :        if(it_dense == itp_dense) then
    1071         1536 :          hinterp(itp_dense,it_dense) = DBLE(hinterp(it_dense,itp_dense))
    1072              :        else
    1073       589056 :          hinterp(itp_dense,it_dense) = CONJG(hinterp(it_dense,itp_dense))
    1074              :        end if
    1075              :      end do
    1076              :    end do
    1077              :  end if
    1078              : 
    1079            2 :  ABI_FREE(Cmat)
    1080            2 :  ABI_FREE(band2it)
    1081              : 
    1082            2 :  ABI_SFREE(tmp_Cmat)
    1083            2 :  ABI_SFREE(work_coeffs)
    1084              : 
    1085            2 :  nullify(ctemp)
    1086            2 :  nullify(btemp)
    1087            2 :  call interpolator%int_free()
    1088              : 
    1089      1181186 :  hinterp = hinterp*factor
    1090              : 
    1091            2 :  call timab(696,2,tsec)
    1092              : 
    1093            2 : end subroutine hexc_compute_hinterp
    1094              : !!***
    1095              : 
    1096              : !----------------------------------------------------------------------
    1097              : 
    1098              : !!****f* m_hexc/hexc_free
    1099              : !! NAME
    1100              : !! hexc_free
    1101              : !!
    1102              : !! FUNCTION
    1103              : !! Destroy the interpolator object in memory
    1104              : !!
    1105              : !! SOURCE
    1106              : 
    1107           23 : subroutine hexc_free(hexc)
    1108              : 
    1109              : !Arguments ---------------------------
    1110              :  class(hexc_t),intent(inout) :: hexc
    1111              : !*****************************************************************************
    1112              : 
    1113           23 :  if (associated(hexc%bsp)) then
    1114           23 :    nullify(hexc%bsp)
    1115              :  end if
    1116              : 
    1117           23 :  if (associated(hexc%crystal)) then
    1118           23 :    nullify(hexc%crystal)
    1119              :  end if
    1120              : 
    1121           23 :  if (associated(hexc%kmesh_coarse)) then
    1122           23 :    nullify(hexc%kmesh_coarse)
    1123              :  end if
    1124              : 
    1125           23 :  ABI_SFREE(hexc%hreso)
    1126           23 :  ABI_SFREE(hexc%hcoup)
    1127           23 :  ABI_SFREE(hexc%diag_coarse)
    1128              : 
    1129           23 : end subroutine hexc_free
    1130              : !!***
    1131              : 
    1132              : !-------------------------------------------------------------------
    1133              : 
    1134              : !!****f* m_hexc/hexc_interp_free
    1135              : !! NAME
    1136              : !! hexc_interp_free
    1137              : !!
    1138              : !! FUNCTION
    1139              : !!  Free dynamic memory.
    1140              : !!
    1141              : !! SOURCE
    1142              : 
    1143           23 : subroutine hexc_interp_free(hexc_i)
    1144              : 
    1145              : !Arguments ---------------------------
    1146              :  class(hexc_interp_t),intent(inout) :: hexc_i
    1147              : !*****************************************************************************
    1148              : 
    1149           23 :  ABI_SFREE(hexc_i%kdense2div)
    1150           23 :  ABI_SFREE(hexc_i%div2kdense)
    1151           23 :  ABI_SFREE(hexc_i%diag_dense)
    1152           23 :  ABI_SFREE(hexc_i%hinterp)
    1153           23 :  ABI_SFREE(hexc_i%all_hmat)
    1154           23 :  ABI_SFREE(hexc_i%all_acoeffs)
    1155           23 :  ABI_SFREE(hexc_i%all_bcoeffs)
    1156           23 :  ABI_SFREE(hexc_i%all_ccoeffs)
    1157              : 
    1158           23 :  if (associated(hexc_i%kmesh_dense)) then
    1159            4 :    nullify(hexc_i%kmesh_dense)
    1160              :  end if
    1161              : 
    1162           23 :  if (associated(hexc_i%vcp_dense)) then
    1163            4 :    nullify(hexc_i%vcp_dense)
    1164              :  end if
    1165              : 
    1166           23 :  call hexc_i%interpolator%free()
    1167              : 
    1168           23 : end subroutine hexc_interp_free
    1169              : !!***
    1170              : 
    1171              : !----------------------------------------------------------------------
    1172              : 
    1173              : !!****f* m_hexc/hexc_interp_matmul
    1174              : !! NAME
    1175              : !! hexc_interp_matmul
    1176              : !!
    1177              : !! FUNCTION
    1178              : !! Compute matrix-vector product Hmat * phi by interpolating coarse Hmat
    1179              : !!
    1180              : !! INPUTS
    1181              : !!  BSp<type(excparam)>=Parameters defining the BS calculation
    1182              : !!  hsize_coarse = Size of the coarse hamiltonian
    1183              : !!  hsize_dense = Size of the dense hamiltonian
    1184              : !!  hmat(hsize_coarse,hsize_coarse,8) = coarse hamiltonian
    1185              : !!  phi(hsize_dense) = ket on which apply the matrix
    1186              : !!  grid <double_grid_t> = Correspondence between coarse and dense k-mesh.
    1187              : !!  nbnd_coarse = Total number of bands
    1188              : !!  interpolator<interpolator_t> = Interpolator
    1189              : !!  div2kdense = Mapping from coarse and division -> dense mesh
    1190              : !!  kdense2div = Mapping from dense mesh -> division
    1191              : !!
    1192              : !! OUTPUT
    1193              : !!  hphi(hsize_dense) = Interp(hmat)*phi
    1194              : !!
    1195              : !! SOURCE
    1196              : 
    1197         3259 : subroutine hexc_interp_matmul(BSp,hsize_coarse,hsize_dense,hmat,phi,hphi,grid,&
    1198         3259 :                               nbnd_coarse,interpolator,div2kdense,kdense2div)
    1199              : 
    1200              : !Arguments ------------------------------------
    1201              : !scalars
    1202              :  integer,intent(in) :: hsize_coarse,hsize_dense,nbnd_coarse !,ntrans
    1203              :  type(excparam),intent(in) :: BSp
    1204              :  type(double_grid_t),intent(in) :: grid
    1205              :  type(interpolator_t),intent(in) :: interpolator
    1206              : !arrays
    1207              :  integer,intent(in) :: div2kdense(grid%nbz_coarse,grid%ndiv), kdense2div(grid%nbz_dense)
    1208              :  complex(dp),intent(in) :: phi(hsize_dense)
    1209              :  complex(dp),intent(in) :: hmat(hsize_coarse,hsize_coarse)
    1210              :  complex(dp),intent(inout) :: hphi(hsize_dense)
    1211              : 
    1212              : !Local variables ------------------------------
    1213              : !scalars
    1214              :  integer :: itt,ik_dense,ik_coarse,it_coarse, ic,iv,iv1,ic1, ibnd_coarse
    1215              :  integer :: ibnd_coarse1, ineighbour,idense,ikpt
    1216              :  integer :: my_k1,my_k2,ind_with_nb,is, is1
    1217              :  real(dp) :: factor
    1218              :  complex(dp) :: tmp
    1219              :  logical,parameter :: use_blas=.True.
    1220              : !arrays
    1221         6518 :  integer :: allindices(nbnd_coarse)
    1222         6518 :  complex(dp) :: allp(hsize_coarse,interpolator%nvert), test(hsize_coarse)
    1223         6518 :  complex(dp) :: ophi(grid%nbz_dense,interpolator%nvert,nbnd_coarse)
    1224         3259 :  complex(dp),allocatable :: b(:), c(:),A(:,:), tmp_array(:), tmp_array2(:,:)
    1225              : !************************************************************************
    1226              : 
    1227         3259 :  factor = one/grid%ndiv
    1228              :  !hphi = czero
    1229              : 
    1230              :  ! Outer index : k point in the dense zone
    1231              :  ! Sum over vc
    1232              :  ! Index of result : k point in the dense zone, v2,c2,neighbour
    1233              : 
    1234              :  ! Parallelization on nbz in the coarse mesh !
    1235         3259 :  my_k1 = 1
    1236         3259 :  my_k2 = grid%nbz_coarse
    1237              : 
    1238        13036 :  ABI_MALLOC(A,(interpolator%nvert*nbnd_coarse,nbnd_coarse))
    1239         9777 :  ABI_MALLOC(b,(nbnd_coarse))
    1240         9777 :  ABI_MALLOC(c,(interpolator%nvert*nbnd_coarse))
    1241              : 
    1242     14673866 :  c = czero; ophi = czero
    1243              : 
    1244       211835 :  do ik_dense = 1,grid%nbz_dense
    1245              :    ! if( ik_dense is not in my set of k-points)
    1246              :    !   ! continue
    1247              :    !
    1248       417152 :    do is1 = 1, BSp%nsppol
    1249      1042880 :      do iv1 = BSp%lomo_spin(is1),Bsp%homo_spin(is1)
    1250      3337216 :        do ic1 = BSp%lumo_spin(is1),Bsp%humo_spin(is1)
    1251      2502912 :          ibnd_coarse = (iv1-BSp%lomo_spin(is1))*BSp%maxnbndc+(ic1-BSp%lumo_spin(is1)+1)
    1252      2502912 :          itt = BSp%vcks2t_interp(iv1,ic1,ik_dense,is1)
    1253      3128640 :          allindices(ibnd_coarse) = itt
    1254              :        end do !ic1
    1255              :      end do !iv1
    1256              :    end do !is1
    1257              : 
    1258      2711488 :    b(:) = phi(allindices(:))
    1259              : 
    1260       417152 :    do is = 1, BSp%nsppol
    1261      1042880 :      do iv = BSp%lomo_spin(is),Bsp%homo_spin(is)
    1262      3337216 :        do ic = BSp%lumo_spin(is),Bsp%humo_spin(is)
    1263      2502912 :          ibnd_coarse = (iv-BSp%lomo_spin(is))*BSp%maxnbndc+(ic-BSp%lumo_spin(is)+1)
    1264      2502912 :          idense = Bsp%vcks2t_interp(iv,ic,ik_dense,is)
    1265              : 
    1266     17313600 :          do ineighbour = 1,interpolator%nvert
    1267     14184960 :            ind_with_nb = (ineighbour-1)*(nbnd_coarse)+ibnd_coarse
    1268              : 
    1269              :            !A(ind_with_nb,:) = overlaps(allindices(:),ibnd_coarse,ineighbour)
    1270              : 
    1271              :            ! Should be optimized !!!
    1272     59242752 :            do iv1 = BSp%lomo_spin(is),Bsp%homo_spin(is)
    1273    226959360 :              do ic1 = BSp%lumo_spin(is),Bsp%humo_spin(is)
    1274    170219520 :                ibnd_coarse1 = (iv1-BSp%lomo_spin(is))*BSp%maxnbndc+(ic1-BSp%lumo_spin(is)+1)
    1275              :                A(ind_with_nb,ibnd_coarse1) = GWPC_CONJG(interpolator%overlaps(iv,iv1,ineighbour,ik_dense,is)) &
    1276    212774400 : &                                          *interpolator%overlaps(ic,ic1,ineighbour,ik_dense,is)
    1277              :              end do !ic1
    1278              :            end do !iv1
    1279              :          end do !ineighbour
    1280              :        end do !ic
    1281              :      end do !iv
    1282              :    end do !is
    1283              : 
    1284              :    if(use_blas) then
    1285       208576 :      call xgemv('N',interpolator%nvert*nbnd_coarse,nbnd_coarse,cone,A,interpolator%nvert*nbnd_coarse,b,1,czero,c,1)
    1286              :    else
    1287              :      c = MATMUL(A,b)
    1288              :    end if
    1289              : 
    1290       420411 :    do is = 1, BSp%nsppol
    1291      1042880 :      do iv = BSp%lomo_spin(is),BSp%homo_spin(is)
    1292      3337216 :        do ic = BSp%lumo_spin(is),BSp%humo_spin(is)
    1293      2502912 :          ibnd_coarse = (iv-BSp%lomo_spin(is))*BSp%maxnbndc+(ic-BSp%lumo_spin(is)+1)
    1294     17313600 :          do ineighbour = 1,interpolator%nvert
    1295     14184960 :            ind_with_nb = (ineighbour-1)*(nbnd_coarse)+ibnd_coarse
    1296     16687872 :            ophi(ik_dense,ineighbour,ibnd_coarse) = c(ind_with_nb)
    1297              :          end do !ineighbour
    1298              :        end do !ic
    1299              :      end do !iv
    1300              :    end do !is
    1301              : 
    1302              :  end do !ik_dense
    1303              : 
    1304         3259 :  ABI_FREE(A)
    1305         3259 :  ABI_FREE(b)
    1306         3259 :  ABI_FREE(c)
    1307              : 
    1308              :  !call xmpi_sum_(ophi,comm,ierr)
    1309              : 
    1310              :  ! Outer index : k,v,c in the coarse zone, ineighbour
    1311              :  ! Sum over all k-dense relative to one coarse point
    1312              :  ! Index of result : k,v,c in the coarse zone, ineighbour
    1313              : 
    1314         9777 :  ABI_MALLOC(b,(grid%ndiv))
    1315         6518 :  ABI_MALLOC(c,(grid%ndiv))
    1316              : 
    1317      1794849 :  allp = czero
    1318              : 
    1319         6518 :  do is = 1, BSp%nsppol
    1320        24988 :    do ineighbour = 1,interpolator%nvert
    1321              : 
    1322      1794849 :      do it_coarse = 1, BSp%nreh(is)
    1323              :        ibnd_coarse = (Bsp%trans(it_coarse,is)%v-BSp%lomo_spin(is))*BSp%maxnbndc+&
    1324      1773120 :                      (BSp%Trans(it_coarse,is)%c-BSp%lumo_spin(is)+1)
    1325      1773120 :        ik_coarse = BSp%trans(it_coarse,is)%k
    1326              :        !b(:) = interp_factors(it_coarse,ineighbour,:)
    1327     15958080 :        b(:) = interpolator%interp_factors(ineighbour,:)
    1328              :        !c(:) = ophi(indices(it_coarse,:),ineighbour,ibnd_coarse)
    1329     15958080 :        c(:) = ophi(div2kdense(ik_coarse,:),ineighbour,ibnd_coarse)
    1330     15958080 :        tmp = DOT_PRODUCT(b,c)
    1331      1791590 :        allp(it_coarse,ineighbour) = tmp
    1332              :      end do
    1333              : 
    1334              :    end do
    1335              :  end do
    1336              : 
    1337              :  !call xmpi_sum_(allp,comm,ierr)
    1338              : 
    1339         3259 :  ABI_FREE(b)
    1340         3259 :  ABI_FREE(c)
    1341              : 
    1342         9777 :  ABI_MALLOC(tmp_array,(hsize_coarse))
    1343        13036 :  ABI_MALLOC(tmp_array2,(hsize_coarse,hsize_coarse))
    1344       316123 :  tmp_array(:) = czero
    1345     30351067 :  tmp_array2(:,:) = czero
    1346              : 
    1347       316123 :  test = czero
    1348              : 
    1349              :  ! Second step : Multiplication by hmat
    1350        21729 :  do ineighbour = 1,interpolator%nvert
    1351    173802700 :    tmp_array2 = factor*hmat(:,interpolator%corresp(:,ineighbour,1)) ! 1 is for spin
    1352         3259 :    if(use_blas) then
    1353              :      !call xgemv('N',hsize_coarse,hsize_coarse,cone,factor*(hmat(:,:,ineighbour)),hsize_coarse,allp(:,ineighbour),1,czero,tmp_array,1)
    1354              :      !tmp_array2 = hmat(:,:,ineighbour)
    1355              :      !tmp_array2 = factor*tmp_array2
    1356        18470 :      call xgemv('N',hsize_coarse,hsize_coarse,cone,tmp_array2,hsize_coarse,allp(:,ineighbour),1,czero,tmp_array,1)
    1357      1791590 :      test = test + tmp_array
    1358              :    else
    1359              :      !test = test+MATMUL(factor*(hmat(:,interpolator%corresp(:,ineighbour,1))),allp(:,ineighbour))
    1360              :      test = test+MATMUL(tmp_array2,allp(:,ineighbour))
    1361              :    end if
    1362              :  end do
    1363              : 
    1364         3259 :  ABI_FREE(tmp_array)
    1365         3259 :  ABI_FREE(tmp_array2)
    1366              : 
    1367              :  ! Outer index : ineighbour
    1368              :  ! Sum over all v c
    1369              :  ! Index of result : ineighbour, k_dense, v,c
    1370        13036 :  ABI_MALLOC(A,(nbnd_coarse,nbnd_coarse))
    1371         6518 :  ABI_MALLOC(b,(nbnd_coarse))
    1372         6518 :  ABI_MALLOC(c,(nbnd_coarse))
    1373        42367 :  c = czero
    1374              : 
    1375        21729 :  do ineighbour = 1,interpolator%nvert
    1376      1203809 :    do ik_dense = 1,grid%nbz_dense
    1377              : 
    1378      2364160 :      do is1 = 1, Bsp%nsppol
    1379      5910400 :        do iv1 = Bsp%lomo_spin(is1),Bsp%homo_spin(is1)
    1380     18913280 :          do ic1 = BSp%lumo_spin(is1), Bsp%humo_spin(is1)
    1381     14184960 :            ibnd_coarse = (iv1-BSp%lomo_spin(is1))*BSp%maxnbndc+(ic1-BSp%lumo_spin(is1)+1)
    1382              : 
    1383     14184960 :            ik_coarse = grid%dense_to_coarse(ik_dense)
    1384     14184960 :            itt = BSp%vcks2t(iv1,ic1,ik_coarse,is1)
    1385     17731200 :            b(ibnd_coarse) = test(interpolator%corresp(itt,ineighbour,is1))
    1386              :          end do ! ic1
    1387              :        end do ! iv1
    1388              :      end do ! is1
    1389              : 
    1390      2364160 :      do is = 1, BSp%nsppol
    1391      5910400 :        do iv = BSp%lomo_spin(is),Bsp%homo_spin(is)
    1392     18913280 :          do ic = BSp%lumo_spin(is),BSp%humo_spin(is)
    1393     14184960 :            ibnd_coarse = (iv-BSp%lomo_spin(is))*Bsp%maxnbndc+(ic-BSp%lumo_spin(is)+1)
    1394     14184960 :            idense = BSp%vcks2t_interp(iv,ic,ik_dense,is)
    1395              : 
    1396              :            !A(ibnd_coarse,:) = CONJG(overlaps(idense,:,ineighbour))
    1397              : 
    1398              :            ! Should be optimized !!!
    1399     60286080 :            do iv1 = BSp%lomo_spin(is),Bsp%homo_spin(is)
    1400    226959360 :              do ic1 = BSp%lumo_spin(is),Bsp%humo_spin(is)
    1401    170219520 :                ibnd_coarse1 = (iv1-BSp%lomo_spin(is))*BSp%maxnbndc+(ic1-BSp%lumo_spin(is)+1)
    1402              :                A(ibnd_coarse,ibnd_coarse1) = (interpolator%overlaps(iv1,iv,ineighbour,ik_dense,is)) &
    1403    212774400 :                                             *GWPC_CONJG(interpolator%overlaps(ic1,ic,ineighbour,ik_dense,is))
    1404              :              end do !ic1
    1405              :            end do !iv1
    1406              :          end do ! ic
    1407              :        end do !iv
    1408              :      end do !is
    1409              : 
    1410              :      if(use_blas) then
    1411      1182080 :        call xgemv('N',nbnd_coarse,nbnd_coarse,cone,A,nbnd_coarse,b,1,czero,c,1)
    1412              :      else
    1413              :        c = MATMUL(A,b)
    1414              :      end if
    1415              : 
    1416      2382630 :      do is = 1, BSp%nsppol
    1417      5910400 :        do iv = BSp%lomo_spin(is),Bsp%homo_spin(is)
    1418     18913280 :          do ic = BSp%lumo_spin(is),BSp%humo_spin(is)
    1419     14184960 :            ibnd_coarse = (iv-BSp%lomo_spin(is))*BSp%maxnbndc+(ic-BSp%lumo_spin(is)+1)
    1420     14184960 :            idense = Bsp%vcks2t_interp(iv,ic,ik_dense,is)
    1421              :            !ophi(ik_dense,ineighbour,ibnd_coarse) = c(idense)
    1422     17731200 :            ophi(ik_dense,ineighbour,ibnd_coarse) = c(ibnd_coarse)
    1423              :          end do
    1424              :        end do
    1425              :      end do
    1426              : 
    1427              :    end do ! ik_dense
    1428              :  end do ! ineighbour
    1429              : 
    1430              :  !call xmpi_sum_(ophi,comm,ierr)
    1431              : 
    1432         3259 :  ABI_FREE(A)
    1433         3259 :  ABI_FREE(b)
    1434         3259 :  ABI_FREE(c)
    1435              : 
    1436              :  ! Outer indices : it_dense
    1437              :  ! Sum over neighbours
    1438              :  ! Index of result : it_dense (ik,ic,iv dense)
    1439              : 
    1440         9777 :  ABI_MALLOC(b,(interpolator%nvert))
    1441         6518 :  ABI_MALLOC(c,(interpolator%nvert))
    1442              : 
    1443         6518 :  do is = 1, BSp%nsppol
    1444      2509430 :    do itt = 1,BSp%nreh_interp(is)
    1445              :     ! From itt -> ik_ibz,ic,iv
    1446      2502912 :     ik_dense = BSp%Trans_interp(itt,is)%k
    1447      2502912 :     ic = BSp%Trans_interp(itt,is)%c
    1448      2502912 :     iv = BSp%Trans_interp(itt,is)%v
    1449              : 
    1450              :     ! From ik_ibz in the dense mesh -> indices_dense
    1451      2502912 :     ik_coarse = grid%dense_to_coarse(ik_dense)
    1452      2502912 :     it_coarse = BSp%vcks2t(iv,ic,ik_coarse,is)
    1453              : 
    1454      2502912 :     ibnd_coarse = (iv-BSp%lomo_spin(is))*BSp%maxnbndc+(ic-BSp%lumo_spin(is)+1)
    1455              : 
    1456      2502912 :     ikpt = kdense2div(ik_dense)
    1457              :     !ikpt = -1
    1458              :     !do ix = 1,grid%ndiv
    1459              :     !  if (indices(it_coarse,ix) == ik_dense) then
    1460              :     !    ikpt = ix
    1461              :     !    exit
    1462              :     !  end if
    1463              :     !end do
    1464              :     !ABI_CHECK(ikpt/=-1,"Cannot find ik_dense")
    1465              : 
    1466              :     !b = interp_factors(it_coarse,:,ikpt)
    1467     19190784 :     b = interpolator%interp_factors(:,ikpt)
    1468     19190784 :     c =  ophi(ik_dense,:,ibnd_coarse)
    1469              : 
    1470      2506171 :     hphi(itt) = hphi(itt) + xdotc(interpolator%nvert, b, 1, c, 1)
    1471              :    end do
    1472              :  end do
    1473              : 
    1474         3259 :  ABI_FREE(b)
    1475         3259 :  ABI_FREE(c)
    1476              : 
    1477         3259 : end subroutine hexc_interp_matmul
    1478              : !!***
    1479              : 
    1480              : !-------------------------------------------------------------------
    1481              : 
    1482              : !!****f* m_hexc/hexc_matmul_tda
    1483              : !! NAME
    1484              : !! hexc_matmul_tda
    1485              : !!
    1486              : !! FUNCTION
    1487              : !! Compute H_exc |\psi>
    1488              : !!
    1489              : !! INPUTS
    1490              : !! hexc_i<hexc_interp_t> = Interpolated excitonic hamiltonian
    1491              : !! phi = Input ket
    1492              : !!
    1493              : !! OUTPUT
    1494              : !! hphi = hreso * phi
    1495              : !!
    1496              : !! SOURCE
    1497              : 
    1498         9793 : subroutine hexc_matmul_tda(hexc, hexc_i, phi, hphi)
    1499              : 
    1500              : !Arguments ---------------------------
    1501              :  class(hexc_t),intent(in) :: hexc
    1502              :  type(hexc_interp_t),intent(in) :: hexc_i
    1503              :  complex(dp),intent(in) :: phi(hexc%hsize)
    1504              :  complex(dp),intent(out) :: hphi(hexc%hsize)
    1505              : 
    1506              : !Local variables ---------------------
    1507              :  integer :: ierr
    1508              :  real(dp) :: tsec(2)
    1509              : !*****************************************************************************
    1510              : 
    1511         9793 :  call timab(697,1,tsec)
    1512              : 
    1513         9793 :  if (hexc%BSp%use_interp) then
    1514      3352840 :    hphi = hexc_i%diag_dense * phi
    1515              : 
    1516         4360 :    if (any(hexc%BSp%interp_mode == [2,3,4])) then
    1517              :      ! hphi = hphi + MATMUL(hinterp,phi)
    1518         2211 :      call xgemv('N',hexc_i%hsize_dense,hexc_i%hsize_dense,cone,hexc_i%hinterp,hexc_i%hsize_dense,phi,1,cone,hphi,1)
    1519         2211 :      if (any(hexc%BSp%interp_mode == [2,4])) then
    1520         1101 :        call timab(697,2,tsec)
    1521         1101 :        return ! We are done
    1522              :      end if
    1523              :    end if
    1524              : 
    1525              :    call hexc_interp_matmul(hexc%bsp, hexc%hsize_coarse, hexc_i%hsize_dense, hexc_i%all_hmat, phi, hphi, &
    1526         3259 :      hexc_i%interpolator%double_grid,hexc%nbnd_coarse, hexc_i%interpolator, hexc_i%div2kdense, hexc_i%kdense2div)
    1527              : 
    1528              :  else ! No interpolation
    1529         5433 :    call xgemv('N',hexc%hsize,hexc%my_nt,cone,hexc%hreso,hexc%hsize,phi,1,czero,hphi,1)
    1530         5433 :    call xmpi_sum(hphi,hexc%comm,ierr)
    1531              :  end if
    1532              : 
    1533         8692 :  call timab(697,2,tsec)
    1534              : 
    1535              : end subroutine hexc_matmul_tda
    1536              : !!***
    1537              : 
    1538              : !-------------------------------------------------------------------
    1539              : 
    1540              : !!****f* m_hexc/hexc_matmul_elphon
    1541              : !! NAME
    1542              : !! hexc_matmul_elphon
    1543              : !!
    1544              : !! FUNCTION
    1545              : !! Compute H | \psi > + E_{elphon} | \psi >
    1546              : !!
    1547              : !! INPUTS
    1548              : !! hexc<hexc_t> = Excitonic hamiltonian
    1549              : !! phi = Input ket
    1550              : !! ep_renorm = vector with electron-phonon renorms
    1551              : !! op = 'N' for H | psi >, 'C' for H^\dagger | psi >
    1552              : !!
    1553              : !! OUTPUT
    1554              : !! hphi = hreso * phi + ep_renorm * phi
    1555              : !!
    1556              : !! SOURCE
    1557              : 
    1558         6432 : subroutine hexc_matmul_elphon(hexc, phi, hphi, op, ep_renorm)
    1559              : 
    1560              : !Arguments ---------------------------
    1561              :  class(hexc_t),intent(in) :: hexc
    1562              :  character,intent(in) :: op
    1563              :  complex(dp),intent(in) :: phi(hexc%my_nt)
    1564              :  complex(dp),intent(out) :: hphi(hexc%hsize)
    1565              :  complex(dp),intent(in) :: ep_renorm(hexc%hsize)
    1566              : 
    1567              : !Local variables ---------------------
    1568              :  integer :: ierr
    1569              :  real(dp) :: tsec(2)
    1570              : !*****************************************************************************
    1571              : 
    1572         6432 :  call timab(697,1,tsec)
    1573              : 
    1574         6432 :  if(hexc%BSp%use_interp) then
    1575            0 :    ABI_ERROR('Not yet implemented with interpolation !')
    1576              :  else ! No interpolation
    1577              :    ! As our matrix is hermitian (hreso), we should always use 'N' here (it is stored column-wise !)
    1578         6432 :    call xgemv('N',hexc%hsize,hexc%my_nt,cone,hexc%hreso,hexc%hsize,phi,1,czero,hphi,1)
    1579              : 
    1580              :    !!! ep_renorm is stored on each cpu
    1581         6432 :    if (op == 'N') then
    1582       311952 :      hphi(hexc%my_t1:hexc%my_t2) = hphi(hexc%my_t1:hexc%my_t2) + ep_renorm(hexc%my_t1:hexc%my_t2) * phi
    1583         3216 :    else if(op == 'C') then
    1584       311952 :      hphi(hexc%my_t1:hexc%my_t2) = hphi(hexc%my_t1:hexc%my_t2) + CONJG(ep_renorm(hexc%my_t1:hexc%my_t2)) * phi
    1585              :    end if
    1586         6432 :    call xmpi_sum(hphi,hexc%comm,ierr)
    1587              :  end if
    1588              : 
    1589         6432 :  call timab(697,2,tsec)
    1590              : 
    1591         6432 : end subroutine hexc_matmul_elphon
    1592              : !!***
    1593              : 
    1594              : !-------------------------------------------------------------------
    1595              : 
    1596              : !!****f* m_hexc/hexc_matmul_full
    1597              : !! NAME
    1598              : !! hexc_matmul_full
    1599              : !!
    1600              : !! FUNCTION
    1601              : !! Compute H | \psi >
    1602              : !!
    1603              : !! INPUTS
    1604              : !! hexc<hexc_t> = Excitonic hamiltonian
    1605              : !! hexc_i<hexc_interp_t> = Interpolated hamiltonian
    1606              : !! phi = Input ket
    1607              : !! parity = -1 or +1 parameter
    1608              : !!
    1609              : !! OUTPUT
    1610              : !! hphi = hreso * phi + parity * hcoup * CONJ(phi)
    1611              : !!
    1612              : !! SOURCE
    1613              : 
    1614            0 : subroutine hexc_matmul_full(hexc, hexc_i, phi, hphi, parity)
    1615              : 
    1616              : !Arguments ---------------------------
    1617              :  class(hexc_t),intent(in) :: hexc
    1618              :  type(hexc_interp_t),intent(in) :: hexc_i
    1619              :  complex(dp),intent(in) :: phi(hexc%hsize)
    1620              :  complex(dp),intent(out) :: hphi(hexc%hsize)
    1621              :  integer,intent(in) :: parity
    1622              : 
    1623              : !Local variables ---------------------
    1624              :  real(dp) :: tsec(2)
    1625              : !*****************************************************************************
    1626              : 
    1627            0 :  call timab(697,1,tsec)
    1628              : 
    1629              :  ABI_UNUSED(hexc_i%hsize_dense)
    1630              : 
    1631            0 :  if(hexc%BSp%use_interp) then
    1632            0 :    ABI_ERROR("Coupling is not yet implemented with interpolation")
    1633              :  else
    1634              :    ! No interpolation
    1635            0 :    hphi = MATMUL(hexc%hreso,phi) + parity * MATMUL(hexc%hcoup,CONJG(phi))
    1636              :  end if
    1637              : 
    1638            0 :  call timab(697,2,tsec)
    1639              : 
    1640            0 : end subroutine hexc_matmul_full
    1641              : !!***
    1642              : 
    1643              : !-------------------------------------------------------------------
    1644              : 
    1645            0 : end module m_hexc
    1646              : !!***
        

Generated by: LCOV version 2.3-1