LCOV - code coverage report
Current view: top level - src/71_bse - m_haydock.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 61.6 % 893 550
Test Date: 2026-09-20 18:56:22 Functions: 70.0 % 10 7

            Line data    Source code
       1              : !!****m* ABINIT/m_haydock
       2              : !! NAME
       3              : !! m_haydock
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !! COPYRIGHT
       8              : !!  Copyright (C) 2008-2026 ABINIT group (M.Giantomassi, Y. Gillet, L.Reining, V.Olevano, F.Sottile, S.Albrecht, G.Onida)
       9              : !!  This file is distributed under the terms of the
      10              : !!  GNU General Public License, see ~abinit/COPYING
      11              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      12              : !!
      13              : !! SOURCE
      14              : 
      15              : #if defined HAVE_CONFIG_H
      16              : #include "config.h"
      17              : #endif
      18              : 
      19              : #include "abi_common.h"
      20              : 
      21              : MODULE m_haydock
      22              : 
      23              :  use defs_basis
      24              :  use m_abicore
      25              :  use m_bs_defs
      26              :  use m_xmpi
      27              :  use m_errors
      28              :  use m_haydock_io
      29              :  use m_linalg_interfaces
      30              :  use netcdf
      31              :  use m_nctk
      32              : 
      33              :  use m_time,              only : timab
      34              :  use m_fstrings,          only : strcat, sjoin, itoa, int2char4
      35              :  use m_io_tools,          only : file_exists, open_file
      36              :  use defs_datatypes,      only : pseudopotential_type
      37              :  use m_geometry,          only : normv
      38              :  use m_hide_blas,         only : xdotc, xgemv
      39              :  use m_hide_lapack,       only : matrginv
      40              :  use m_numeric_tools,     only : print_arr, symmetrize, hermitianize, continued_fract, wrap2_pmhalf, iseven
      41              :  use m_kpts,              only : listkk
      42              :  use m_crystal,           only : crystal_t
      43              :  use m_ebands,            only : ebands_t
      44              :  use m_hdr,               only : hdr_type
      45              :  use m_bz_mesh,           only : kmesh_t, findqg0
      46              :  use m_double_grid,       only : double_grid_t, get_kpt_from_indices_coarse, compute_corresp
      47              :  use m_paw_hr,            only : pawhur_t
      48              :  use m_wfd,               only : wfdgw_t
      49              :  use m_bse_io,            only : exc_write_optme
      50              :  use m_pawtab,            only : pawtab_type
      51              :  use m_vcoul,             only : vcoul_t
      52              :  use m_hexc,              only : hexc_t, hexc_interp_t
      53              :  use m_exc_spectra,       only : exc_write_data, exc_eps_rpa, exc_write_tensor, mdfs_ncwrite
      54              :  use m_eprenorms,         only : eprenorms_t, renorm_bst
      55              :  use m_wfd_optic,         only : calc_optical_mels
      56              : 
      57              :  implicit none
      58              : 
      59              :  private
      60              : !!***
      61              : 
      62              :  public :: exc_haydock_driver     ! Driver for the Haydock method (main entry point for client code).
      63              : 
      64              : CONTAINS  !=======================================================================
      65              : !!***
      66              : 
      67              : !!****f* m_haydock/exc_haydock_driver
      68              : !! NAME
      69              : !! exc_haydock_driver
      70              : !!
      71              : !! FUNCTION
      72              : !!  Calculate the imaginary part of the macroscopic dielectric function with the Haydock recursive method.
      73              : !!
      74              : !! INPUTS
      75              : !! BSp<type(excparam)=The parameter for the Bethe-Salpeter run.
      76              : !! BS_files<excparam>=Files associated to the bethe_salpeter code.
      77              : !! Cryst<crystal_t>=Info on the crystalline structure.
      78              : !! Kmesh<type(kmesh_t)>=The list of k-points in the BZ, IBZ and symmetry tables.
      79              : !! Cryst<type(crystal_t)>=Info on the crystalline structure.
      80              : !! Hdr_bse
      81              : !! KS_BSt=The KS energies.
      82              : !! QP_BSt=The QP energies.
      83              : !! Wfd<wfdgw_t>=Wavefunction descriptor (input k-mesh)
      84              : !! Psps <type(pseudopotential_type)>=variables related to pseudopotentials.
      85              : !! Pawtab(Cryst%ntypat*usepaw)<pawtab_type>=PAW tabulated starting data.
      86              : !! Hur(Cryst%natom*usepaw)<type(pawhur_t)>=Only for PAW and DFT+U, quantities used to evaluate the commutator [H_u,r].
      87              : !!
      88              : !! OUTPUT
      89              : !!  The imaginary part of the macroscopic dielectric function is written on the external file _EXC_MDF
      90              : !!
      91              : !! SOURCE
      92              : 
      93           23 : subroutine exc_haydock_driver(BSp,BS_files,Cryst,Kmesh,Hdr_bse,KS_BSt,QP_Bst,Wfd,Psps,Pawtab,Hur,Epren, &
      94              :  Kmesh_dense, KS_BSt_dense, QP_BSt_dense, Wfd_dense, Vcp_dense, grid) ! Optional args
      95              : 
      96              : !Arguments ------------------------------------
      97              : !scalars
      98              :  type(excparam),intent(in) :: BSp
      99              :  type(excfiles),intent(in) :: BS_files
     100              :  type(kmesh_t),intent(in) :: Kmesh
     101              :  type(crystal_t),intent(in) :: Cryst
     102              :  type(Hdr_type),intent(in) :: Hdr_bse
     103              :  type(wfdgw_t),intent(inout) :: Wfd
     104              :  type(pseudopotential_type),intent(in) :: Psps
     105              :  type(ebands_t),intent(in) :: KS_BSt,QP_Bst
     106              :  type(double_grid_t),intent(in),optional :: grid
     107              :  type(kmesh_t),intent(in),optional :: Kmesh_dense
     108              :  type(wfdgw_t),intent(inout),optional :: Wfd_dense
     109              :  type(ebands_t),intent(in),optional :: KS_BSt_dense, QP_Bst_dense
     110              :  type(vcoul_t),intent(in),optional :: Vcp_dense
     111              :  type(eprenorms_t),intent(in) :: Epren
     112              : !arrays
     113              :  type(pawtab_type),intent(in) :: Pawtab(Cryst%ntypat*Wfd%usepaw)
     114              :  type(pawhur_t),intent(in) :: Hur(Cryst%natom*Wfd%usepaw)
     115              : 
     116              : !Local variables ------------------------------
     117              : !scalars
     118              :  integer,parameter :: master=0
     119              :  integer :: io,my_rank,iq,itt,ierr
     120              :  integer :: hsize,comm,my_t1,my_t2,nsppol,nkets,nproc,ncid
     121              :  integer :: spin,spad,ik_bz,iv,ic,trans_idx,lomo_min,max_band
     122              :  real(dp) :: omegaev,rand_phi !,norm
     123              :  complex(dp) :: ks_avg,gw_avg,exc_avg
     124              :  logical :: use_mpio,prtdos
     125              :  character(len=500) :: msg
     126           23 :  type(hexc_t) :: hexc
     127           23 :  type(hexc_interp_t) :: hexc_i
     128              : !arrays
     129              :  real(dp) :: tsec(2)
     130           23 :  real(dp),allocatable :: dos(:),dos_gw(:),dos_ks(:)
     131           23 :  complex(dp),allocatable :: green(:,:)
     132           23 :  complex(dp),allocatable :: opt_cvk(:,:,:,:,:),kets(:,:)
     133           23 :  complex(dp),allocatable :: eps_rpanlf(:,:),eps_gwnlf(:,:)
     134           23 :  complex(dp),allocatable :: tensor_cart(:,:),tensor_cart_rpanlf(:,:),tensor_cart_gwnlf(:,:)
     135           23 :  complex(dp),allocatable :: tensor_red(:,:),tensor_red_rpanlf(:,:),tensor_red_gwnlf(:,:)
     136              : 
     137              :  !Temperature
     138              :  integer :: ep_ik, ik, ireh, isppol, itemp, ntemp
     139              :  real(dp) :: dksqmax, en
     140           23 :  integer,allocatable :: bs2eph(:,:)
     141              :  integer :: sppoldbl, timrev
     142              :  logical :: do_ep_renorm, do_ep_lifetime
     143              :  character(len=4) :: ts
     144              :  character(len=fnlen) :: prefix, path
     145           23 :  complex(dp),allocatable :: ep_renorms(:)
     146           23 :  type(ebands_t) :: EPBSt, EP_QPBSt
     147              : !************************************************************************
     148              : 
     149           23 :  call timab(690,1,tsec) ! exc_haydock_driver
     150           23 :  call timab(691,1,tsec) ! exc_haydock_driver(read)
     151              : 
     152           23 :  if (BSp%have_complex_ene) then
     153            0 :    ABI_ERROR("Complex energies are not supported yet")
     154              :  end if
     155              : 
     156           23 :  my_rank = Wfd%my_rank
     157           23 :  comm    = Wfd%comm
     158           23 :  nsppol  = Wfd%nsppol
     159           23 :  nproc   = Wfd%nproc
     160              : 
     161              :  use_mpio=.FALSE.
     162              : #ifdef HAVE_MPI_IO
     163              :  use_mpio = (nproc > 1)
     164              :  !use_mpio = .TRUE.
     165              : #endif
     166           23 :  use_mpio=.FALSE.
     167              :  !use_mpio = .TRUE.
     168              : 
     169              :  ! Hsize refers to the size of the individual blocks (resonant and coupling).
     170              :  ! Thanks to the symmetry property of the starting vector, the Haydock method
     171              :  ! can be reformulated in terms of matrix-vector multiplication involving the
     172              :  ! blocks thus avoiding to allocation of the full matrix ( R   C )
     173              :  !                                                        -C* -R*)
     174           46 :  hsize=SUM(BSp%nreh)
     175              : 
     176              :  !YG2014
     177           23 :  call hexc%init(BSp, BS_files, Cryst, Kmesh, Wfd, KS_BSt, QP_BSt, comm)
     178              : 
     179              :  !YG2014
     180           23 :  if(BSp%use_interp) then
     181              :    call hexc_i%init(hexc, BSp%interp_m3_width, BSp%interp_method,&
     182              :      Kmesh_dense, Vcp_dense, grid, Wfd_dense, &
     183            4 :      KS_BSt_dense, QP_BSt_dense, Psps, Pawtab)
     184              :  end if
     185              : 
     186           23 :  call timab(691,2,tsec) ! exc_haydock_driver(read)
     187           23 :  call timab(692,1,tsec) ! exc_haydock_driver(prep)
     188              : 
     189              :  ! Prepare the starting vectors for the Lanczos chain.
     190           23 :  nkets=Bsp%nq
     191              : 
     192           23 :  prtdos=.FALSE. !prtdos=.TRUE.
     193              :  if (prtdos) then
     194              :    nkets=nkets+1
     195              :    if (Bsp%use_coupling>0) then
     196              :      ABI_ERROR("DOS with coupling not coded")
     197              :      nkets=nkets+1
     198              :    end if
     199              :  end if
     200              : 
     201              :  !YG2014
     202           92 :  ABI_MALLOC_OR_DIE(kets,(hexc%hsize,nkets), ierr)
     203        64289 :  kets=czero
     204              :  !
     205              :  ! Prepare the kets for the macroscopic dielectric function.
     206           23 :  lomo_min=Bsp%lomo_min; max_band=Bsp%nbnds
     207              : 
     208              :  !YG2014
     209          161 :  ABI_MALLOC_OR_DIE(opt_cvk,(lomo_min:max_band,lomo_min:max_band,hexc%nbz,Wfd%nsppol,BSp%nq), ierr)
     210              : 
     211          161 :  do iq=1,Bsp%nq
     212              :  ! Note KS_BSt is used here to calculate the commutator.
     213              :    call calc_optical_mels(hexc%Wfd,hexc%Kmesh,hexc%KS_BSt,Cryst,Psps,Pawtab,Hur, &
     214          138 : &     BSp%inclvkb,BSp%lomo_spin,lomo_min,max_band,hexc%nbz,BSp%q(:,iq),opt_cvk(:,:,:,:,iq))
     215              : 
     216              :  ! Fill ket0 using the same ordering for the indices as the one used for the excitonic Hamiltonian.
     217              :  ! Note that only the resonant part is used here.
     218          299 :    do spin=1,nsppol
     219              : 
     220          138 :      if(BSp%use_interp) then
     221           24 :        spad=(spin-1)*BSp%nreh_interp(spin)
     222              :      else
     223          114 :        spad=(spin-1)*BSp%nreh(spin)
     224              :      end if
     225              : 
     226         7524 :      do ik_bz=1,hexc%nbz
     227        28794 :        do iv=BSp%lomo_spin(spin),BSp%homo_spin(spin)
     228        92784 :          do ic=BSp%lumo_spin(spin),BSp%nbnds
     229              : 
     230        64128 :            if(BSp%use_interp) then
     231        18432 :              trans_idx = BSp%vcks2t_interp(iv,ic,ik_bz,spin)
     232              :            else
     233        45696 :              trans_idx = BSp%vcks2t(iv,ic,ik_bz,spin)
     234              :            end if
     235              : 
     236        85536 :            if (trans_idx>0) kets(trans_idx+spad,iq)=opt_cvk(ic,iv,ik_bz,spin,iq)
     237              :          end do
     238              :        end do
     239              :      end do
     240              :    end do
     241              : 
     242              :  end do
     243              : 
     244              :  ! ========================================================
     245              :  ! === Write the Optical Matrix Elements to NetCDF file ===
     246              :  ! ========================================================
     247              : 
     248              :  !if (.false.) then
     249              :  !  ome_fname='test_OME.nc'
     250              :  !  call exc_write_optme(ome_fname,minb,maxb,BSp%nkbz,Wfd%nsppol,BSp%nq,opt_cvk,ierr)
     251              :  !end if
     252              : 
     253              :  ! Free WFD descriptor, we don't need ur and ug anymore !
     254              :  ! We make space for interpolated hamiltonian
     255           23 :  call wfd%wave_free("All")
     256           23 :  if(BSp%use_interp) call wfd_dense%wave_free("All")
     257              : 
     258              :  ! Build interpolated hamiltonian
     259           23 :  if(BSp%use_interp) then
     260            4 :    if (any(BSp%interp_mode == [2,3,4])) call hexc%build_hinterp(hexc_i)
     261              :  end if
     262              : 
     263           23 :  call timab(692,2,tsec) ! exc_haydock_driver(prep)
     264           23 :  call timab(693,1,tsec) ! exc_haydock_driver(wo lf) - that is, without local field
     265              : 
     266           23 :  do_ep_renorm = .FALSE.
     267           23 :  ntemp = 1
     268           23 :  do_ep_lifetime = .FALSE.
     269              : 
     270           23 :  if(BSp%do_ep_renorm) then
     271            1 :    if (BSp%nsppol == 2) then
     272            0 :      ABI_ERROR('Elphon renorm with nsppol == 2 not yet coded !')
     273              :    end if
     274            1 :    do_ep_renorm = .TRUE.
     275            1 :    ntemp = Epren%ntemp
     276              :    if(BSp%do_lifetime) do_ep_lifetime = .TRUE.
     277              : 
     278              :    ! Force elphon linewidth
     279            1 :    do_ep_lifetime = .TRUE.
     280              : 
     281              :    ! Map points from BSE to elphon kpoints
     282            1 :    sppoldbl = 1 !; if (any(Cryst%symafm == -1) .and. Epren%nsppol == 1) nsppoldbl=2
     283            3 :    ABI_MALLOC(bs2eph, (Kmesh%nbz*sppoldbl, 6))
     284            3 :    ABI_MALLOC(ep_renorms, (hsize))
     285            1 :    timrev = 1
     286              :    call listkk(dksqmax, Cryst%gmet, bs2eph, Epren%kpts, Kmesh%bz, Epren%nkpt, Kmesh%nbz, Cryst%nsym, &
     287            1 :       sppoldbl, Cryst%symafm, Cryst%symrel, timrev, comm, use_symrec=.False.)
     288              :  end if
     289              : 
     290           23 :  call timab(693,2,tsec) ! exc_haydock_driver(wo lf    - that is, without local field
     291           23 :  call timab(694,1,tsec) ! exc_haydock_driver(apply
     292              : 
     293           23 :  prefix = ""
     294           55 :  do itemp = 1, ntemp
     295              : 
     296           32 :    call hexc%KS_BSt%copy(EPBSt)
     297           32 :    call hexc%QP_BSt%copy(EP_QPBSt)
     298              : 
     299              :    ! =================================================
     300              :    ! == Calculate elphon vector in transition space ==
     301              :    ! =================================================
     302           32 :    if (do_ep_renorm) then
     303              : 
     304              :      ! Will perform elphon renormalization for itemp
     305              : 
     306           10 :      call int2char4(itemp,ts)
     307           10 :      prefix = TRIM("_T") // ts
     308              : 
     309              :      ! No scissor with KS Bands
     310           10 :      call renorm_bst(Epren, EPBSt, Cryst, itemp, do_lifetime=.TRUE.,do_check=.TRUE.)
     311           10 :      call renorm_bst(Epren, EP_QPBSt, Cryst, itemp, do_lifetime=.TRUE.,do_check=.FALSE.)
     312              : 
     313           20 :      do isppol = 1, BSp%nsppol
     314          980 :        do ireh = 1, BSp%nreh(isppol)
     315          960 :          ic = BSp%Trans(ireh,isppol)%c
     316          960 :          iv = BSp%Trans(ireh,isppol)%v
     317          960 :          ik = BSp%Trans(ireh,isppol)%k ! In the full bz
     318          960 :          en = BSp%Trans(ireh,isppol)%en
     319              : 
     320          960 :          ep_ik = bs2eph(ik,1)
     321              : 
     322              :          !TODO support multiple spins !
     323          960 :          if(ABS(en - (Epren%eigens(ic,ep_ik,isppol)-Epren%eigens(iv,ep_ik,isppol)+BSp%mbpt_sciss)) > tol3) then
     324            0 :            ABI_ERROR("Eigen from the transition does not correspond to the EP file !")
     325              :          end if
     326          960 :          ep_renorms(ireh) = (Epren%renorms(1,ic,ik,isppol,itemp) - Epren%renorms(1,iv,ik,isppol,itemp))
     327              : 
     328              :          ! Add linewith
     329           10 :          if(do_ep_lifetime) then
     330              :            ep_renorms(ireh) = ep_renorms(ireh) - j_dpc*(Epren%linewidth(1,ic,ik,isppol,itemp) +&
     331          960 :                                                         Epren%linewidth(1,iv,ik,isppol,itemp))
     332              :          end if
     333              : 
     334              :        end do
     335              :      end do
     336              :    end if
     337              : 
     338              :    ! =======================================================
     339              :    ! === Make EPS RPA and GW without local-field effects ===
     340              :    ! =======================================================
     341          128 :    ABI_MALLOC(eps_rpanlf,(BSp%nomega,BSp%nq))
     342           96 :    ABI_MALLOC(dos_ks,(BSp%nomega))
     343           96 :    ABI_MALLOC(eps_gwnlf ,(BSp%nomega,BSp%nq))
     344           64 :    ABI_MALLOC(dos_gw,(BSp%nomega))
     345              : 
     346           32 :    call wrtout(std_out," Calculating RPA NLF and QP NLF epsilon")
     347              : 
     348              :    call exc_eps_rpa(BSp%nbnds,BSp%lomo_spin,BSp%lomo_min,BSp%homo_spin,hexc%Kmesh,EPBSt,BSp%nq,nsppol,&
     349           32 :     opt_cvk,Cryst%ucvol,BSp%broad,BSp%nomega,BSp%omega,eps_rpanlf,dos_ks)
     350              : 
     351              :    call exc_eps_rpa(BSp%nbnds,BSp%lomo_spin,BSp%lomo_min,BSp%homo_spin,hexc%Kmesh,EP_QPBSt,BSp%nq,nsppol,&
     352           32 :     opt_cvk,Cryst%ucvol,Bsp%broad,BSp%nomega,BSp%omega,eps_gwnlf,dos_gw)
     353              : 
     354           32 :    if (my_rank==master) then ! Only master works.
     355              :      !
     356              :      ! Master node writes final results on file.
     357           28 :      call exc_write_data(BSp,BS_files,"RPA_NLF_MDF",eps_rpanlf,prefix=prefix,dos=dos_ks)
     358           28 :      call exc_write_data(BSp,BS_files,"GW_NLF_MDF",eps_gwnlf,prefix=prefix,dos=dos_gw)
     359              : 
     360              :      ! Computing and writing tensor in files
     361              : 
     362              :      ! RPA_NLF
     363           84 :      ABI_MALLOC(tensor_cart_rpanlf,(BSp%nomega,6))
     364           56 :      ABI_MALLOC(tensor_red_rpanlf,(BSp%nomega,6))
     365              : 
     366           28 :      call wrtout(std_out," Calculating RPA NLF dielectric tensor")
     367           28 :      call haydock_mdf_to_tensor(BSp,Cryst,eps_rpanlf,tensor_cart_rpanlf, tensor_red_rpanlf, ierr)
     368              : 
     369           28 :      if (ierr == 0) then
     370              :        ! Writing tensor
     371           28 :        call exc_write_tensor(BSp,BS_files,"RPA_NLF_TSR_CART",tensor_cart_rpanlf)
     372           28 :        call exc_write_tensor(BSp,BS_files,"RPA_NLF_TSR_RED",tensor_red_rpanlf)
     373              :      else
     374              :         write(msg,'(3a)')&
     375            0 :          'The RPA_NLF dielectric complex tensor cannot be computed',ch10,&
     376            0 :          'There must be 6 different q-points in long wavelength limit (see gw_nqlwl)'
     377            0 :         ABI_COMMENT(msg)
     378              :      end if
     379              : 
     380           28 :      ABI_FREE(tensor_cart_rpanlf)
     381           28 :      ABI_FREE(tensor_red_rpanlf)
     382              : 
     383              :      ! GW_NLF
     384           56 :      ABI_MALLOC(tensor_cart_gwnlf,(BSp%nomega,6))
     385           56 :      ABI_MALLOC(tensor_red_gwnlf,(BSp%nomega,6))
     386              : 
     387           28 :      call wrtout(std_out," Calculating GW NLF dielectric tensor")
     388              : 
     389           28 :      call haydock_mdf_to_tensor(BSp,Cryst,eps_gwnlf,tensor_cart_gwnlf, tensor_red_gwnlf, ierr)
     390              : 
     391           28 :      if(ierr == 0) then
     392              :         ! Writing tensor
     393           28 :         call exc_write_tensor(BSp,BS_files,"GW_NLF_TSR_CART",tensor_cart_gwnlf)
     394           28 :         call exc_write_tensor(BSp,BS_files,"GW_NLF_TSR_RED",tensor_red_gwnlf)
     395              :      else
     396              :         write(msg,'(3a)')&
     397            0 :          'The GW_NLF dielectric complex tensor cannot be computed',ch10,&
     398            0 :          'There must be 6 different q-points in long wavelength limit (see gw_nqlwl)'
     399            0 :         ABI_COMMENT(msg)
     400              :      end if
     401              : 
     402           28 :      ABI_FREE(tensor_cart_gwnlf)
     403           84 :      ABI_FREE(tensor_red_gwnlf)
     404              : 
     405              :      !call wrtout(std_out," Checking Kramers Kronig on Excitonic Macroscopic Epsilon")
     406              :      !call check_kramerskronig(BSp%nomega,REAL(BSp%omega),eps_exc(:,1))
     407              : 
     408              :      !call wrtout(std_out," Checking Kramers Kronig on RPA NLF Macroscopic Epsilon")
     409              :      !call check_kramerskronig(BSp%nomega,REAL(BSp%omega),eps_rpanlf(:,1))
     410              : 
     411              :      !call wrtout(std_out," Checking Kramers Kronig on GW NLF Macroscopic Epsilon")
     412              :      !call check_kramerskronig(BSp%nomega,REAL(BSp%omega),eps_gwnlf(:,1))
     413              : 
     414              :      !call wrtout(std_out," Checking f-sum rule on Excitonic Macroscopic Epsilon")
     415              : 
     416              :      !if (BSp%exchange_term>0) then
     417              :      !  ABI_COMMENT(' f-sum rule should be checked without LF')
     418              :      !end if
     419              :      !call check_fsumrule(BSp%nomega,REAL(BSp%omega),AIMAG(eps_exc(:,1)),drude_plsmf)
     420              : 
     421              :      !call wrtout(std_out," Checking f-sum rule on RPA NLF Macroscopic Epsilon")
     422              :      !call check_fsumrule(BSp%nomega,REAL(BSp%omega),AIMAG(eps_rpanlf(:,1)),drude_plsmf)
     423              : 
     424              :      !call wrtout(std_out," Checking f-sum rule on GW NLF Macroscopic Epsilon")
     425              :      !call check_fsumrule(BSp%nomega,REAL(BSp%omega),AIMAG(eps_gwnlf(:,1)),drude_plsmf)
     426              :    end if ! my_rank==master
     427              : 
     428              :    !call xmpi_barrier(comm)
     429              :    !
     430              :    ! The ket for the approximated DOS.
     431              :    if (prtdos) then
     432              :      ABI_WARNING("Calculating DOS with Haydock method")
     433              :      ABI_CHECK(BSp%use_coupling==0,"DOS with coupling not coded")
     434              :      iq = BSp%nq + 1
     435              :      if (my_rank==master) then
     436              :        !call random_seed()
     437              :        do itt=1,SUM(Bsp%nreh)
     438              :          call RANDOM_NUMBER(rand_phi)
     439              :          rand_phi = two_pi*rand_phi
     440              :          kets(itt,iq) = CMPLX( COS(rand_phi), SIN(rand_phi) )
     441              :        end do
     442              :        ! Normalize the vector.
     443              :        !norm = SQRT( DOT_PRODUCT(kets(:,iq), kets(:,iq)) )
     444              :        !kets(:,iq) = kets(:,iq)/norm
     445              :      end if
     446              :      call xmpi_bcast(kets(:,iq),master,comm,ierr)
     447              :    end if
     448              : 
     449          128 :    ABI_MALLOC(green,(BSp%nomega,nkets))
     450              : 
     451           32 :    if (BSp%use_coupling==0) then
     452           32 :      if(do_ep_renorm) then
     453           10 :        call haydock_bilanczos(BSp,BS_files,Cryst,Hdr_bse,hexc,hexc_i,hsize,hexc%my_t1,hexc%my_t2,nkets,kets,ep_renorms,green,comm)
     454              :      else
     455              :        !YG2014
     456           22 :        call haydock_herm(BSp,BS_files,Cryst,Hdr_bse,hexc%my_t1,hexc%my_t2,nkets,kets,green,hexc,hexc_i,comm)
     457              :      end if
     458              :    else
     459            0 :      if (BSp%use_interp) then
     460            0 :        ABI_ERROR("BSE Interpolation with coupling is not supported")
     461              :      else
     462            0 :        call haydock_psherm(BSp,BS_files,Cryst,Hdr_bse,hexc,hexc_i,hsize,my_t1,my_t2,nkets,kets,green,comm)
     463              :      end if
     464              :    end if
     465              : 
     466              :    ! Add 1 to have the real part right.
     467        87374 :    green = one + green
     468              : 
     469           32 :    if (my_rank==master) then ! Master writes the final results.
     470              : 
     471              :      if (prtdos) then
     472              :        ABI_MALLOC(dos,(BSp%nomega))
     473              :        dos = -AIMAG(green(:,BSp%nq+1))
     474              :        call exc_write_data(BSp,BS_files,"EXC_MDF",green,prefix=prefix,dos=dos)
     475              :        ABI_FREE(dos)
     476              :      else
     477           28 :        call exc_write_data(BSp,BS_files,"EXC_MDF",green,prefix=prefix)
     478              :      end if
     479              : 
     480              :      ! =========================
     481              :      ! === Write out Epsilon ===
     482              :      ! =========================
     483              : 
     484           84 :      ABI_MALLOC(tensor_cart,(BSp%nomega,6))
     485           56 :      ABI_MALLOC(tensor_red,(BSp%nomega,6))
     486              : 
     487           28 :      call wrtout(std_out," Calculating EXC dielectric tensor")
     488           28 :      call haydock_mdf_to_tensor(BSp,Cryst,green,tensor_cart,tensor_red,ierr)
     489              : 
     490           28 :      if (ierr == 0) then
     491              :          ! Writing tensor
     492           28 :          call exc_write_tensor(BSp,BS_files,"EXC_TSR_CART",tensor_cart)
     493           28 :          call exc_write_tensor(BSp,BS_files,"EXC_TSR_RED",tensor_red)
     494              :      else
     495              :          write(msg,'(3a)')&
     496            0 :            'The EXC dielectric complex tensor cannot be computed',ch10,&
     497            0 :            'There must be 6 different q-points in long wavelength limit (see gw_nqlwl)'
     498            0 :          ABI_COMMENT(msg)
     499              :      end if
     500              : 
     501           28 :      ABI_FREE(tensor_cart)
     502           28 :      ABI_FREE(tensor_red)
     503              :      !
     504              :      ! This part will be removed when fldiff will be able to compare two mdf files.
     505           28 :      write(ab_out,*)" "
     506           28 :      write(ab_out,*)"Macroscopic dielectric function:"
     507           28 :      write(ab_out,*)"omega [eV] <KS_RPA_nlf>  <GW_RPA_nlf>  <BSE> "
     508          308 :      do io=1,MIN(BSp%nomega,10)
     509          280 :        omegaev = REAL(BSp%omega(io))*Ha_eV
     510         1960 :        ks_avg  = SUM( eps_rpanlf(io,:)) / Bsp%nq
     511         1960 :        gw_avg  = SUM( eps_gwnlf (io,:)) / Bsp%nq
     512         1960 :        exc_avg = SUM( green     (io,:)) / BSp%nq
     513          308 :        write(ab_out,'(7f9.4)')omegaev,ks_avg,gw_avg,exc_avg
     514              :      end do
     515           28 :      write(ab_out,*)" "
     516              : 
     517              :      ! Write MDF file with the final results.
     518              :      ! FIXME: It won't work if prtdos == True
     519           28 :      path = strcat(BS_files%out_basename,strcat(prefix,"_MDF.nc"))
     520           28 :      NCF_CHECK(nctk_open_create(ncid, path, xmpi_comm_self))
     521           28 :      NCF_CHECK(cryst%ncwrite(ncid))
     522           28 :      NCF_CHECK(QP_bst%ncwrite(ncid))
     523           28 :      call mdfs_ncwrite(ncid, Bsp, green, eps_rpanlf, eps_gwnlf)
     524           56 :      NCF_CHECK(nf90_close(ncid))
     525              :    end if
     526              : 
     527           32 :    ABI_FREE(green)
     528           32 :    ABI_FREE(eps_rpanlf)
     529           32 :    ABI_FREE(eps_gwnlf)
     530           32 :    ABI_FREE(dos_ks)
     531           32 :    ABI_FREE(dos_gw)
     532              : 
     533           32 :    call EPBSt%free()
     534           55 :    call EP_QPBst%free()
     535              :  end do ! itemp loop
     536              : 
     537           23 :  ABI_FREE(opt_cvk)
     538           23 :  ABI_FREE(kets)
     539              : 
     540           23 :  call timab(694,2,tsec) ! exc_haydock_driver(apply
     541           23 :  call timab(695,1,tsec) ! exc_haydock_driver(end)
     542              : 
     543              :  !YG2014
     544           23 :  call hexc%free()
     545           23 :  call hexc_i%free()
     546              : 
     547           23 :  ABI_SFREE(ep_renorms)
     548           23 :  ABI_SFREE(bs2eph)
     549              : 
     550           23 :  call timab(695,2,tsec) ! exc_haydock_driver(end)
     551           23 :  call timab(690,2,tsec) ! exc_haydock_driver
     552              : 
     553           23 : end subroutine exc_haydock_driver
     554              : !!***
     555              : 
     556              : !----------------------------------------------------------------------
     557              : 
     558              : !!****f* m_haydock/haydock_herm
     559              : !! NAME
     560              : !! haydock_herm
     561              : !!
     562              : !! FUNCTION
     563              : !!  Reads the excitonic Hamiltonian from file and construct the Lanczos set of vectors
     564              : !!  by iterative matrix-vector multiplications.
     565              : !!
     566              : !! INPUTS
     567              : !! BSp<excparam>=Parameters for the Bethe-Salpeter calculation.
     568              : !! BS_files<excparam>=Files associated to the bethe_salpeter code.
     569              : !! Cryst<crystal_t>=Info on the crystalline structure.
     570              : !! Pawtab(Cryst%ntypat*usepaw)<pawtab_type>=PAW tabulated starting data.
     571              : !! hize=Size of the excitonic matrix.
     572              : !! my_t1,my_t2=First and last columns treated by this node.
     573              : !! nkets=Number of starting vectors for Haydock method.
     574              : !! kets(hsize,nkets)=The kets in the eh representation.
     575              : !! comm=MPI communicator.
     576              : !!
     577              : !! OUTPUT
     578              : !!  green(BSp%nomega,nkets)=
     579              : !!
     580              : !! SOURCE
     581              : 
     582           22 : subroutine haydock_herm(BSp,BS_files,Cryst,Hdr_bse,my_t1,my_t2,nkets,kets,green,hexc,hexc_i,comm)
     583              : 
     584              : !Arguments ------------------------------------
     585              : !scalars
     586              :  integer,intent(in) :: my_t1,my_t2,nkets,comm
     587              :  type(crystal_t),intent(in) :: Cryst
     588              :  type(excparam),intent(in) :: BSp
     589              :  type(excfiles),intent(in) :: BS_files
     590              :  type(Hdr_type),intent(in) :: Hdr_bse
     591              :  type(hexc_t),intent(inout) :: hexc
     592              :  type(hexc_interp_t),intent(inout) :: hexc_i
     593              : !arrays
     594              :  complex(dp),intent(out) :: green(BSp%nomega,nkets)
     595              :  complex(dp),intent(in) :: kets(hexc%hsize,nkets)
     596              : 
     597              : !Local variables ------------------------------
     598              : !scalars
     599              :  integer,parameter :: master=0
     600              :  integer :: inn,nproc,my_rank,ierr
     601              :  integer :: niter_file,niter_max,niter_done,nsppol,iq,my_nt,term_type,n_all_omegas
     602              :  real(dp) :: norm,nfact
     603              :  logical :: can_restart,is_converged
     604              :  complex(dp) :: factor
     605              :  character(len=500) :: msg
     606              :  character(len=fnlen), parameter :: tag_file="_HAYDR_SAVE"
     607              :  character(len=fnlen) :: restart_file,out_file
     608           22 :  type(haydock_type) :: haydock_file
     609              : !arrays
     610           22 :  real(dp),allocatable :: bb_file(:)
     611           22 :  real(dp),allocatable :: bb(:)
     612           22 :  complex(dp),allocatable :: aa(:),phi_nm1(:),phi_n(:),hphi_n(:),hphi_nm1(:)
     613           22 :  complex(dp),allocatable :: aa_file(:),phi_n_file(:),phi_nm1_file(:)
     614           22 :  complex(dp),allocatable :: ket0(:),all_omegas(:),green_temp(:,:)
     615              : ! complex(dp),allocatable :: diag_dense(:)
     616              :  logical :: check(2)
     617              : !************************************************************************
     618              : 
     619           22 :  ABI_CHECK(Bsp%nsppol==1,"nsppol > 1 not implemented yet")
     620              : 
     621           22 :  nproc  = xmpi_comm_size(comm); my_rank= xmpi_comm_rank(comm)
     622           22 :  nsppol = Hdr_bse%nsppol
     623              : 
     624           22 :  if (BSp%use_interp) then
     625            4 :    ABI_COMMENT("No parallelization in Interpolation")
     626            8 :    my_nt = SUM(Bsp%nreh_interp)
     627              :  else
     628           18 :    my_nt = my_t2-my_t1+1
     629              :  end if
     630              : 
     631           22 :  ABI_CHECK(my_nt>0,"One of the processors has zero columns")
     632              : 
     633           22 :  write(msg,'(a,i0)')' Haydock algorithm with MAX number of iterations: ',BSp%niter
     634           22 :  call wrtout(std_out,msg)
     635              :  !
     636              :  ! Select the terminator for the continued fraction.
     637           22 :  term_type=0; if (Bsp%hayd_term>0) term_type=1
     638           22 :  call wrtout(std_out,sjoin("Using terminator type: ",itoa(term_type)))
     639              :  !
     640              :  ! Check for presence of the restart file.
     641           22 :  can_restart=.FALSE.
     642           22 :  if ( BS_files%in_haydock_basename /= BSE_NOFILE) then
     643            0 :    restart_file = TRIM(BS_files%in_haydock_basename)//TRIM(tag_file)
     644            0 :    if (file_exists(restart_file) ) then
     645            0 :      can_restart=.TRUE.
     646            0 :      msg = " Restarting Haydock calculation from file: "//TRIM(restart_file)
     647            0 :      call wrtout(std_out,msg)
     648            0 :      call wrtout(ab_out,msg)
     649              :    else
     650            0 :      can_restart=.FALSE.
     651            0 :      call wrtout(ab_out," WARNING: cannot find restart file: "//TRIM(restart_file))
     652              :    end if
     653              :  end if
     654            0 :  ABI_CHECK(.not.can_restart,"restart not yet implemented")
     655              : 
     656              :  ! Open the file and write basic dimensions and info.
     657           22 :  if (my_rank==master) then
     658           18 :    out_file = TRIM(BS_files%out_basename)//TRIM(tag_file)
     659           18 :    call haydock_file%open(out_file)
     660           18 :    haydock_file%hsize = hexc%hsize
     661           18 :    haydock_file%use_coupling = Bsp%use_coupling
     662           18 :    haydock_file%op = BSE_HAYD_IMEPS
     663           18 :    haydock_file%nq = nkets
     664           18 :    haydock_file%broad = Bsp%broad
     665           18 :    call haydock_file%write_dim()
     666              :  end if
     667              : 
     668              :  !
     669              :  ! Calculate green(w) for the different starting points.
     670        27244 :  green=czero
     671          154 :  do iq=1,nkets
     672          396 :    ABI_MALLOC(ket0,(hexc%hsize))
     673        63816 :    ket0=kets(:,iq)
     674              : 
     675          132 :    niter_file=0
     676          132 :    if (can_restart) then
     677              :      call haydock_restart(BSp,restart_file,BSE_HAYD_IMEPS,iq,hexc%hsize,&
     678            0 :        niter_file,aa_file,bb_file,phi_nm1_file,phi_n_file,comm)
     679              :    end if
     680              :    !
     681              :    ! For n>1, we have:
     682              :    !  1) a_n = <n|H|n>
     683              :    !  2) b_n = || H|n> - a_n|n> -b_{n-1}|n-1> ||
     684              :    !  3) |n+1> = [H|n> -a_n|n> -b_{n-1}|n-1>]/b_n
     685              :    !
     686              :    ! The sequences starts with |1> normalized to 1 and b_0 =0, therefore:
     687              :    !  a_1 = <1|H|1>
     688              :    !  b_1 = || H|1> - a_1|1> ||
     689              :    !  |2> = [H|1> - a_1|1>]/b_1
     690              :    !
     691          396 :    ABI_MALLOC(hphi_n,(hexc%hsize))
     692          264 :    ABI_MALLOC(hphi_nm1,(hexc%hsize))
     693          396 :    ABI_MALLOC(phi_nm1,(my_nt))
     694          264 :    ABI_MALLOC(phi_n,(my_nt))
     695              : 
     696          132 :    niter_max = niter_file + Bsp%niter
     697          396 :    ABI_MALLOC(aa,(niter_max))
     698          396 :    ABI_MALLOC(bb,(niter_max))
     699        34212 :    aa=czero; bb=zero
     700              : 
     701          132 :    if (niter_file==0) then       ! Calculation from scratch.
     702        54600 :      phi_nm1=ket0(my_t1:my_t2)   ! Select the slice treated by this node.
     703          132 :      norm = DZNRM2(hexc%hsize,ket0,1) ! Normalization
     704        54468 :      phi_nm1=phi_nm1/norm
     705              : 
     706          132 :      call hexc%matmul_tda(hexc_i,phi_nm1,hphi_n)
     707              : 
     708          132 :      aa(1)=xdotc(my_nt,phi_nm1,1,hphi_n(my_t1:),1)
     709          132 :      call xmpi_sum(aa(1:1),comm,ierr)
     710              : 
     711        54600 :      phi_n = hphi_n(my_t1:my_t2) - aa(1)*phi_nm1
     712              : 
     713          132 :      bb(1) = xdotc(my_nt,phi_n,1,phi_n,1)
     714          132 :      call xmpi_sum(bb(1:1),comm,ierr)
     715          132 :      bb(1) = SQRT(bb(1))
     716              : 
     717        54468 :      phi_n = phi_n/bb(1)
     718          132 :      niter_done=1
     719              : 
     720              :    else ! Use the previous a and b.
     721            0 :      niter_done=niter_file
     722            0 :      aa(1:niter_done) = aa_file
     723            0 :      bb(1:niter_done) = bb_file
     724            0 :      phi_nm1=phi_nm1_file(my_t1:my_t2)   ! Select the slice treated by this node.
     725            0 :      phi_n  =phi_n_file  (my_t1:my_t2)
     726              :    end if
     727              : 
     728          132 :    if (can_restart) then
     729            0 :      ABI_FREE(aa_file)
     730            0 :      ABI_FREE(bb_file)
     731            0 :      ABI_FREE(phi_nm1_file)
     732            0 :      ABI_FREE(phi_n_file)
     733              :    end if
     734              : 
     735              :    ! Multiplicative factor (k-point sampling and unit cell volume)
     736              :    ! TODO be careful with the spin here
     737              :    ! TODO four_pi comes from the coulomb term 1/|q| is already included in the
     738              :    ! oscillators hence the present approach wont work if a cutoff interaction is used.
     739          132 :    nfact = -four_pi/(Cryst%ucvol*hexc%nbz)
     740          132 :    if (nsppol==1) nfact=two*nfact
     741              : 
     742          132 :    factor = nfact*(DZNRM2(hexc%hsize,ket0,1)**2)
     743              : 
     744              :    ! Which quantity should be checked for convergence?
     745          132 :    check = (/.TRUE.,.TRUE./)
     746          132 :    if (ABS(Bsp%haydock_tol(2)-one)<tol6) check = (/.TRUE. ,.FALSE./)
     747          132 :    if (ABS(Bsp%haydock_tol(2)-two)<tol6) check = (/.FALSE.,.TRUE./)
     748              : 
     749              :    ! Create new frequencies "mirror" in negative range to add
     750              :    ! their contributions. Can be improved by computing only once
     751              :    ! zero frequency, but loosing clearness
     752          132 :    n_all_omegas = 2*BSp%nomega
     753              : 
     754          396 :    ABI_MALLOC(all_omegas,(n_all_omegas))
     755              :    ! Put all omegas with frequency > 0 in table
     756        27222 :    all_omegas(BSp%nomega+1:n_all_omegas) = BSp%omega
     757              :    ! Put all omegas with frequency < 0
     758              :    ! Warning, the broadening must be kept positive
     759        27222 :    all_omegas(1:BSp%nomega) = -DBLE(BSp%omega(BSp%nomega:1:-1)) + j_dpc*AIMAG(BSp%omega(BSp%nomega:1:-1))
     760              : 
     761          528 :    ABI_MALLOC(green_temp,(n_all_omegas,nkets))
     762              : 
     763              :    call haydock_herm_algo(niter_done,niter_max,n_all_omegas,all_omegas,BSp%haydock_tol(1),check,&
     764              :      my_t1,my_t2,factor,term_type,aa,bb,phi_nm1,phi_n,&
     765              :      green_temp(:,iq),inn,is_converged,&
     766          132 :      hexc, hexc_i, comm)
     767              : 
     768              :    ! Computing result from two ranges of frequencies
     769              :    ! The real part is added, the imaginary part is substracted
     770        27222 :    green(:,iq) = green_temp(BSp%nomega+1:n_all_omegas,iq)+CONJG(green_temp(BSp%nomega:1:-1,iq))
     771              : 
     772          132 :    ABI_FREE(all_omegas)
     773          132 :    ABI_FREE(green_temp)
     774              :    !
     775              :    ! Save the a"s and the b"s for possible restarting.
     776              :    ! 1) Info on the Q.
     777              :    ! 2) Number of iterations performed.
     778              :    ! 3) do iter=1,niter_performed
     779              :    !      aa(iter),bb(iter)
     780              :    !    end do
     781              :    ! 4) |n-1>
     782              :    !    |n>
     783              :    !
     784        63684 :    hphi_nm1 = czero
     785        54468 :    hphi_nm1(my_t1:my_t2) = phi_nm1
     786          132 :    call xmpi_sum_master(hphi_nm1,master,comm,ierr)
     787              : 
     788        63684 :    hphi_n = czero
     789        54468 :    hphi_n(my_t1:my_t2) = phi_n
     790          132 :    call xmpi_sum_master(hphi_n,master,comm,ierr)
     791              : 
     792          132 :    if (my_rank==master) then
     793              :      ! Write data for restarting
     794          108 :      call haydock_file%write(hexc%hsize, Bsp%q(:,iq), aa, bb, hphi_n, hphi_nm1, MIN(inn,niter_max), factor)
     795              :    end if
     796              : 
     797          132 :    ABI_FREE(hphi_n)
     798          132 :    ABI_FREE(hphi_nm1)
     799          132 :    ABI_FREE(phi_nm1)
     800          132 :    ABI_FREE(phi_n)
     801          132 :    ABI_FREE(aa)
     802          132 :    ABI_FREE(bb)
     803          154 :    ABI_FREE(ket0)
     804              :  end do ! iq
     805              : 
     806           22 :  if (my_rank==master) call haydock_file%close()
     807              : 
     808           22 :  call xmpi_barrier(comm)
     809              : 
     810           22 : end subroutine haydock_herm
     811              : !!***
     812              : 
     813              : !----------------------------------------------------------------------
     814              : 
     815              : !!****f* m_haydock/haydock_herm_algo
     816              : !! NAME
     817              : !! haydock_herm_algo
     818              : !!
     819              : !! FUNCTION
     820              : !!
     821              : !! INPUTS
     822              : !!  niter_done=Number of iterations already performed (0 if the run starts from scratch).
     823              : !!  niter_max=Max number of iterations. Always > niter_done
     824              : !!  nomega=Number of Frequency points for the evaluation of the matrix element.
     825              : !!  omega(nomega)=Frequency set (imaginary part is already included).
     826              : !!  tol_iter=Tolerance used to stop the algorithm.
     827              : !!  check(2)=Logical flags to specify where both the real and the imaginary part of the
     828              : !!    matrix elements of the Green functions have to be checked for convergence.
     829              : !!  hsize=Size of the blocks.
     830              : !!  my_t1,my_t2=Indices of the first and last column stored treated by this done.
     831              : !!  term_type=0 if no terminator is used, 1 otherwise.
     832              : !!  hmat(hsize,my_t1:my_t2)=The columns of the block.
     833              : !!  factor
     834              : !!  ntrans = Number of transitions
     835              : !!  corresp = mapping between coarse points and neighbours
     836              : !!  overlaps = overlaps of wavefunctions between dense k-point coarse neighbours and bands
     837              : !!  comm=MPI communicator.
     838              : !!
     839              : !! OUTPUT
     840              : !!  green(nomega)=Output matrix elements.
     841              : !!  inn=Last iteration performed.
     842              : !!  is_converged=.TRUE. of the algorithm converged.
     843              : !!
     844              : !! SIDE EFFECTS
     845              : !!  phi_nm1(my_t2-my_t1+1), phi_n(my_t2-my_t1+1)
     846              : !!    input: vectors used to initialize the iteration
     847              : !!    output: the vectors obtained in the last iteration
     848              : !!  aa(niter_max) and bb(niter_max)
     849              : !!    if niter_done>0: aa(1:niter_done), bb(1:niter_done) store the coefficients of the previous run.
     850              : !!    when the routine returns aa(1:inn) and bb(1:inn) contain the matrix elements of the tridiagonal form.
     851              : !!
     852              : !! SOURCE
     853              : 
     854          132 : subroutine haydock_herm_algo(niter_done,niter_max,nomega,omega,tol_iter,check,&
     855          132 :                               my_t1,my_t2,factor,term_type,aa,bb,phi_nm1,phi_n,&
     856          132 :                               green,inn,is_converged, hexc, hexc_i, comm)
     857              : 
     858              : !Arguments ------------------------------------
     859              : !scalars
     860              :  integer,intent(in) :: niter_max,niter_done,nomega
     861              :  integer,intent(in) :: my_t1,my_t2,term_type
     862              :  integer,intent(in) :: comm
     863              :  integer,intent(out) :: inn
     864              :  logical,intent(out) :: is_converged
     865              :  real(dp),intent(in) :: tol_iter
     866              :  complex(dp),intent(in) :: factor
     867              :  type(hexc_t),intent(in) :: hexc
     868              :  type(hexc_interp_t),intent(in) :: hexc_i
     869              : !arrays
     870              :  real(dp),intent(inout) :: bb(niter_max)
     871              :  complex(dp),intent(out) :: green(nomega)
     872              :  complex(dp),intent(in) :: omega(nomega)
     873              :  complex(dp),intent(inout) :: aa(niter_max)
     874              :  complex(dp),intent(inout) :: phi_nm1(my_t2-my_t1+1)
     875              :  complex(dp),intent(inout) :: phi_n  (my_t2-my_t1+1)
     876              :  logical,intent(in) :: check(2)
     877              : 
     878              : !Local variables ------------------------------
     879              : !scalars
     880              :  integer :: ierr,my_nt,niter_min,nconv
     881              :  character(len=500) :: msg
     882              :  logical,parameter :: force_real=.TRUE.
     883              : !arrays
     884              :  integer :: units(2)
     885          264 :  real(dp) :: abs_err(nomega,2) !,rel_err(nomega,2)
     886          132 :  complex(dp),allocatable :: oldg(:),newg(:), phi_np1(:),hphi_n(:),cfact(:)
     887              :  logical :: test(2)
     888              : !************************************************************************
     889              : 
     890              :  ! The sequences starts with |1> normalized to 1 and b_0 =0, therefore:
     891              :  !  a_1 = <1|H|1>
     892              :  !  b_1 = || H|1> - a_1|1> ||
     893              :  !  |2> = [H|1> - a_1|1>]/b_1
     894              :  !
     895              :  ! For n>1 we have
     896              :  !  1) a_n = <n|H|n>
     897              :  !  2) b_n = || H|n> - a_n|n> -b_{n-1}|n-1> ||
     898              :  !  3) |n+1> = [H|n> -a_n|n> -b_{n-1}|n-1>]/b_n
     899              :  !
     900          132 :  my_nt = my_t2-my_t1+1
     901          396 :  units = [std_out, ab_out]
     902              : 
     903          396 :  ABI_MALLOC_OR_DIE(hphi_n,(hexc%hsize), ierr)
     904          396 :  ABI_MALLOC(phi_np1,(my_nt))
     905        54576 :  ABI_CALLOC(oldg,(nomega))
     906        54444 :  ABI_CALLOC(newg,(nomega))
     907        54444 :  ABI_CALLOC(cfact,(nomega))
     908              : 
     909          132 :  nconv=0
     910         9661 :  do inn=niter_done+1,niter_max
     911              : 
     912              :    !YG2014
     913         9661 :    call hexc%matmul_tda(hexc_i,phi_n,hphi_n)
     914              : 
     915         9661 :    aa(inn) = xdotc(my_nt,phi_n,1,hphi_n(my_t1:),1)
     916         9661 :    call xmpi_sum(aa(inn:inn),comm,ierr)
     917         9661 :    if (force_real) aa(inn) = DBLE(aa(inn)) ! Matrix is Hermitian.
     918              : 
     919              :    ! |n+1> = H|n> - A(n)|n> - B(n-1)|n-1>
     920      5417978 :    phi_np1 = hphi_n(my_t1:my_t2) - aa(inn)*phi_n - bb(inn-1)*phi_nm1
     921              : 
     922         9661 :    bb(inn) = xdotc(my_nt,phi_np1,1,phi_np1,1)
     923         9661 :    call xmpi_sum(bb(inn),comm,ierr)
     924         9661 :    bb(inn) = SQRT(bb(inn))
     925              : 
     926      5408317 :    phi_np1 = phi_np1/bb(inn)
     927      5408317 :    phi_nm1 = phi_n
     928      5408317 :    phi_n   = phi_np1
     929              : 
     930         9661 :    write(msg,'(a,i0,a,3es12.4)')' Iteration number ',inn,', b_i RE(a_i) IM(a_i) ',bb(inn),REAL(aa(inn)),AIMAG(aa(inn))
     931         9661 :    call wrtout(std_out, msg)
     932              : 
     933         9661 :    call continued_fract(inn,term_type,aa,bb,nomega,omega,cfact)
     934      2846830 :    newg= factor*cfact
     935              : 
     936              :    ! Avoid spurious convergence.
     937         9661 :    niter_min=4; if (niter_done>1) niter_min=niter_done+1
     938         9661 :    if (inn>niter_min) then
     939        27795 :      test=.TRUE.
     940      2674233 :      abs_err(:,1) = ABS(DBLE (newg-oldg))
     941      2674233 :      abs_err(:,2) = ABS(AIMAG(newg-oldg))
     942              :      !
     943         9265 :      if (tol_iter>zero) then
     944              :        ! Test on the L1 norm.
     945      3938750 :        if (check(1)) test(1) = SUM(abs_err(:,1)) < tol_iter*SUM(ABS(DBLE (newg)))
     946      3938750 :        if (check(2)) test(2) = SUM(abs_err(:,2)) < tol_iter*SUM(ABS(AIMAG(newg)))
     947              :      else
     948              :        ! Stringent test for each point.
     949       590552 :        if (check(1)) test(1) = ALL( abs_err(:,1) < -tol_iter*ABS(DBLE (newg)))
     950       593729 :        if (check(2)) test(2) = ALL( abs_err(:,2) < -tol_iter*ABS(AIMAG(newg)))
     951              :      end if
     952              :      !
     953        11028 :      if (ALL(test)) then
     954          371 :        nconv = nconv+1
     955              :      else
     956              :        nconv = 0
     957              :      end if
     958          371 :      if (nconv==2) then
     959          132 :        if(inn<100)then
     960              :          write(msg,'(a,es10.2,a)')&
     961          102 :            " >>> Haydock algorithm converged twice within haydock_tol= ",tol_iter," after less than 100 iterations."
     962              :        else
     963              :          write(msg,'(a,es10.2,a,i0,a)')&
     964           30 :            " >>> Haydock algorithm converged twice within haydock_tol= ",tol_iter," after ",inn," iterations."
     965              :        endif
     966          132 :        call wrtout(units, msg)
     967          132 :        EXIT
     968              :      end if
     969              :    end if
     970              : 
     971      2802047 :    oldg = newg
     972              :  end do ! inn
     973              : 
     974        54312 :  green = newg
     975          132 :  if (nconv/=2) then
     976              :    write(msg,'(a,es10.2,a,i0,a)')&
     977            0 :     " WARNING: Haydock algorithm did not converge within ",tol_iter," after ",niter_max," iterations."
     978            0 :    call wrtout(units, msg)
     979              :  end if
     980              : 
     981          132 :  is_converged = (nconv==2)
     982              : 
     983          132 :  ABI_FREE(oldg)
     984          132 :  ABI_FREE(newg)
     985          132 :  ABI_FREE(cfact)
     986          132 :  ABI_FREE(hphi_n)
     987          132 :  ABI_FREE(phi_np1)
     988              : 
     989          132 : end subroutine haydock_herm_algo
     990              : !!***
     991              : 
     992              : !----------------------------------------------------------------------
     993              : 
     994              : !!****f* m_haydock/haydock_restart
     995              : !! NAME
     996              : !! haydock_restart
     997              : !!
     998              : !! FUNCTION
     999              : !! Restart the Haydock method from file reading the data produced in a previous run.
    1000              : !!
    1001              : !! INPUTS
    1002              : !!  BSp<type(excparam)>=Parameters defining the Bethe-Salpeter calculation.
    1003              : !!    omega(BSp%nomega)=Frequency mesh for the macroscopic dielectric function (broadening is already included).
    1004              : !!  iq_search=The index of the q-point to be searched.
    1005              : !!  hsize
    1006              : !!  comm=MPI communicator.
    1007              : !!  nsppol
    1008              : !!  restart_file
    1009              : !!
    1010              : !! OUTPUT
    1011              : !!  niter_file=Number of iterations already performed. 0 to signal that an error occurred during the reading
    1012              : !!  bb_file(:)
    1013              : !!  aa_file(:)
    1014              : !!  phi_n_file(:)
    1015              : !!  phi_nm1_file(:)
    1016              : !!
    1017              : !! SOURCE
    1018              : 
    1019            0 : subroutine haydock_restart(BSp,restart_file,ftype,iq_search,hsize,niter_file,aa_file,bb_file,phi_nm1_file,phi_n_file,comm)
    1020              : 
    1021              : !Arguments ------------------------------------
    1022              : !scalars
    1023              :  integer,intent(in) :: comm,hsize,iq_search,ftype
    1024              :  integer,intent(out) :: niter_file
    1025              :  character(len=*),intent(in) :: restart_file
    1026              :  type(excparam),intent(in) :: BSp
    1027              : !arrays
    1028              :  real(dp),allocatable,intent(out) :: bb_file(:)
    1029              :  complex(dp),allocatable,intent(out) :: aa_file(:),phi_n_file(:),phi_nm1_file(:)
    1030              : 
    1031              : !Local variables ------------------------------
    1032              : !scalars
    1033              :  integer,parameter :: master=0
    1034              :  integer :: nproc,my_rank,ierr,op_file, units(2)
    1035              :  integer :: hsize_file,use_coupling_file
    1036              :  complex(dp) :: factor_file
    1037              :  character(len=500) :: msg
    1038            0 :  type(haydock_type) :: haydock_file
    1039              : !************************************************************************
    1040              : 
    1041            0 :  nproc = xmpi_comm_size(comm); my_rank= xmpi_comm_rank(comm)
    1042            0 :  units = [std_out, ab_out]
    1043              : 
    1044            0 :  if (my_rank==master) then
    1045            0 :    call haydock_file%open(restart_file)
    1046            0 :    call haydock_file%read_dim()
    1047              : 
    1048            0 :    if (haydock_file%op/=ftype) then
    1049            0 :      write(msg,"(2(a,i0))")" Expecting restart file with filetype: ",ftype," but found ",op_file
    1050            0 :      ABI_ERROR(msg)
    1051              :    end if
    1052              : 
    1053            0 :    if (haydock_file%hsize/=hsize) then
    1054              :      write(msg,"(2(a,i0))")&
    1055            0 :        " Rank of H_exc read from file: ",hsize_file," differs from the one used in this run: ",hsize
    1056            0 :      ABI_ERROR(msg)
    1057              :    end if
    1058              : 
    1059            0 :    if (haydock_file%use_coupling /= BSp%use_coupling) then
    1060              :      write(msg,'(2(a,i0))')&
    1061            0 :        " use_coupling_file: ",use_coupling_file," differs from input file value: ",BSp%use_coupling
    1062            0 :      ABI_ERROR(msg)
    1063              :    end if
    1064              : 
    1065              :    call haydock_file%read(Bsp%q(:,iq_search), aa_file, bb_file, &
    1066            0 :                    phi_n_file, phi_nm1_file, niter_file, factor_file)
    1067              : 
    1068            0 :    if (niter_file == 0) then
    1069              :      write(msg,"(a,3f8.4,3a)")&
    1070            0 :       " Could not find q-point: ",BSp%q(:,iq_search)," in file ",TRIM(restart_file),&
    1071            0 :       " Cannot restart Haydock iterations for this q-point"
    1072            0 :      ABI_COMMENT(msg)
    1073              :    else
    1074            0 :      write(msg,'(a,i0)')" Number of iterations already performed: ",niter_file
    1075            0 :      call wrtout(units, msg)
    1076              : 
    1077            0 :      if ( ABS(haydock_file%broad - BSp%broad) > tol6) then
    1078              :        write(msg,'(2a,2(a,f8.4),a)')&
    1079            0 :         " Restart file has been produced with a different Lorentzian broadening: ",ch10,&
    1080            0 :         " broad_file: ",haydock_file%broad," input broadening: ",BSp%broad," Continuing anyway. "
    1081            0 :        ABI_WARNING(msg)
    1082              :      end if
    1083              : 
    1084            0 :      call haydock_file%close()
    1085              :    end if
    1086              :  end if
    1087              :  !
    1088              :  ! Master broadcasts the data.
    1089            0 :  call xmpi_bcast(niter_file,master,comm,ierr)
    1090              : 
    1091            0 :  if (my_rank/=master) then
    1092            0 :    ABI_MALLOC(aa_file,(niter_file))
    1093            0 :    ABI_MALLOC(bb_file,(niter_file))
    1094            0 :    ABI_MALLOC(phi_nm1_file,(hsize))
    1095            0 :    ABI_MALLOC(phi_n_file,(hsize))
    1096              :  end if
    1097              : 
    1098            0 :  call xmpi_bcast(aa_file,master,comm,ierr)
    1099            0 :  call xmpi_bcast(bb_file,master,comm,ierr)
    1100            0 :  call xmpi_bcast(phi_nm1_file,master,comm,ierr)
    1101            0 :  call xmpi_bcast(phi_n_file,master,comm,ierr)
    1102              : 
    1103            0 : end subroutine haydock_restart
    1104              : !!***
    1105              : 
    1106              : !----------------------------------------------------------------------
    1107              : 
    1108              : !!****f* m_haydock/haydock_mdf_to_tensor
    1109              : !! NAME
    1110              : !! haydock_mdf_to_tensor
    1111              : !!
    1112              : !! FUNCTION
    1113              : !! Transform macroscopic dielectric function from green function to each components of the tensor in red and cart coord.
    1114              : !!
    1115              : !! INPUTS
    1116              : !!  BSp<type(excparam)>=Parameters defining the Bethe-Salpeter calculation.
    1117              : !!    omega(BSp%nomega)=Frequency mesh for the macroscopic dielectric function (broadening is already included).
    1118              : !!  Cryst=Parameters of the crystal
    1119              : !!  eps(BSp%nomega,BSp%nq) = Macroscopic dielectric function to be written.
    1120              : !!
    1121              : !! OUTPUT
    1122              : !!  tensor_cart(BSp%nomega,6) = dielectric tensor for each frequency, order (11,22,33,12,13,23) in cart. coord.
    1123              : !!  tensor_red(BSp%nomega, 6) = idem in reduced coordinated
    1124              : !!  ierr = 0 if the tensors have been successfully computed
    1125              : !!      \= 0 if the system is ill-posed in terms of q-points (not enough or not independent q-points)
    1126              : !!
    1127              : !! SOURCE
    1128              : 
    1129           84 : subroutine haydock_mdf_to_tensor(BSp,Cryst,eps,tensor_cart,tensor_red,ierr)
    1130              : 
    1131              : !Arguments ------------------------------------
    1132              : !scalars
    1133              :  integer,intent(out) :: ierr
    1134              :  type(excparam),intent(in) :: BSp
    1135              :  type(crystal_t),intent(in) :: Cryst
    1136              : !arrays
    1137              :  complex(dp),intent(in) :: eps(BSp%nomega,BSp%nq)
    1138              :  complex(dp),intent(out) :: tensor_cart(BSp%nomega,6), tensor_red(BSp%nomega,6)
    1139              : 
    1140              : !Local variables ------------------------------
    1141              : !scalars
    1142              :  integer :: iq,info
    1143              :  real(dp) :: normqcart, normqred
    1144              : !arrays
    1145           84 :  integer,allocatable :: ipiv(:)
    1146              :  real(dp) :: qcart(3), qtmet(3)
    1147              :  real(dp) :: qred2cart(3,3),qcart2red(3,3)
    1148          168 :  complex(dp) :: qqcart(BSp%nq,6), qqred(BSp%nq,6)
    1149            0 :  complex(dp) :: b(6,BSP%nomega)
    1150              : !************************************************************************
    1151              : 
    1152              :  ! Error flag
    1153           84 :  ierr = 0
    1154              : 
    1155           84 :  if(BSp%nq /= 6) then
    1156            0 :     ierr = -1
    1157            0 :     return
    1158              :  end if
    1159              : 
    1160              :  ! Transformation matrices from reduced coordinates to cartesian coordinates
    1161         1092 :  qred2cart = two_pi*Cryst%gprimd
    1162           84 :  qcart2red = qred2cart
    1163           84 :  call matrginv(qcart2red,3,3)
    1164          588 :  do iq = 1, 6
    1165              : 
    1166              :    ! Computing cartesian q-vector
    1167         6552 :    qcart = MATMUL(qred2cart, BSp%q(:,iq))
    1168              : 
    1169              :    ! Computing product 'metric - qred' to form quadratic form
    1170         8568 :    qtmet = (two_pi**2)*MATMUL(Cryst%gmet, BSp%q(:,iq))
    1171              : 
    1172              :    ! squared norms
    1173          504 :    normqcart = qcart(1)**2+qcart(2)**2+qcart(3)**2
    1174          504 :    normqred = (normv(BSp%q(:,iq),Cryst%gmet,"G"))**2
    1175              : 
    1176              :    ! Compute line 'iq' for matrix in cartesian coord
    1177          504 :    qqcart(iq,1) = (qcart(1))**2
    1178          504 :    qqcart(iq,2) = (qcart(2))**2
    1179          504 :    qqcart(iq,3) = (qcart(3))**2
    1180          504 :    qqcart(iq,4) = 2*(qcart(1)*qcart(2))
    1181          504 :    qqcart(iq,5) = 2*(qcart(1)*qcart(3))
    1182          504 :    qqcart(iq,6) = 2*(qcart(2)*qcart(3))
    1183              : 
    1184              :    ! Compute line 'iq' for matrix in reduced coord
    1185          504 :    qqred(iq,1) = (qtmet(1))**2
    1186          504 :    qqred(iq,2) = (qtmet(2))**2
    1187          504 :    qqred(iq,3) = (qtmet(3))**2
    1188          504 :    qqred(iq,4) = 2*(qtmet(1)*qtmet(2))
    1189          504 :    qqred(iq,5) = 2*(qtmet(1)*qtmet(3))
    1190          504 :    qqred(iq,6) = 2*(qtmet(2)*qtmet(3))
    1191              : 
    1192              :    ! Renormalize line
    1193         3528 :    qqcart(iq,:) = qqcart(iq,:)/normqcart
    1194         3612 :    qqred(iq,:) = qqred(iq,:)/normqred
    1195              :  end do
    1196              : 
    1197           84 :  ABI_MALLOC(ipiv,(6))
    1198              : 
    1199              :  ! Solving linear system
    1200       279825 :  b = TRANSPOSE(eps)
    1201           84 :  call ZGESV(6,BSp%nomega,qqcart,6,ipiv,b,6,info)
    1202       240366 :  tensor_cart = TRANSPOSE(b)
    1203              : 
    1204           84 :  if(info /= 0) then
    1205              :    ! Skipping the rest of the routine
    1206            0 :    ierr = info
    1207            0 :    ABI_FREE(ipiv)
    1208            0 :    return
    1209              :  end if
    1210              : 
    1211       279825 :  b = TRANSPOSE(eps)
    1212           84 :  call ZGESV(6,BSp%nomega,qqred,6,ipiv,b,6,info)
    1213       240366 :  tensor_red = TRANSPOSE(b)
    1214              : 
    1215           84 :  if(info /= 0) ierr = info
    1216              : 
    1217           84 :  ABI_FREE(ipiv)
    1218              : 
    1219              : end subroutine haydock_mdf_to_tensor
    1220              : !!***
    1221              : 
    1222              : !----------------------------------------------------------------------
    1223              : 
    1224              : !!****f* m_haydock/haydock_psherm
    1225              : !! NAME
    1226              : !! haydock_psherm
    1227              : !!
    1228              : !! FUNCTION
    1229              : !!  Reads the excitonic Hamiltonian from file and construct the Lanczos set of vectors
    1230              : !!  by iterative matrix-vector multiplications.
    1231              : !!
    1232              : !! INPUTS
    1233              : !!  BSp<type(excparam)>=Parameters defining the Bethe-Salpeter calculation.
    1234              : !!    omega(BSp%nomega)=Frequency mesh for the macroscopic dielectric function (broadening is already included).
    1235              : !! hize
    1236              : !! my_t1,my_t2
    1237              : !! hreso(hsize,my_t1:my_t2)
    1238              : !! hcoup(hsize,my_t1:my_t2)
    1239              : !! nkets
    1240              : !! kets(hsize,nkets)
    1241              : !! comm=MPI communicator.
    1242              : !!
    1243              : !! OUTPUT
    1244              : !!  green(BSp%nomega)=The imaginary part of the macroscopic dielectric function.
    1245              : !!
    1246              : !! SOURCE
    1247              : 
    1248            0 : subroutine haydock_psherm(BSp,BS_files,Cryst,Hdr_bse,hexc,hexc_i,hsize,my_t1,my_t2,nkets,kets,green,comm)
    1249              : 
    1250              : !Arguments ------------------------------------
    1251              : !scalars
    1252              :  integer,intent(in) :: hsize,my_t1,my_t2,nkets,comm
    1253              :  type(crystal_t),intent(in) :: Cryst
    1254              :  type(excparam),intent(in) :: BSp
    1255              :  type(excfiles),intent(in) :: BS_files
    1256              :  type(Hdr_type),intent(in) :: Hdr_bse
    1257              :  type(hexc_t),intent(in) :: hexc
    1258              :  type(hexc_interp_t),intent(in) :: hexc_i
    1259              : !arrays
    1260              :  complex(dp),intent(out) :: green(BSp%nomega,BSp%nq)
    1261              :  complex(dp),intent(in) :: kets(hsize,nkets)
    1262              : 
    1263              : !Local variables ------------------------------
    1264              : !scalars
    1265              :  integer,parameter :: master=0
    1266              :  integer :: inn,itt,out_unt,nproc,my_rank,ierr
    1267              :  integer :: niter_file,niter_max,niter_done,nsppol,iq,my_nt,term_type
    1268              :  real(dp) :: ket0_hbar_norm,nfact
    1269              :  logical :: can_restart,is_converged
    1270              :  complex(dp) :: factor
    1271              :  character(len=fnlen),parameter :: tag_file="_HAYDC_SAVE"
    1272              :  character(len=500) :: msg
    1273              :  character(len=fnlen) :: restart_file,out_file
    1274              : !arrays
    1275              :  integer :: units(2)
    1276            0 :  real(dp),allocatable :: bb_file(:), bb(:)
    1277            0 :  complex(dp),allocatable :: aa(:),cc(:),phi_np1(:),phi_n(:),phi_nm1(:),cbuff(:)
    1278            0 :  complex(dp),allocatable :: aa_file(:),phi_n_file(:),phi_np1_file(:),cc_file(:), ket0(:)
    1279              :  logical :: check(2)
    1280              : !************************************************************************
    1281              : 
    1282            0 :  ABI_WARNING("Haydock + coupling is still under development")
    1283            0 :  units = [std_out, ab_out]
    1284              : 
    1285            0 :  if(BSp%use_interp) then
    1286            0 :    ABI_ERROR("Coupling is not yet implemented with interpolation")
    1287              :  end if
    1288              : 
    1289            0 :  nproc  = xmpi_comm_size(comm)
    1290            0 :  my_rank= xmpi_comm_rank(comm)
    1291            0 :  nsppol = Hdr_bse%nsppol
    1292              : 
    1293            0 :  my_nt = my_t2-my_t1+1
    1294            0 :  ABI_CHECK(my_nt>0,"One of the processors has zero columns")
    1295              : 
    1296              :  ! Multiplicative factor (k-point sampling and unit cell volume)
    1297              :  ! TODO be careful with the spin here
    1298              :  ! TODO four_pi comes from the coulomb term 1/|q| is already included in the
    1299              :  ! oscillators hence the present approach wont work if a cutoff interaction is used.
    1300            0 :  nfact = four_pi/(Cryst%ucvol*BSp%nkbz)
    1301            0 :  if (nsppol==1) nfact=two*nfact
    1302              : 
    1303            0 :  write(msg,'(a,i0)')' Haydock algorithm with MAX number of iterations: ',BSp%niter
    1304            0 :  call wrtout(std_out,msg)
    1305              :  !
    1306              :  ! Check for presence of the restart file.
    1307            0 :  can_restart=.FALSE.
    1308              : 
    1309            0 :  if ( BS_files%in_haydock_basename /= BSE_NOFILE) then
    1310            0 :    restart_file = strcat(BS_files%in_haydock_basename,tag_file)
    1311            0 :    if (file_exists(restart_file) ) then
    1312            0 :      can_restart=.TRUE.
    1313            0 :      msg = strcat(" Restarting Haydock calculation from file: ",restart_file)
    1314            0 :      call wrtout(units, msg)
    1315            0 :      ABI_ERROR("Restart is not tested")
    1316              :    else
    1317            0 :      can_restart=.FALSE.
    1318            0 :      ABI_WARNING(strcat("Cannot find restart file: ",restart_file))
    1319              :    end if
    1320              :  end if
    1321              :  !
    1322              :  ! Open the file and writes basic dimensions and info.
    1323            0 :  if (my_rank==master) then
    1324            0 :    out_file = TRIM(BS_files%out_basename)//TRIM(tag_file)
    1325            0 :    if (open_file(out_file,msg,newunit=out_unt,form="unformatted") /= 0) then
    1326            0 :      ABI_ERROR(msg)
    1327              :    end if
    1328              :    ! write header TODO: standardize this part.
    1329            0 :    write(out_unt)hsize,Bsp%use_coupling,BSE_HAYD_IMEPS,nkets,Bsp%broad
    1330              :  end if
    1331              :  !
    1332              :  ! Select the terminator for the continued fraction.
    1333            0 :  term_type=0 !; if (Bsp%hayd_term>0) term_type=2
    1334            0 :  call wrtout(std_out,sjoin("Using terminator type: ",itoa(term_type)))
    1335              :  !
    1336              :  ! Calculate green(w) for the different starting kets.
    1337            0 :  green=czero
    1338            0 :  do iq=1,nkets
    1339            0 :    ABI_MALLOC(ket0,(my_nt))
    1340            0 :    ket0 = kets(my_t1:my_t2,iq)
    1341              :    !
    1342            0 :    niter_file=0
    1343              : 
    1344            0 :    if (can_restart) then
    1345              :      call haydock_restart(BSp,restart_file,BSE_HAYD_IMEPS,iq,hsize,&
    1346            0 :                           niter_file,aa_file,bb_file,phi_np1_file,phi_n_file,comm)
    1347              :    end if
    1348              : 
    1349            0 :    ABI_MALLOC(phi_nm1,(my_nt))
    1350            0 :    ABI_MALLOC(phi_n,(my_nt))
    1351            0 :    ABI_MALLOC(phi_np1,(my_nt))
    1352              :    !
    1353              :    ! TODO: Note the different convention used for the coefficients
    1354              :    ! Should use the same convention in the Hermitian case.
    1355            0 :    niter_max = niter_file + Bsp%niter
    1356            0 :    ABI_MALLOC(aa,(niter_max))
    1357            0 :    ABI_MALLOC(bb,(niter_max+1))
    1358            0 :    ABI_MALLOC(cc,(niter_max+1))
    1359            0 :    aa=czero; bb=czero; cc=czero
    1360              : 
    1361            0 :    if (niter_file==0) then ! Calculation from scratch.
    1362            0 :      phi_n   = ket0
    1363            0 :      call hexc%matmul_full(hexc_i, phi_n, phi_np1, -1)
    1364              :      !phi_np1 = MATMUL(hreso,ket0) - MATMUL(hcoup,CONJG(ket0))
    1365            0 :      ket0_hbar_norm = SQRT(two*DBLE(DOT_PRODUCT(phi_n,phi_np1)))
    1366            0 :      phi_n   = phi_n  /ket0_hbar_norm
    1367            0 :      phi_np1 = phi_np1/ket0_hbar_norm
    1368              :      !ket0    = ket0/ket0_hbar_norm
    1369            0 :      cc(1)=zero ! <P|F|P>
    1370              :      !cc(1) =  DOT_PRODUCT(ket0,phi_np1)
    1371              :      !write(std_out,*)" cc(1), ket0_hbar_norm =",cc(1),ket0_hbar_norm
    1372              : 
    1373            0 :      phi_nm1 = czero
    1374            0 :      niter_done=0  ! TODO Be careful here
    1375              : 
    1376              :    else ! Use the previously calculates a and b.
    1377            0 :      niter_done=niter_file
    1378            0 :      ABI_ERROR("Restart not coded")
    1379              :      !aa(1:niter_done) = aa_file
    1380              :      !bb(1:niter_done) = bb_file
    1381              :      !phi_np1=phi_np1_file(my_t1:my_t2)   ! Select the slice treated by this node.
    1382              :      !phi_n  =phi_n_file  (my_t1:my_t2)
    1383              :    end if
    1384              : 
    1385            0 :    if (can_restart) then
    1386            0 :      ABI_FREE(aa_file)
    1387            0 :      ABI_FREE(bb_file)
    1388            0 :      ABI_FREE(cc_file)
    1389              :      ABI_FREE(phi_np1_file)
    1390              :      ABI_FREE(phi_n_file)
    1391              :    end if
    1392              : 
    1393              :    ! This factor gives the correct results
    1394            0 :    factor = -nfact*ket0_hbar_norm / SQRT(two)
    1395              : 
    1396              :    ! Which quantity should be checked for convergence?
    1397            0 :    check = (/.TRUE.,.TRUE./)
    1398            0 :    if (ABS(Bsp%haydock_tol(2)-one)<tol6) check = (/.TRUE. ,.FALSE./)
    1399            0 :    if (ABS(Bsp%haydock_tol(2)-two)<tol6) check = (/.FALSE.,.TRUE./)
    1400              : 
    1401              :    call haydock_psherm_optalgo(niter_done,niter_max,BSp%nomega,BSp%omega,BSp%haydock_tol(1),check,hexc,hexc_i,&
    1402              :       hsize,my_t1,my_t2,factor,term_type,aa,bb,cc,ket0,ket0_hbar_norm,phi_nm1,phi_n,phi_np1,&
    1403            0 :       green(:,iq),inn,is_converged,comm)
    1404              : 
    1405              :    ! Save the a"s and the b"s for possible restarting.
    1406              :    ! 1) Info on the Q.
    1407              :    ! 2) Number of iterations performed.
    1408              :    ! 3) do iter=1,niter_performed
    1409              :    !      aa(iter),bb(iter)
    1410              :    !    end do
    1411              :    ! 4) |n-1>
    1412              :    !    |n>
    1413              :    !    |n+1>
    1414              :    !
    1415            0 :    if (my_rank==master) then ! Open the file and writes basic dimensions and info.
    1416            0 :      write(out_unt)Bsp%q(:,iq)
    1417            0 :      write(out_unt)MIN(inn,niter_max)  ! NB: if the previous loop completed inn=niter_max+1
    1418            0 :      do itt=1,MIN(inn,niter_max)        !     if we exited then inn is not incremented by one.
    1419            0 :        write(out_unt)itt,aa(itt),bb(itt)
    1420              :      end do
    1421              :    end if
    1422              :    !
    1423              :    ! cbuff is used as workspace to gather |n-1>, |n> and |n+1>.
    1424            0 :    ABI_MALLOC(cbuff,(hsize))
    1425            0 :    cbuff=czero; cbuff(my_t1:my_t2) = phi_nm1
    1426            0 :    call xmpi_sum_master(cbuff,master,comm,ierr)
    1427            0 :    if (my_rank==master) write(out_unt) cbuff ! |n-1>
    1428              : 
    1429            0 :    cbuff=czero; cbuff(my_t1:my_t2) = phi_n
    1430            0 :    call xmpi_sum_master(cbuff,master,comm,ierr)
    1431            0 :    if (my_rank==master) write(out_unt) cbuff ! |n>
    1432              : 
    1433            0 :    cbuff=czero; cbuff(my_t1:my_t2) = phi_np1
    1434            0 :    call xmpi_sum_master(cbuff,master,comm,ierr)
    1435            0 :    if (my_rank==master) write(out_unt) cbuff ! |n+1>
    1436              : 
    1437            0 :    ABI_FREE(phi_nm1)
    1438            0 :    ABI_FREE(phi_n)
    1439            0 :    ABI_FREE(phi_np1)
    1440            0 :    ABI_FREE(cbuff)
    1441            0 :    ABI_FREE(aa)
    1442            0 :    ABI_FREE(bb)
    1443            0 :    ABI_FREE(cc)
    1444            0 :    ABI_FREE(ket0)
    1445              :  end do ! iq
    1446              : 
    1447            0 :  if (my_rank==master) close(out_unt)
    1448              : 
    1449            0 :  call xmpi_barrier(comm)
    1450              : 
    1451            0 : end subroutine haydock_psherm
    1452              : !!***
    1453              : 
    1454              : !----------------------------------------------------------------------
    1455              : 
    1456              : !!****f* m_haydock/haydock_psherm_optalgo
    1457              : !! NAME
    1458              : !! haydock_psherm_optalgo
    1459              : !!
    1460              : !! FUNCTION
    1461              : !!  Haydock algorithm for pseudo-hermitian matrix
    1462              : !!
    1463              : !! INPUTS
    1464              : !!  niter_done=Number of iterations already performed (0 if the run starts from scratch).
    1465              : !!  niter_tot=Max number of iterations. Always > niter_done
    1466              : !!  nomega=Number of Frequency points for the evaluation of the matrix element.
    1467              : !!  omega(nomega)=Frequency set (imaginary part is already included).
    1468              : !!  tol_iter=Tollerance used to stop the the algorithm.
    1469              : !!  check(2)=Logical flags to specify where both the real and the imaginary part of the
    1470              : !!    matrix elements of the Green functions have to be checked for convergence.
    1471              : !!  hsize=Size of the blocks.
    1472              : !!  my_t1,my_t2=Indeces of the first and last column stored treated by this done.
    1473              : !!  term_type=0 if no terminator is used, 1 otherwise.
    1474              : !!  hreso(hsize,my_t1:my_t2)=The columns of the resonant block.
    1475              : !!  hcoup(hsize,my_t1:my_t2)=The columns of the coupling block.
    1476              : !!  factor
    1477              : !!  comm=MPI communicator.
    1478              : !!
    1479              : !! OUTPUT
    1480              : !!  green(nomega)=Output matrix elements.
    1481              : !!  inn=Last iteration performed.
    1482              : !!  is_converged=.TRUE. of the algorithm converged.
    1483              : !!
    1484              : !! SIDE EFFECTS
    1485              : !!  phi_nm1(my_t2-my_t1+1), phi_n(my_t2-my_t1+1)
    1486              : !!    input: vectors used to initialize the iteration
    1487              : !!    output: the vectors obtained in the last iteration
    1488              : !!  aa(niter_tot) and bb(niter_tot+1)
    1489              : !!    if niter_done>0: aa(1:niter_done), bb(1:niter_done) store the coefficients of the previous run.
    1490              : !!    when the routine returns aa(1:inn) and bb(1:inn) contain the matrix elements of the tridiagonal form.
    1491              : !!  cc(niter_tot+1)
    1492              : !!
    1493              : !! SOURCE
    1494              : 
    1495            0 : subroutine haydock_psherm_optalgo(niter_done,niter_tot,nomega,omega,tol_iter,check,hexc,hexc_i,hsize,my_t1,my_t2,&
    1496            0 : &  factor,term_type,aa,bb,cc,ket0,ket0_hbar_norm,phi_nm1,phi_n,phi_np1,green,inn,is_converged,comm)
    1497              : 
    1498              : !Arguments ------------------------------------
    1499              : !scalars
    1500              :  integer,intent(in) :: niter_tot,niter_done,nomega,comm,hsize,my_t1,my_t2,term_type
    1501              :  integer,intent(out) :: inn
    1502              :  logical,intent(out) :: is_converged
    1503              :  real(dp),intent(in) :: tol_iter,ket0_hbar_norm
    1504              :  complex(dp),intent(in) :: factor
    1505              :  type(hexc_t),intent(in) :: hexc
    1506              :  type(hexc_interp_t),intent(in) :: hexc_i
    1507              : !arrays
    1508              :  real(dp),intent(inout) :: bb(niter_tot+1)
    1509              :  complex(dp),intent(out) :: green(nomega)
    1510              :  complex(dp),intent(in) :: omega(nomega)
    1511              :  complex(dp),intent(inout) :: aa(niter_tot),cc(niter_tot+1)
    1512              :  complex(dp),intent(in) :: ket0(my_t2-my_t1+1)
    1513              :  complex(dp),intent(inout) :: phi_nm1(my_t2-my_t1+1)
    1514              :  complex(dp),intent(inout) :: phi_n  (my_t2-my_t1+1)
    1515              :  complex(dp),intent(inout) :: phi_np1(my_t2-my_t1+1)
    1516              :  logical,intent(in) :: check(2)
    1517              : 
    1518              : !Local variables ------------------------------
    1519              : !scalars
    1520              :  integer :: my_nt,niter_min,nconv,parity,ii,jj,tdim,ierr
    1521              :  integer :: row_max,col_max,nlev
    1522              :  character(len=500) :: msg
    1523              :  real(dp) :: max_err,mean_err,mean_err2,std_dev,err
    1524              :  logical :: keep_vectors=.TRUE.
    1525              : !arrays
    1526              :  integer :: units(2)
    1527            0 :  real(dp) :: abs_err(nomega,2) !,ww_err(nomega,2)
    1528            0 :  complex(dp) :: gn0(nomega,niter_tot)
    1529            0 :  complex(dp),allocatable :: oldg(:),newg(:)
    1530            0 :  complex(dp),allocatable :: hphi_n(:),save_phi(:,:)
    1531            0 :  complex(dp),allocatable ::  alpha(:,:),beta(:,:),ovlp(:,:)
    1532            0 :  complex(dp),allocatable :: phi_test(:),phi_test2(:),g00(:)
    1533              :  logical :: test(2)
    1534              : !************************************************************************
    1535              : 
    1536              :  ABI_UNUSED(ket0_hbar_norm)
    1537            0 :  units = [std_out, ab_out]
    1538              : 
    1539            0 :  my_nt = my_t2-my_t1+1
    1540              : 
    1541            0 :  ABI_MALLOC(oldg,(nomega))
    1542            0 :  ABI_MALLOC(newg,(nomega))
    1543            0 :  ABI_MALLOC(g00,(nomega))
    1544            0 :  oldg=czero; newg=czero; g00=czero
    1545            0 :  nconv=0
    1546              : 
    1547            0 :  keep_vectors = (keep_vectors.and.xmpi_comm_size(comm)==1)
    1548            0 :  if (keep_vectors) then
    1549            0 :    ABI_MALLOC_OR_DIE(save_phi,(my_t2-my_t1+1,niter_tot), ierr)
    1550            0 :    save_phi=czero
    1551              :  end if
    1552              : 
    1553            0 :  ABI_MALLOC(hphi_n,(hsize))
    1554              : 
    1555            0 :  do inn=niter_done+1,niter_tot
    1556              :    !
    1557              :    ! a(n) = <Vn+1|F|Vn+1> = <Vn|HFH|Vn>) = 0 by symmetry.
    1558            0 :    aa(inn)=zero
    1559              : 
    1560              :    ! |n+1> = |n+1> - a(n)|Vn> - a(n)|n-1>
    1561            0 :    phi_np1 = phi_np1 - bb(inn)*phi_nm1
    1562              :    !
    1563              :    ! |n-1> = |n>
    1564              :    ! |n>   = |n+1>
    1565            0 :    phi_nm1 = phi_n
    1566            0 :    phi_n   = phi_np1
    1567              : 
    1568              :    !|n+1> = H |n> using all eh components.
    1569            0 :    parity = (-1)**(inn+1)
    1570            0 :    call hexc%matmul_full(hexc_i, phi_n, phi_np1, parity)
    1571              : 
    1572              :    !phi_np1 = MATMUL(hreso,phi_n) + parity * MATMUL(hcoup,CONJG(phi_n))
    1573              :    !call xmpi_sum(hphi_np1,comm,ierr)
    1574              :    !
    1575              :    ! B(n+1)= <n|F|n+1>^(1/2) = <n|FH|n>^(1/2))= (2*Re(<n|V+1>))^(1/2)
    1576              :    ! by symmetry, where the dot_product is done in the resonant eh sub-space.
    1577              :    !
    1578            0 :    bb(inn+1)=SQRT(two*DBLE(DOT_PRODUCT(phi_n,phi_np1)))
    1579              :    !bb(inn+1)=two*DBLE(DOT_PRODUCT(phi_n,phi_np1))
    1580              :    !call xmpi_sum(bb(inn+1),comm,ierr)
    1581              :    !bb(inn+1)=SQRT(bb(inn+1)
    1582              :    !
    1583              :    !|n+1> =|n+1>/B(n+1)
    1584            0 :    phi_n   = phi_n  /bb(inn+1)
    1585            0 :    phi_np1 = phi_np1/bb(inn+1)
    1586              : 
    1587            0 :    if (keep_vectors) save_phi(:,inn) = phi_n
    1588              : 
    1589            0 :    parity = (-1)**(inn+1)
    1590              :    !if (parity==-1) then
    1591              :    !  cc(inn+1)=czero
    1592              :    !else
    1593            0 :      cc(inn+1)=DOT_PRODUCT(ket0,phi_n) + parity * DOT_PRODUCT(phi_n,ket0)
    1594              :    !end if
    1595              :    !call xmpi_sum(cc(inn+1),comm,ierr)
    1596              : 
    1597            0 :    write(msg,'(a,i0,a,3es12.4)')' Iteration number ',inn,', b_i RE(c_i+1) IM(c_i+1) ',bb(inn),REAL(cc(inn+1)),AIMAG(cc(inn+1))
    1598            0 :    call wrtout(std_out,msg)
    1599              : 
    1600            0 :    call continued_fract(inn,term_type,aa,bb(2:),nomega,omega,g00)
    1601            0 :    gn0(:,1) = g00
    1602              : 
    1603              :    if (.FALSE.) then
    1604              :      gn0(:,2) = (one - omega(:)*g00(:))/bb(2)
    1605              :      do ii=3,inn
    1606              :        gn0(:,ii) = -(-bb(ii)*gn0(:,ii-2) -omega(:)*gn0(:,ii-1))/bb(ii+1)
    1607              :      end do
    1608              :    else
    1609            0 :      do ii=2,inn
    1610            0 :        nlev = inn-ii
    1611            0 :        call continued_fract(nlev,term_type,aa,bb(ii+1:),nomega,omega,g00)
    1612            0 :        gn0(:,ii) = +bb(ii+1) * g00 * gn0(:,ii-1)
    1613              :      end do
    1614              :    end if
    1615              : 
    1616            0 :    newg=czero
    1617            0 :    do ii=1,inn
    1618            0 :      newg(:) = newg + cc(ii)* gn0(:,ii)
    1619              :    end do
    1620            0 :    newg = factor*newg
    1621              :    !
    1622              :    ! Avoid spurious convergence.
    1623            0 :    niter_min=4; if (niter_done>1) niter_min=niter_done+1
    1624            0 :    if (inn>niter_min) then
    1625            0 :      test=.TRUE.
    1626            0 :      abs_err(:,1) = ABS(DBLE (newg-oldg))
    1627            0 :      abs_err(:,2) = ABS(AIMAG(newg-oldg))
    1628              :      !
    1629            0 :      if (tol_iter>zero) then
    1630              :        ! Test on the L1 norm.
    1631            0 :        if (check(1)) test(1) = SUM(abs_err(:,1)) < tol_iter*SUM(ABS(DBLE (newg)))
    1632            0 :        if (check(2)) test(2) = SUM(abs_err(:,2)) < tol_iter*SUM(ABS(AIMAG(newg)))
    1633              :      else
    1634              :        ! Stringent test for each point.
    1635            0 :        if (check(1)) test(1) = ALL( abs_err(:,1) < -tol_iter*ABS(DBLE (newg)))
    1636            0 :        if (check(2)) test(2) = ALL( abs_err(:,2) < -tol_iter*ABS(AIMAG(newg)))
    1637              :      end if
    1638              :      !
    1639            0 :      if (ALL(test)) then
    1640            0 :        nconv = nconv+1
    1641              :      else
    1642              :        nconv = 0
    1643              :      end if
    1644            0 :      if (nconv==2) then
    1645            0 :        if(inn<100)then
    1646              :          write(msg,'(a,es10.2,a)')&
    1647            0 :           " >>> Haydock algorithm converged twice within haydock_tol= ",tol_iter," after less than 100 iterations."
    1648              :        else
    1649              :          write(msg,'(a,es10.2,a,i0,a)')&
    1650            0 :           " >>> Haydock algorithm converged twice within haydock_tol= ",tol_iter," after ",inn," iterations."
    1651              :        endif
    1652            0 :        call wrtout(units, msg)
    1653            0 :        EXIT
    1654              :      end if
    1655              :    end if
    1656              :    !
    1657            0 :    oldg = newg
    1658              :  end do ! inn
    1659              : 
    1660            0 :  green = newg
    1661            0 :  if (nconv/=2) then
    1662              :    write(msg,'(a,es10.2,a,i0,a)')&
    1663            0 :     " WARNING: Haydock algorithm did not converge within ",tol_iter," after ",niter_tot," iterations."
    1664            0 :    call wrtout(units, msg)
    1665              :  end if
    1666              : 
    1667            0 :  is_converged = (nconv==2)
    1668              : 
    1669            0 :  ABI_FREE(oldg)
    1670            0 :  ABI_FREE(newg)
    1671            0 :  ABI_FREE(g00)
    1672            0 :  ABI_FREE(hphi_n)
    1673              : 
    1674            0 :  if (keep_vectors) then
    1675            0 :    tdim = MIN(inn,niter_tot)
    1676            0 :    ABI_MALLOC(ovlp,(tdim,tdim))
    1677              : 
    1678            0 :    ABI_MALLOC(phi_test,(hsize))
    1679            0 :    ABI_MALLOC(phi_test2,(hsize))
    1680              : 
    1681            0 :    max_err=smallest_real; mean_err=zero; mean_err2=zero; row_max=-1
    1682            0 :    do ii=1,tdim
    1683            0 :      parity = (-1)**(ii+1)
    1684            0 :      phi_test  = save_phi(:,ii)
    1685            0 :      call hexc%matmul_full(hexc_i, phi_test, phi_test2, parity)
    1686              :      !phi_test2 = MATMUL(hreso,phi_test) + parity * MATMUL(hcoup,CONJG(phi_test))
    1687            0 :      ovlp(ii,ii) = DOT_PRODUCT(phi_test,phi_test2) + DOT_PRODUCT(phi_test2,phi_test)
    1688            0 :      err = ABS(ovlp(ii,ii)-cone)
    1689            0 :      mean_err  = mean_err + err
    1690            0 :      mean_err2 = mean_err2 + err**2
    1691            0 :      if (err > max_err) then
    1692            0 :        max_err = err
    1693            0 :        row_max = ii
    1694              :      end if
    1695              :    end do
    1696            0 :    mean_err = mean_err/tdim
    1697            0 :    std_dev = mean_err2/tdim -mean_err**2
    1698              :    write(std_out,'(a,i0,1x,3es14.6)') &
    1699            0 :     " Error in normalization (ii, max_err,mean,std_dev): ",row_max,max_err,mean_err,std_dev
    1700              : 
    1701            0 :    ABI_FREE(phi_test)
    1702            0 :    ABI_FREE(phi_test2)
    1703              : 
    1704            0 :    ABI_MALLOC(alpha,(hsize,tdim))
    1705              : 
    1706              :    ! Less efficient but for sake of simplicity with hexc_matmul
    1707              :    ! TODO possibility to call hreso * phi, and hcoup * phi separately
    1708            0 :    do ii=1,tdim
    1709            0 :      parity = (-1)**(ii+1)
    1710            0 :      call hexc%matmul_full(hexc_i, save_phi(:,ii), alpha(:,ii), parity)
    1711              :    end do
    1712              : 
    1713              :    !alpha = MATMUL(hreso,save_phi(:,1:tdim))
    1714              :    !
    1715              :    !do ii=1,tdim
    1716              :    !  parity = (-1)**(ii+1)
    1717              :    !  alpha(:,ii) =  alpha(:,ii) + parity*MATMUL(hcoup,CONJG(save_phi(:,ii)))
    1718              :    !end do
    1719              : 
    1720            0 :    ovlp = MATMUL(TRANSPOSE(CONJG(save_phi(:,1:tdim))),alpha)
    1721              : 
    1722            0 :    ABI_MALLOC(beta,(hsize,tdim))
    1723            0 :    do ii=1,tdim
    1724            0 :      parity = (-1)**(ii+1)
    1725            0 :      beta(:,ii)  =  parity*save_phi(:,ii)
    1726            0 :      alpha(:,ii) = -parity*alpha(:,ii)
    1727              :    end do
    1728              : 
    1729            0 :    ovlp = ovlp - MATMUL(TRANSPOSE(CONJG(beta)),alpha)
    1730              : 
    1731            0 :    max_err=smallest_real; row_max=-1; col_max=-1
    1732            0 :    mean_err=zero; mean_err2=zero
    1733            0 :    do jj=1,tdim
    1734            0 :      do ii=1,jj
    1735            0 :        err = ABS(ovlp(ii,jj))
    1736            0 :        if (ii==jj) err = ABS(err - one)
    1737            0 :        mean_err  = mean_err + err
    1738            0 :        mean_err2 = mean_err2 + err**2
    1739            0 :        if (err > max_err) then
    1740            0 :          max_err = err
    1741            0 :          row_max=ii
    1742            0 :          col_max=jj
    1743              :        end if
    1744              :      end do
    1745              :    end do
    1746              : 
    1747            0 :    mean_err = mean_err/(tdim*(tdim+1)/2)
    1748            0 :    std_dev = mean_err2/(tdim*(tdim+1)/2) - mean_err**2
    1749              :    write(std_out,'(a,2(i0,1x),3es14.6)')&
    1750            0 :      " Error in Hbar-ortho (i,j), max_err, mean, std_dev ",row_max,col_max,max_err,mean_err,std_dev
    1751              :    !call print_arr(ovlp,max_r=185,max_c=10,unit=std_out)
    1752              : 
    1753            0 :    ABI_FREE(alpha)
    1754            0 :    ABI_FREE(beta)
    1755            0 :    ABI_FREE(ovlp)
    1756            0 :    ABI_FREE(save_phi)
    1757              :  end if
    1758              : 
    1759            0 : end subroutine haydock_psherm_optalgo
    1760              : !!***
    1761              : 
    1762              : !----------------------------------------------------------------------
    1763              : 
    1764              : !!****f* m_haydock/haydock_bilanczos
    1765              : !! NAME
    1766              : !! haydock_bilanczos
    1767              : !!
    1768              : !! FUNCTION
    1769              : !!  Reads the excitonic Hamiltonian from file and construct the Lanczos set of vectors
    1770              : !!  by iterative matrix-vector multiplications for any general matrix.
    1771              : !!
    1772              : !! INPUTS
    1773              : !!  BSp<type(excparam)>=Parameters defining the Bethe-Salpeter calculation.
    1774              : !!    omega(BSp%nomega)=Frequency mesh for the macroscopic dielectric function (broadening is already included).
    1775              : !! hize
    1776              : !! my_t1,my_t2
    1777              : !! hreso(hsize,my_t1:my_t2)
    1778              : !! hcoup(hsize,my_t1:my_t2)
    1779              : !! nkets
    1780              : !! kets(hsize,nkets)
    1781              : !! comm=MPI communicator.
    1782              : !!
    1783              : !! OUTPUT
    1784              : !!  green(BSp%nomega)=The imaginary part of the macroscopic dielectric function.
    1785              : !!
    1786              : !! SOURCE
    1787              : 
    1788           10 : subroutine haydock_bilanczos(BSp,BS_files,Cryst,Hdr_bse,hexc,hexc_i,hsize,my_t1,my_t2,nkets,kets,ep_renorms,green,comm)
    1789              : 
    1790              : !Arguments ------------------------------------
    1791              : !scalars
    1792              :  integer,intent(in) :: hsize,my_t1,my_t2,nkets,comm
    1793              :  type(crystal_t),intent(in) :: Cryst
    1794              :  type(excparam),intent(in) :: BSp
    1795              :  type(excfiles),intent(in) :: BS_files
    1796              :  type(Hdr_type),intent(in) :: Hdr_bse
    1797              : !arrays
    1798              :  complex(dp),intent(out) :: green(BSp%nomega,BSp%nq)
    1799              :  complex(dp),intent(in) :: kets(hsize,nkets)
    1800              :  complex(dp),intent(in) :: ep_renorms(hsize)
    1801              : 
    1802              : !Local variables ------------------------------
    1803              : !scalars
    1804              :  integer,parameter :: master=0
    1805              :  integer :: inn,itt,out_unt,nproc,my_rank,ierr
    1806              :  integer :: niter_file,niter_max,niter_done,nsppol,iq,my_nt,term_type,n_all_omegas
    1807              :  real(dp) :: ket0_hbar_norm,nfact,norm
    1808              :  logical :: can_restart,is_converged
    1809              :  complex(dp) :: factor
    1810              :  character(len=fnlen),parameter :: tag_file="_HAYDC_SAVE"
    1811              :  character(len=500) :: msg
    1812              :  character(len=fnlen) :: restart_file,out_file
    1813              :  type(hexc_t),intent(in) :: hexc
    1814              :  type(hexc_interp_t),intent(in) :: hexc_i
    1815              : !arrays
    1816           10 :  complex(dp),allocatable :: aa_file(:),bb_file(:),cc_file(:)
    1817           10 :  complex(dp),allocatable :: aa(:),bb(:),cc(:)
    1818           10 :  complex(dp),allocatable :: phi_np1(:),phi_n(:),phi_nm1(:)
    1819           10 :  complex(dp),allocatable :: phit_np1(:),phit_n(:),phit_nm1(:)
    1820           10 :  complex(dp),allocatable :: cbuff(:), phi_n_file(:),phi_np1_file(:)
    1821           10 :  complex(dp),allocatable :: ket0(:), hphi_n(:), hphit_n(:)
    1822           10 :  complex(dp),allocatable :: all_omegas(:),green_temp(:,:)
    1823              :  logical :: check(2)
    1824              : !************************************************************************
    1825              : 
    1826           10 :  ABI_WARNING("Haydock with Bilanczos is still under development")
    1827              : 
    1828           10 :  if(BSp%use_interp) then
    1829            0 :    ABI_ERROR("Bilanczos is not yet implemented with interpolation")
    1830              :  end if
    1831              : 
    1832           10 :  nproc  = xmpi_comm_size(comm)
    1833           10 :  my_rank= xmpi_comm_rank(comm)
    1834           10 :  nsppol = Hdr_bse%nsppol
    1835              : 
    1836           10 :  my_nt = my_t2-my_t1+1
    1837           10 :  ABI_CHECK(my_nt>0,"One of the processors has zero columns")
    1838              : 
    1839              :  ! Multiplicative factor (k-point sampling and unit cell volume)
    1840              :  ! TODO be careful with the spin here
    1841              :  ! TODO four_pi comes from the coulomb term 1/|q| is already included in the
    1842              :  ! oscillators hence the present approach wont work if a cutoff interaction is used.
    1843           10 :  nfact = four_pi/(Cryst%ucvol*BSp%nkbz)
    1844           10 :  if (nsppol==1) nfact=two*nfact
    1845              : 
    1846           10 :  write(msg,'(a,i0)')' Bi-Lanczos algorithm with MAX number of iterations: ',BSp%niter
    1847           10 :  call wrtout(std_out,msg)
    1848              :  !
    1849              :  ! Check for presence of the restart file.
    1850           10 :  can_restart=.FALSE.
    1851              : 
    1852           10 :  if (BS_files%in_haydock_basename /= BSE_NOFILE) then
    1853            0 :    restart_file = strcat(BS_files%in_haydock_basename,tag_file)
    1854            0 :    if (file_exists(restart_file) ) then
    1855            0 :      can_restart=.TRUE.
    1856            0 :      msg = strcat(" Restarting Haydock calculation from file: ",restart_file)
    1857            0 :      call wrtout(std_out,msg)
    1858            0 :      call wrtout(ab_out,msg)
    1859            0 :      ABI_ERROR("Restart is not implemented")
    1860              :    else
    1861            0 :      can_restart=.FALSE.
    1862            0 :      ABI_WARNING(strcat("Cannot find restart file: ",restart_file))
    1863              :    end if
    1864              :  end if
    1865              :  !
    1866              :  ! Open the file and writes basic dimensions and info.
    1867           10 :  if (my_rank==master) then
    1868           10 :    out_file = TRIM(BS_files%out_basename)//TRIM(tag_file)
    1869           10 :    if (open_file(out_file,msg,newunit=out_unt,form="unformatted") /= 0) then
    1870            0 :      ABI_ERROR(msg)
    1871              :    end if
    1872              :    ! write header TODO: standardize this part.
    1873           10 :    write(out_unt)hsize,Bsp%use_coupling,BSE_HAYD_IMEPS,nkets,Bsp%broad
    1874              :  end if
    1875              :  !
    1876              :  ! Select the terminator for the continued fraction.
    1877           10 :  term_type=0 !; if (Bsp%hayd_term>0) term_type=2
    1878           10 :  call wrtout(std_out,sjoin("Using terminator type: ",itoa(term_type)))
    1879              :  !
    1880              :  ! Calculate green(w) for the different starting kets.
    1881        60130 :  green=czero
    1882           70 :  do iq=1,nkets
    1883          180 :    ABI_MALLOC(ket0,(hexc%hsize))
    1884         5880 :    ket0 = kets(:,iq)
    1885              :    !
    1886           60 :    niter_file=0
    1887              : 
    1888              :    if (can_restart) then
    1889              : !     call haydock_restart(BSp,restart_file,BSE_HAYD_IMEPS,iq,hsize,&
    1890              : !&      niter_file,aa_file,bb_file,phi_np1_file,phi_n_file,comm)
    1891              :    end if
    1892              :    !
    1893          180 :    ABI_MALLOC(phi_nm1,(my_nt))
    1894          120 :    ABI_MALLOC(phi_n,(my_nt))
    1895          120 :    ABI_MALLOC(phi_np1,(my_nt))
    1896          120 :    ABI_MALLOC(phit_nm1,(my_nt))
    1897          120 :    ABI_MALLOC(phit_n,(my_nt))
    1898          120 :    ABI_MALLOC(phit_np1,(my_nt))
    1899          120 :    ABI_MALLOC(hphi_n,(hexc%hsize))
    1900          120 :    ABI_MALLOC(hphit_n,(hexc%hsize))
    1901              :    !
    1902              :    ! TODO: Note the different convention used for the coefficients
    1903              :    ! Should use the same convention in the Hermitian case.
    1904           60 :    niter_max = niter_file + Bsp%niter
    1905        60180 :    ABI_CALLOC(aa,(niter_max))
    1906        60120 :    ABI_CALLOC(bb,(niter_max))
    1907        60120 :    ABI_CALLOC(cc,(niter_max))
    1908              : 
    1909              :    if (niter_file==0) then ! Calculation from scratch.
    1910         5880 :      phi_nm1 = ket0(my_t1:my_t2)
    1911         5880 :      phit_nm1 = ket0(my_t1:my_t2)
    1912           60 :      norm = DZNRM2(hexc%hsize,ket0,1)
    1913         5820 :      phi_nm1=phi_nm1/norm
    1914         5820 :      phit_nm1=phit_nm1/norm
    1915              : 
    1916           60 :      call hexc%matmul_elphon(phi_nm1,hphi_n,'N',ep_renorms)
    1917           60 :      call hexc%matmul_elphon(phit_nm1,hphit_n,'C',ep_renorms)
    1918              : 
    1919           60 :      aa(1)=xdotc(my_nt,phit_nm1,1,hphi_n(my_t1:),1)
    1920           60 :      call xmpi_sum(aa(1:1),comm,ierr)
    1921              : 
    1922         5880 :      phi_n = hphi_n(my_t1:my_t2) - aa(1)*phi_nm1
    1923         5880 :      phit_n = hphit_n(my_t1:my_t2) - CONJG(aa(1))*phit_nm1
    1924              : 
    1925           60 :      bb(1)=xdotc(my_nt,phi_n,1,phi_n,1)
    1926           60 :      call xmpi_sum(bb(1:1),comm,ierr)
    1927           60 :      bb(1) = SQRT(bb(1))
    1928              : 
    1929           60 :      cc(1)=xdotc(my_nt,phit_n,1,phi_n,1)
    1930           60 :      call xmpi_sum(cc(1:1),comm,ierr)
    1931           60 :      cc(1) = cc(1)/bb(1)
    1932              : 
    1933         5820 :      phi_n   = phi_n  /bb(1)
    1934         5820 :      phit_n  = phit_n /CONJG(cc(1))
    1935           60 :      niter_done=1  ! TODO Be careful here
    1936              : 
    1937              :    else ! Use the previously calculates a and b.
    1938              :      niter_done=niter_file
    1939              :      ABI_ERROR("Restart not coded")
    1940              :      !aa(1:niter_done) = aa_file
    1941              :      !bb(1:niter_done) = bb_file
    1942              :      !phi_np1=phi_np1_file(my_t1:my_t2)   ! Select the slice treated by this node.
    1943              :      !phi_n  =phi_n_file  (my_t1:my_t2)
    1944              :    end if
    1945              : 
    1946           60 :    if (can_restart) then
    1947            0 :      ABI_FREE(aa_file)
    1948              :      ABI_FREE(bb_file)
    1949              :      ABI_FREE(cc_file)
    1950              :      ABI_FREE(phi_np1_file)
    1951              :      ABI_FREE(phi_n_file)
    1952              :    end if
    1953              : 
    1954              :    ! This factor gives the correct results
    1955           60 :    factor = -nfact*(DZNRM2(hexc%hsize,ket0,1)**2)
    1956              : 
    1957              :    ! Which quantity should be checked for convergence?
    1958           60 :    check = (/.TRUE.,.TRUE./)
    1959           60 :    if (ABS(Bsp%haydock_tol(2)-one)<tol6) check = (/.TRUE. ,.FALSE./)
    1960           60 :    if (ABS(Bsp%haydock_tol(2)-two)<tol6) check = (/.FALSE.,.TRUE./)
    1961              :    ! Create new frequencies "mirror" in negative range to add
    1962              :    ! their contributions. Can be improved by computing only once
    1963              :    ! zero frequency, but loosing clearness
    1964           60 :    n_all_omegas = 2*BSp%nomega
    1965              : 
    1966          180 :    ABI_MALLOC(all_omegas,(n_all_omegas))
    1967              :    ! Put all omegas with frequency > 0 in table
    1968        60120 :    all_omegas(BSp%nomega+1:n_all_omegas) = BSp%omega
    1969              :    ! Put all omegas with frequency < 0
    1970              :    ! Warning, the broadening must be kept positive
    1971        60120 :    all_omegas(1:BSp%nomega) = -DBLE(BSp%omega(BSp%nomega:1:-1)) + j_dpc*AIMAG(BSp%omega(BSp%nomega:1:-1))
    1972              : 
    1973          240 :    ABI_MALLOC(green_temp,(n_all_omegas,nkets))
    1974              : 
    1975              :    call haydock_bilanczos_optalgo(niter_done,niter_max,n_all_omegas,all_omegas,BSp%haydock_tol(1),check,hexc,hexc_i,&
    1976              :     hsize,my_t1,my_t2,factor,term_type,ep_renorms,aa,bb,cc,ket0,ket0_hbar_norm,phi_nm1,phi_n,phi_np1,&
    1977           60 :     phit_nm1,phit_n,phit_np1,green_temp(:,iq),inn,is_converged,comm)
    1978              : 
    1979              :    ! Computing result from two ranges of frequencies
    1980              :    ! The real part is added, the imaginary part is substracted
    1981        60120 :    green(:,iq) = green_temp(BSp%nomega+1:n_all_omegas,iq)+CONJG(green_temp(BSp%nomega:1:-1,iq))
    1982              : 
    1983           60 :    ABI_FREE(all_omegas)
    1984           60 :    ABI_FREE(green_temp)
    1985              : 
    1986              :    ! Save the a"s and the b"s for possible restarting.
    1987              :    ! 1) Info on the Q.
    1988              :    ! 2) Number of iterations performed.
    1989              :    ! 3) do iter=1,niter_performed
    1990              :    !      aa(iter),bb(iter)
    1991              :    !    end do
    1992              :    ! 4) |n-1>
    1993              :    !    |n>
    1994              :    !    |n+1>
    1995              :    !
    1996           60 :    if (my_rank==master) then ! Open the file and writes basic dimensions and info.
    1997           60 :      write(out_unt)Bsp%q(:,iq)
    1998           60 :      write(out_unt)MIN(inn,niter_max)  ! NB: if the previous loop completed inn=niter_max+1
    1999         3276 :      do itt=1,MIN(inn,niter_max)        !     if we exited then inn is not incremented by one.
    2000         3276 :        write(out_unt)itt,aa(itt),bb(itt)
    2001              :      end do
    2002              :    end if
    2003              :    !
    2004              :    ! cbuff is used as workspace to gather |n-1>, |n> and |n+1>.
    2005          180 :    ABI_MALLOC(cbuff,(hsize))
    2006        11580 :    cbuff=czero; cbuff(my_t1:my_t2) = phi_nm1
    2007           60 :    call xmpi_sum_master(cbuff,master,comm,ierr)
    2008           60 :    if (my_rank==master) write(out_unt) cbuff ! |n-1>
    2009              : 
    2010        11580 :    cbuff=czero; cbuff(my_t1:my_t2) = phi_n
    2011           60 :    call xmpi_sum_master(cbuff,master,comm,ierr)
    2012           60 :    if (my_rank==master) write(out_unt) cbuff ! |n>
    2013              : 
    2014        11580 :    cbuff=czero; cbuff(my_t1:my_t2) = phi_np1
    2015           60 :    call xmpi_sum_master(cbuff,master,comm,ierr)
    2016           60 :    if (my_rank==master) write(out_unt) cbuff ! |n+1>
    2017              : 
    2018           60 :    ABI_FREE(phi_nm1)
    2019           60 :    ABI_FREE(phi_n)
    2020           60 :    ABI_FREE(phi_np1)
    2021           60 :    ABI_FREE(phit_nm1)
    2022           60 :    ABI_FREE(phit_n)
    2023           60 :    ABI_FREE(phit_np1)
    2024           60 :    ABI_FREE(hphi_n)
    2025           60 :    ABI_FREE(hphit_n)
    2026           60 :    ABI_FREE(cbuff)
    2027           60 :    ABI_FREE(aa)
    2028           60 :    ABI_FREE(bb)
    2029           60 :    ABI_FREE(cc)
    2030           70 :    ABI_FREE(ket0)
    2031              :  end do ! iq
    2032              : 
    2033           10 :  if (my_rank==master) close(out_unt)
    2034           10 :  call xmpi_barrier(comm)
    2035              : 
    2036           10 : end subroutine haydock_bilanczos
    2037              : !!***
    2038              : 
    2039              : !----------------------------------------------------------------------
    2040              : 
    2041              : !!****f* m_haydock/haydock_bilanczos_optalgo
    2042              : !! NAME
    2043              : !! haydock_bilanczos_optalgo
    2044              : !!
    2045              : !! FUNCTION
    2046              : !!  Haydock algorithm for general matrix
    2047              : !!
    2048              : !! INPUTS
    2049              : !!  niter_done=Number of iterations already performed (0 if the run starts from scratch).
    2050              : !!  niter_tot=Max number of iterations. Always > niter_done
    2051              : !!  nomega=Number of Frequency points for the evaluation of the matrix element.
    2052              : !!  omega(nomega)=Frequency set (imaginary part is already included).
    2053              : !!  tol_iter=Tollerance used to stop the the algorithm.
    2054              : !!  check(2)=Logical flags to specify where both the real and the imaginary part of the
    2055              : !!    matrix elements of the Green functions have to be checked for convergence.
    2056              : !!  hsize=Size of the blocks.
    2057              : !!  my_t1,my_t2=Indeces of the first and last column stored treated by this done.
    2058              : !!  term_type=0 if no terminator is used, 1 otherwise.
    2059              : !!  hreso(hsize,my_t1:my_t2)=The columns of the resonant block.
    2060              : !!  hcoup(hsize,my_t1:my_t2)=The columns of the coupling block.
    2061              : !!  factor
    2062              : !!  comm=MPI communicator.
    2063              : !!
    2064              : !! OUTPUT
    2065              : !!  green(nomega)=Output matrix elements.
    2066              : !!  inn=Last iteration performed.
    2067              : !!  is_converged=.TRUE. of the algorithm converged.
    2068              : !!
    2069              : !! SIDE EFFECTS
    2070              : !!  phi_nm1(my_t2-my_t1+1), phi_n(my_t2-my_t1+1)
    2071              : !!    input: vectors used to initialize the iteration
    2072              : !!    output: the vectors obtained in the last iteration
    2073              : !!  aa(niter_tot) and bb(niter_tot+1)
    2074              : !!    if niter_done>0: aa(1:niter_done), bb(1:niter_done) store the coefficients of the previous run.
    2075              : !!    when the routine returns aa(1:inn) and bb(1:inn) contain the matrix elements of the tridiagonal form.
    2076              : !!  cc(niter_tot+1)
    2077              : !!
    2078              : !! SOURCE
    2079              : 
    2080           60 : subroutine haydock_bilanczos_optalgo(niter_done,niter_tot,nomega,omega,tol_iter,check,hexc,hexc_i,hsize,my_t1,my_t2,&
    2081           60 : &  factor,term_type,ep_renorms,aa,bb,cc,ket0,ket0_hbar_norm,phi_nm1,phi_n,phi_np1,phit_nm1,phit_n,phit_np1,&
    2082           60 : &  green,inn,is_converged,comm)
    2083              : 
    2084              : !Arguments ------------------------------------
    2085              : !scalars
    2086              :  integer,intent(in) :: niter_tot,niter_done,nomega,comm,hsize,my_t1,my_t2,term_type
    2087              :  integer,intent(out) :: inn
    2088              :  logical,intent(out) :: is_converged
    2089              :  real(dp),intent(in) :: tol_iter,ket0_hbar_norm
    2090              :  complex(dp),intent(in) :: factor
    2091              :  type(hexc_t),intent(in) :: hexc
    2092              :  type(hexc_interp_t),intent(in) :: hexc_i
    2093              : !arrays
    2094              :  complex(dp),intent(inout) :: bb(niter_tot+1)
    2095              :  complex(dp),intent(out) :: green(nomega)
    2096              :  complex(dp),intent(in) :: omega(nomega)
    2097              :  complex(dp),intent(inout) :: aa(niter_tot),cc(niter_tot+1)
    2098              :  complex(dp),intent(in) :: ket0(my_t2-my_t1+1)
    2099              :  complex(dp),intent(in) :: ep_renorms(hsize)
    2100              :  complex(dp),intent(inout) :: phi_nm1(my_t2-my_t1+1)
    2101              :  complex(dp),intent(inout) :: phi_n  (my_t2-my_t1+1)
    2102              :  complex(dp),intent(inout) :: phi_np1(my_t2-my_t1+1)
    2103              :  complex(dp),intent(inout) :: phit_nm1(my_t2-my_t1+1)
    2104              :  complex(dp),intent(inout) :: phit_n  (my_t2-my_t1+1)
    2105              :  complex(dp),intent(inout) :: phit_np1(my_t2-my_t1+1)
    2106              :  logical,intent(in) :: check(2)
    2107              : 
    2108              : !Local variables ------------------------------
    2109              : !scalars
    2110              :  integer :: my_nt,niter_min,nconv !,ierr
    2111              :  character(len=500) :: msg
    2112              :  logical :: keep_vectors=.TRUE.
    2113              : !arrays
    2114              :  integer :: units(2)
    2115          120 :  real(dp) :: abs_err(nomega,2) !,ww_err(nomega,2)
    2116           60 :  complex(dp),allocatable :: oldg(:),newg(:)
    2117           60 :  complex(dp),allocatable :: hphi_np1(:),hphit_np1(:),save_phi(:,:),save_phit(:,:)
    2118           60 :  complex(dp),allocatable :: g00(:)
    2119              :  logical :: test(2)
    2120              :  integer :: ierr
    2121              : !************************************************************************
    2122              : 
    2123              :  ABI_UNUSED(ket0_hbar_norm)
    2124              :  ABI_UNUSED(ket0(1))
    2125              :  ABI_UNUSED(hexc_i%hsize_dense)
    2126          180 :  units = [std_out, ab_out]
    2127              : 
    2128           60 :  my_nt = my_t2-my_t1+1
    2129              : 
    2130          180 :  ABI_MALLOC(oldg,(nomega))
    2131          120 :  ABI_MALLOC(newg,(nomega))
    2132          120 :  ABI_MALLOC(g00,(nomega))
    2133       360420 :  oldg=czero; newg=czero; g00=czero
    2134           60 :  nconv=0
    2135              : 
    2136           60 :  keep_vectors = (keep_vectors.and.xmpi_comm_size(comm)==1)
    2137           60 :  if (keep_vectors) then
    2138          300 :    ABI_MALLOC(save_phi,(my_t2-my_t1+1,niter_tot))
    2139          180 :    ABI_MALLOC_OR_DIE(save_phit,(my_t2-my_t1+1,niter_tot),ierr)
    2140      5820060 :    save_phi=czero
    2141      5820060 :    save_phit=czero
    2142              :  end if
    2143              : 
    2144          180 :  ABI_MALLOC_OR_DIE(hphi_np1,(hexc%hsize),ierr)
    2145          180 :  ABI_MALLOC_OR_DIE(hphit_np1,(hexc%hsize),ierr)
    2146              : 
    2147         3156 :  do inn=niter_done+1,niter_tot
    2148              : 
    2149              :    !|n+1> = H |n> using all eh components.
    2150         3156 :    call hexc%matmul_elphon(phi_n, hphi_np1, 'N', ep_renorms)
    2151         3156 :    call hexc%matmul_elphon(phit_n, hphit_np1, 'C', ep_renorms)
    2152              : 
    2153              :    ! a(n) = < phit_n | H  | phi_n >
    2154         3156 :    aa(inn)=xdotc(my_nt,phit_n,1,hphi_np1(my_t1:),1)
    2155         3156 :    call xmpi_sum(aa(inn),comm,ierr)
    2156              : 
    2157              :    ! |n+1> = |n+1> - a(n)|Vn> - c(n)|n-1>
    2158       306132 :    phi_np1 = hphi_np1(my_t1:my_t2) - aa(inn)*phi_n - cc(inn-1)*phi_nm1
    2159       306132 :    phit_np1 = hphit_np1(my_t1:my_t2) - CONJG(aa(inn))*phit_n - CONJG(bb(inn-1))*phit_nm1
    2160              : 
    2161         3156 :    bb(inn) = xdotc(my_nt,phi_np1,1,phi_np1,1)
    2162         3156 :    call xmpi_sum(bb(inn),comm,ierr)
    2163         3156 :    bb(inn) = SQRT(bb(inn))
    2164              : 
    2165         3156 :    cc(inn) = xdotc(my_nt,phit_np1,1,phi_np1,1)
    2166         3156 :    call xmpi_sum(cc(inn),comm,ierr)
    2167         3156 :    cc(inn) = cc(inn)/bb(inn)
    2168              : 
    2169       306132 :    phi_np1 = phi_np1 / bb(inn)
    2170       306132 :    phit_np1 = phit_np1 / CONJG(cc(inn))
    2171              : 
    2172              :    ! |n-1> = |n>
    2173              :    ! |n>   = |n+1>
    2174       306132 :    phi_nm1 = phi_n
    2175       306132 :    phi_n   = phi_np1
    2176       306132 :    phit_nm1 = phit_n
    2177       306132 :    phit_n = phit_np1
    2178              : 
    2179         3156 :    if (keep_vectors) then
    2180       306132 :      save_phi(:,inn) = phi_n
    2181       306132 :      save_phit(:,inn) = phit_n
    2182              :    end if
    2183         3156 :    write(msg,'(a,i0,a,3es12.4)')' Iteration number ',inn,', b_i RE(c_i) IM(c_i) ',REAL(bb(inn)),REAL(cc(inn)),AIMAG(cc(inn))
    2184         3156 :    call wrtout(std_out,msg)
    2185              : 
    2186         3156 :    call continued_fract_general(inn,term_type,aa,bb,cc,nomega,omega,g00)
    2187      6324624 :    newg = factor*g00
    2188              :    !
    2189              :    ! Avoid spurious convergence.
    2190         3156 :    niter_min=4; if (niter_done>1) niter_min=niter_done+1
    2191         3156 :    if (inn>niter_min) then
    2192         8928 :      test=.TRUE.
    2193      5960928 :      abs_err(:,1) = ABS(DBLE (newg-oldg))
    2194      5960928 :      abs_err(:,2) = ABS(AIMAG(newg-oldg))
    2195              : 
    2196         2976 :      if (tol_iter>zero) then
    2197              :        ! Test on the L1 norm.
    2198            0 :        if (check(1)) test(1) = SUM(abs_err(:,1)) < tol_iter*SUM(ABS(DBLE (newg)))
    2199            0 :        if (check(2)) test(2) = SUM(abs_err(:,2)) < tol_iter*SUM(ABS(AIMAG(newg)))
    2200              :      else
    2201              :        ! Stringent test for each point.
    2202      4133190 :        if (check(1)) test(1) = ALL( abs_err(:,1) < -tol_iter*ABS(DBLE (newg)))
    2203      4102776 :        if (check(2)) test(2) = ALL( abs_err(:,2) < -tol_iter*ABS(AIMAG(newg)))
    2204              :      end if
    2205              :      !
    2206         3469 :      if (ALL(test)) then
    2207          186 :        nconv = nconv+1
    2208              :      else
    2209              :        nconv = 0
    2210              :      end if
    2211          186 :      if (nconv==2) then
    2212           60 :        if(inn<100)then
    2213              :          write(msg,'(a,es10.2,a)')&
    2214           60 :           " >>> Haydock algorithm converged twice within haydock_tol= ",tol_iter," after less than 100 iterations."
    2215              :        else
    2216              :          write(msg,'(a,es10.2,a,i0,a)')&
    2217            0 :           " >>> Haydock algorithm converged twice within haydock_tol= ",tol_iter," after ",inn," iterations."
    2218              :        endif
    2219           60 :        call wrtout(units, msg)
    2220           60 :        EXIT
    2221              :      end if
    2222              :    end if
    2223              :    !
    2224      6213852 :    oldg = newg
    2225              :  end do ! inn
    2226              : 
    2227       120180 :  green = newg
    2228           60 :  if (nconv/=2) then
    2229              :    write(msg,'(a,es10.2,a,i0,a)')&
    2230            0 :      " WARNING: Haydock algorithm did not converge within ",tol_iter," after ",niter_tot," iterations."
    2231            0 :    call wrtout(units, msg)
    2232              :  end if
    2233              : 
    2234           60 :  is_converged = (nconv==2)
    2235              : 
    2236           60 :  ABI_FREE(oldg)
    2237           60 :  ABI_FREE(newg)
    2238           60 :  ABI_FREE(g00)
    2239           60 :  ABI_FREE(hphi_np1)
    2240           60 :  ABI_FREE(hphit_np1)
    2241              : 
    2242           60 :  ABI_SFREE(save_phi)
    2243           60 :  ABI_SFREE(save_phit)
    2244              : 
    2245              :  !! if (keep_vectors) then
    2246              :  !!   tdim = MIN(inn,niter_tot)
    2247              :  !!   ABI_MALLOC(ovlp,(tdim,tdim))
    2248              : 
    2249              :  !!   ABI_MALLOC(phi_test,(hsize))
    2250              :  !!   ABI_MALLOC(phi_test2,(hsize))
    2251              : 
    2252              :  !!   max_err=smallest_real; mean_err=zero; mean_err2=zero; row_max=-1
    2253              :  !!   do ii=1,tdim
    2254              :  !!     parity = (-1)**(ii+1)
    2255              :  !!     phi_test  = save_phi(:,ii)
    2256              :  !!     call hexc%matmul_full(hexc_i, phi_test, phi_test2, parity)
    2257              :  !!     !phi_test2 = MATMUL(hreso,phi_test) + parity * MATMUL(hcoup,CONJG(phi_test))
    2258              :  !!     ovlp(ii,ii) = DOT_PRODUCT(phi_test,phi_test2) + DOT_PRODUCT(phi_test2,phi_test)
    2259              :  !!     err = ABS(ovlp(ii,ii)-cone)
    2260              :  !!     mean_err  = mean_err + err
    2261              :  !!     mean_err2 = mean_err2 + err**2
    2262              :  !!     if (err > max_err) then
    2263              :  !!       max_err = err
    2264              :  !!       row_max = ii
    2265              :  !!     end if
    2266              :  !!   end do
    2267              :  !!   mean_err = mean_err/tdim
    2268              :  !!   std_dev = mean_err2/tdim -mean_err**2
    2269              :  !!   write(std_out,'(a,i0,1x,3es14.6)')&
    2270              :  !!&    " Error in normalization (ii, max_err,mean,std_dev): ",row_max,max_err,mean_err,std_dev
    2271              : 
    2272              :  !!   ABI_FREE(phi_test)
    2273              :  !!   ABI_FREE(phi_test2)
    2274              :  !!
    2275              :  !!   ABI_MALLOC(alpha,(hsize,tdim))
    2276              : 
    2277              :  !!   ! Less efficient but for sake of simplicity with hexc_matmul
    2278              :  !!   ! TODO possibility to call hreso * phi, and hcoup * phi separately
    2279              :  !!   do ii=1,tdim
    2280              :  !!     parity = (-1)**(ii+1)
    2281              :  !!     call hexc%matmul_full(hexc_i, save_phi(:,ii), alpha(:,ii), parity)
    2282              :  !!   end do
    2283              : 
    2284              :  !!   !alpha = MATMUL(hreso,save_phi(:,1:tdim))
    2285              :  !!   !
    2286              :  !!   !do ii=1,tdim
    2287              :  !!   !  parity = (-1)**(ii+1)
    2288              :  !!   !  alpha(:,ii) =  alpha(:,ii) + parity*MATMUL(hcoup,CONJG(save_phi(:,ii)))
    2289              :  !!   !end do
    2290              : 
    2291              :  !!   ovlp = MATMUL(TRANSPOSE(CONJG(save_phi(:,1:tdim))),alpha)
    2292              : 
    2293              :  !!   ABI_MALLOC(beta,(hsize,tdim))
    2294              :  !!   do ii=1,tdim
    2295              :  !!     parity = (-1)**(ii+1)
    2296              :  !!     beta(:,ii)  =  parity*save_phi(:,ii)
    2297              :  !!     alpha(:,ii) = -parity*alpha(:,ii)
    2298              :  !!   end do
    2299              : 
    2300              :  !!   ovlp = ovlp - MATMUL(TRANSPOSE(CONJG(beta)),alpha)
    2301              : 
    2302              :  !!   max_err=smallest_real; row_max=-1; col_max=-1
    2303              :  !!   mean_err=zero; mean_err2=zero
    2304              :  !!   do jj=1,tdim
    2305              :  !!     do ii=1,jj
    2306              :  !!       err = ABS(ovlp(ii,jj))
    2307              :  !!       if (ii==jj) err = ABS(err - one)
    2308              :  !!       mean_err  = mean_err + err
    2309              :  !!       mean_err2 = mean_err2 + err**2
    2310              :  !!       if (err > max_err) then
    2311              :  !!         max_err = err
    2312              :  !!         row_max=ii
    2313              :  !!         col_max=jj
    2314              :  !!       end if
    2315              :  !!     end do
    2316              :  !!   end do
    2317              : 
    2318              :  !!   mean_err = mean_err/(tdim*(tdim+1)/2)
    2319              :  !!   std_dev = mean_err2/(tdim*(tdim+1)/2) - mean_err**2
    2320              :  !!   write(std_out,'(a,2(i0,1x),3es14.6)')&
    2321              :  !!      " Error in Hbar-ortho (i,j), max_err, mean, std_dev ",row_max,col_max,max_err,mean_err,std_dev
    2322              :  !!   !call print_arr(ovlp,max_r=185,max_c=10,unit=std_out)
    2323              : 
    2324              :  !!   ABI_FREE(alpha)
    2325              :  !!   ABI_FREE(beta)
    2326              :  !!   ABI_FREE(ovlp)
    2327              :  !!   ABI_FREE(save_phi)
    2328              :  !! end if
    2329              : 
    2330           60 : end subroutine haydock_bilanczos_optalgo
    2331              : !!***
    2332              : 
    2333              : 
    2334              : !----------------------------------------------------------------------
    2335              : 
    2336              : !!****f* m_numeric_tools/continued_fract_general
    2337              : !! NAME
    2338              : !!  continued_fract
    2339              : !!
    2340              : !! FUNCTION
    2341              : !!  This routine calculates the continued fraction:
    2342              : !!
    2343              : !!                        1
    2344              : !! f(z) =  _______________________________
    2345              : !!           z - a1 -        b1^2
    2346              : !!                   _____________________
    2347              : !!                     z - a2 -    b2^2
    2348              : !!                             ___________
    2349              : !!                                z -a3 -    ........
    2350              : !!
    2351              : !! INPUTS
    2352              : !!  nlev=Number of "levels" in the continued fraction.
    2353              : !!  term_type=Type of the terminator.
    2354              : !!    0 --> No terminator.
    2355              : !!   -1 --> Assume constant coefficients for a_i and b_i for i>nlev with a_inf = a(nlev) and b_inf = b(nleb)
    2356              : !!    1 --> Same as above but a_inf and b_inf are obtained by averaging over the nlev values.
    2357              : !!  aa(nlev)=Set of a_i coefficients.
    2358              : !!  bb(nlev)=Set of b_i coefficients.
    2359              : !!  nz=Number of points on the z-mesh.
    2360              : !!  zpts(nz)=z-mesh.
    2361              : !!
    2362              : !! OUTPUT
    2363              : !!  spectrum(nz)=Contains f(z) on the input mesh.
    2364              : !!
    2365              : !! SOURCE
    2366              : 
    2367         3156 : subroutine continued_fract_general(nlev,term_type,aa,bb,cc,nz,zpts,spectrum)
    2368              : 
    2369              : !Arguments ------------------------------------
    2370              : !scalars
    2371              :  integer,intent(in) :: nlev,term_type,nz
    2372              : !arrays
    2373              :  complex(dp),intent(in) :: bb(nlev)
    2374              :  complex(dp),intent(in) :: cc(nlev)
    2375              :  complex(dp),intent(in) :: aa(nlev)
    2376              :  complex(dp),intent(in) :: zpts(nz)
    2377              :  complex(dp),intent(out) :: spectrum(nz)
    2378              : 
    2379              : !Local variables ------------------------------
    2380              : !scalars
    2381              :  integer :: it
    2382              :  complex(dp) :: bb_inf,bg,bu,swap, aa_inf
    2383              :  character(len=500) :: msg
    2384              : !arrays
    2385         3156 :  complex(dp),allocatable :: div(:),den(:)
    2386              : !************************************************************************
    2387              : 
    2388         9468 :  ABI_MALLOC(div,(nz))
    2389         6312 :  ABI_MALLOC(den,(nz))
    2390              : 
    2391         3156 :  select case (term_type)
    2392              :  case (0) ! No terminator.
    2393      6321468 :    div=czero
    2394              :  case (-1,1)
    2395            0 :    ABI_ERROR("Not yet implemented")
    2396            0 :    if (term_type==-1) then
    2397            0 :      bb_inf=bb(nlev)
    2398            0 :      aa_inf=aa(nlev)
    2399              :    else
    2400            0 :      bb_inf=SUM(bb)/nlev
    2401            0 :      aa_inf=SUM(aa)/nlev
    2402              :    end if
    2403              :    ! Be careful with the sign of the SQRT.
    2404            0 :    div(:) = half*(bb(nlev)/(bb_inf))**2 * ( zpts-aa_inf - SQRT((zpts-aa_inf)**2 - four*bb_inf**2) )
    2405              :  case (2)
    2406            0 :    ABI_ERROR("Not yet implemented")
    2407            0 :    div = zero
    2408            0 :    if (nlev>4) then
    2409            0 :      bg=zero; bu=zero
    2410            0 :      do it=1,nlev,2
    2411            0 :        if (it+2<nlev) bg = bg + bb(it+2)
    2412            0 :        bu = bu + bb(it)
    2413              :      end do
    2414            0 :      bg = bg/(nlev/2+MOD(nlev,2))
    2415            0 :      bu = bg/((nlev+1)/2)
    2416              :      !if (iseven(nlev)) then
    2417            0 :      if (.not.iseven(nlev)) then
    2418            0 :        swap = bg
    2419            0 :        bg = bu
    2420            0 :        bu = bg
    2421              :      end if
    2422              :      !write(std_out,*)nlev,bg,bu
    2423              :      !Here be careful with the sign of SQRT
    2424            0 :      do it=1,nz
    2425              :        div(it) = half/zpts(it) * (bb(nlev)/bu)**2 * &
    2426            0 :          ( (zpts(it)**2 +bu**2 -bg**2) - SQRT( (zpts(it)**2+bu**2-bg**2)**2 -four*(zpts(it)*bu)**2) )
    2427              :      end do
    2428              :    end if
    2429              : 
    2430              :  case default
    2431            0 :    write(msg,'(a,i0)')" Wrong value for term_type: ",term_type
    2432         3156 :    ABI_ERROR(msg)
    2433              :  end select
    2434              : 
    2435        89458 :  do it=nlev,2,-1
    2436    172862906 :    den(:) = zpts(:) - aa(it) - div(:)
    2437    172866062 :    div(:) = (bb(it-1)*cc(it-1) )/ den(:)
    2438              :  end do
    2439              : 
    2440      6324624 :  den = zpts(:) - aa(1) - div(:)
    2441      6324624 :  div = one/den(:)
    2442              : 
    2443      6321468 :  spectrum = div
    2444         3156 :  ABI_FREE(div)
    2445         3156 :  ABI_FREE(den)
    2446              : 
    2447         3156 : end subroutine continued_fract_general
    2448              : !!***
    2449              : 
    2450              : !----------------------------------------------------------------------
    2451              : 
    2452            0 : end module m_haydock
    2453              : !!***
        

Generated by: LCOV version 2.3-1