LCOV - code coverage report
Current view: top level - src/70_gw - m_screening.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 68.2 % 1027 700
Test Date: 2026-09-21 19:39:32 Functions: 50.0 % 28 14

            Line data    Source code
       1              : !!****m* ABINIT/m_screening
       2              : !! NAME
       3              : !!  m_screening
       4              : !!
       5              : !! FUNCTION
       6              : !!  This module contains the definition of the object used to deal
       7              : !!  with the inverse dielectric matrix as well as related methods.
       8              : !!
       9              : !! COPYRIGHT
      10              : !! Copyright (C) 2008-2026 ABINIT group (MG)
      11              : !! This file is distributed under the terms of the
      12              : !! GNU General Public License, see ~abinit/COPYING
      13              : !! or http://www.gnu.org/copyleft/gpl.txt .
      14              : !!
      15              : !! SOURCE
      16              : 
      17              : #if defined HAVE_CONFIG_H
      18              : #include "config.h"
      19              : #endif
      20              : 
      21              : #include "abi_common.h"
      22              : 
      23              : module m_screening
      24              : 
      25              :  use, intrinsic :: iso_c_binding
      26              :  use defs_basis
      27              :  use m_abicore
      28              :  use m_hide_blas
      29              :  use m_linalg_interfaces
      30              :  use m_xmpi
      31              :  use m_errors
      32              :  use m_copy
      33              :  use m_splines
      34              :  use m_lebedev
      35              :  use m_spectra
      36              :  use m_nctk
      37              :  use m_distribfft
      38              :  use netcdf
      39              : 
      40              :  use defs_abitypes,     only : MPI_type
      41              :  use m_gwdefs,          only : GW_TOLQ0, czero_gw, GW_Q0_DEFAULT
      42              :  use m_fstrings,        only : toupper, endswith, sjoin, itoa, strcat
      43              :  use m_io_tools,        only : open_file
      44              :  use m_time,            only : cwtime, cwtime_report
      45              :  use m_numeric_tools,   only : print_arr, hermitianize
      46              :  use m_special_funcs,   only : k_fermi, k_thfermi
      47              :  use m_geometry,        only : normv, vdotw, metric
      48              :  use m_hide_lapack,     only : xginv
      49              :  use m_crystal,         only : crystal_t
      50              :  use m_bz_mesh,         only : kmesh_t, box_len
      51              :  use m_fft_mesh,        only : g2ifft
      52              :  use m_fftcore,         only : kgindex
      53              :  use m_fft,             only : fourdp
      54              :  use m_gsphere,         only : gsphere_t
      55              :  use m_vcoul,           only : vcoul_t
      56              :  use m_io_screening,    only : read_screening, write_screening, &
      57              :                                HSCR_LATEST_HEADFORM, hscr_t, ncname_from_id, em1_ncname
      58              :  use m_paw_sphharm,     only : ylmc
      59              :  use m_mpinfo,          only : destroy_mpi_enreg, initmpi_seq
      60              :  use m_pstat,           only : pstat_proc
      61              : 
      62              :  implicit none
      63              : 
      64              :  private
      65              : !!***
      66              : 
      67              : !----------------------------------------------------------------------
      68              : 
      69              : !!****t* m_screening/epsm1_t
      70              : !! NAME
      71              : !! epsm1_t
      72              : !!
      73              : !! FUNCTION
      74              : !! For the GW part of ABINIT, the epsm1_t structured datatype
      75              : !! gather the results of screening: the inverse dielectric matrix, and the omega matrices.
      76              : !!
      77              : !! SOURCE
      78              : 
      79              :  type,public :: epsm1_t
      80              : 
      81              :   integer :: id
      82              :   ! Matrix identifier: O if not yet defined, 1 for chi0,
      83              :   ! 2 for chi, 3 for epsilon, 4 for espilon^{-1}, 5 for W.
      84              : 
      85              :   integer :: ikxc
      86              :   ! Kxc kernel used, 0 for None (RPA), >0 for static TDDFT (=ixc), <0 for TDDFT
      87              : 
      88              :   integer :: fform
      89              :   ! File format: 1002 for SCR|SUSC files.
      90              : 
      91              :   integer :: mqmem
      92              :   ! =0 for out-of-core solution, =nqibz if entire matrix is stored in memory.
      93              : 
      94              :   integer :: nI,nJ
      95              :   ! Number of components (rows,columns) in chi|eps^-1. (1,1) if collinear.
      96              : 
      97              :   integer :: nqibz
      98              :   ! Number of q-points in the IBZ used.
      99              : 
     100              :   integer :: nqlwl
     101              :   ! Number of point used for the treatment of the long wave-length limit.
     102              : 
     103              :   integer :: nomega
     104              :   ! Total number of frequencies.
     105              : 
     106              :   integer :: nomega_i
     107              :   ! Number of purely imaginary frequencies used.
     108              : 
     109              :   integer :: nomega_i_conv
     110              :   ! Number of purely imaginary frequencies used for convolution.
     111              : 
     112              :   integer :: nomega_r
     113              :   ! Number of real frequencies used.
     114              : 
     115              :   integer :: npwe
     116              :   ! Number of G vectors.
     117              : 
     118              :   integer :: test_type
     119              :   ! 0 for None, 1 for TEST-PARTICLE, 2 for TEST-ELECTRON (only for TDDFT)
     120              : 
     121              :   integer :: tordering
     122              :   ! 0 if not defined, 1 for Time-Ordered, 2 for Advanced, 3 for Retarded.
     123              : 
     124              :   character(len=fnlen) :: fname
     125              :   ! Name of the file from which epsm1 is read.
     126              : 
     127              :   integer,allocatable :: gvec(:,:)
     128              :   ! gvec(3,npwe)
     129              :   ! G-vectors used to describe the two-point function (r.l.u.).
     130              : 
     131              :   real(dp),allocatable :: qibz(:,:)
     132              :   ! qibz(3,nqibz)
     133              :   ! q-points in reduced coordinates
     134              : 
     135              :   real(dp),allocatable :: qlwl(:,:)
     136              :   ! qlwl(3,nqlwl)
     137              :   ! q-points used for the long wave-length limit treatment.
     138              : 
     139              :   logical :: use_mpi_shared_win = .False.
     140              :   ! This flag allows us to understand if espm1 is associates to a MPI window or not.
     141              :   ! In the former case, we should free the window and not the pointer
     142              : 
     143              :   integer :: epsm1_win = xmpi_undefined
     144              : 
     145              :   type(xcomm_t) :: shared_comm
     146              : 
     147              :   complex(gwp), contiguous, pointer :: epsm1(:,:,:,:) => null()
     148              :   ! epsm1(npwe,npwe,nomega,nqibz)
     149              :   ! Contains the two-point function $\epsilon_{G,Gp}(q,omega)$ in frequency and reciprocal space.
     150              :   ! We use a pointer so that we can associated it to MPI shared memory window.
     151              : 
     152              :   complex(gwp), contiguous, pointer :: epsm1_qbz(:,:,:) => null()
     153              :   integer :: epsm1_qbz_win = xmpi_undefined
     154              : 
     155              :   complex(dp),allocatable :: omega(:)
     156              :   ! omega(nomega)
     157              :   ! Frequencies used both along the real and the imaginary axis.
     158              : 
     159              :   type(hscr_t) :: Hscr
     160              :   ! The header reported in the _SCR of _SUSC file.
     161              :   ! This object contains information on the susceptibility or the inverse dielectric matrix
     162              :   ! as stored in the external file. These quantities do *NOT* correspond to the quantities
     163              :   ! used during the GW calculation since some parameters might differ, actually they might be smaller.
     164              :   ! For example, the number of G-vectors used can be smaller than the number of G"s stored on file.
     165              : 
     166              :  contains
     167              : 
     168              :    procedure :: free => epsm1_free
     169              :     ! Free memory
     170              : 
     171              :    procedure :: print => epsm1_print
     172              :      ! Print basic info
     173              : 
     174              :    procedure :: rotate_iqbz => epsm1_rotate_iqbz
     175              :      ! Symmetrize two-point function at a q-point in the BZ.
     176              : 
     177              :    procedure :: rotate_iqbz_inplace => epsm1_rotate_iqbz_inplace
     178              :      ! In-place version of the above
     179              : 
     180              :    procedure :: from_file => epsm1_from_file
     181              :      ! Initialize the object from file
     182              : 
     183              :    procedure :: mkdump => epsm1_mkdump
     184              :      ! Dump the object to a file.
     185              : 
     186              :    procedure :: get_epsm1 => get_epsm1
     187              : 
     188              :    procedure :: decompose_epsm1 => decompose_epsm1
     189              :     ! Decompose the complex symmetrized dielectric
     190              : 
     191              :    procedure :: malloc_epsm1_qbz => epsm1_malloc_epsm1_qbz
     192              : 
     193              :    procedure :: free_epsm1_qbz => epsm1_free_epsm1_qbz
     194              : 
     195              :  end type epsm1_t
     196              : 
     197              :  public :: make_epsm1_driver              ! Calculate the inverse symmetrical dielectric matrix starting from chi0
     198              :  public :: mkem1_q0                       ! Construct the microscopic dielectric matrix for q-->0
     199              : 
     200              :  ! Routines for the model dielectric function
     201              : 
     202              :  public :: screen_mdielf                  ! Calculates W_{G,G'}(q,w) for a given q-point in the BZ using a model dielectric function.
     203              :  public :: rpa_symepsm1
     204              : !!***
     205              : 
     206              : !!****t* m_screening/chi_t
     207              : !! NAME
     208              : !!  chi_t
     209              : !!
     210              : !! FUNCTION
     211              : !!  This object contains the head and the wings of the polarizability
     212              : !!  These quantities are used to treat the q-->0 limit
     213              : !!
     214              : !! SOURCE
     215              : 
     216              :  type,public :: chi_t
     217              : 
     218              :    integer :: npwe
     219              :    ! Number of G vectors.
     220              : 
     221              :    integer :: nomega
     222              :    ! Number of frequencies
     223              : 
     224              :    complex(gwp),allocatable :: mat(:,:,:)
     225              :    ! mat(npwe, npwe, nomega)
     226              : 
     227              :    complex(dp),allocatable :: head(:,:,:)
     228              :    ! head(3,3,nomega)
     229              : 
     230              :    complex(dp),allocatable :: lwing(:,:,:)
     231              :    ! lwing(3,npwe,nomega)
     232              :    ! Lower wings
     233              : 
     234              :    complex(dp),allocatable :: uwing(:,:,:)
     235              :    ! uwing(3,npwe,nomega)
     236              :    ! Upper wings.
     237              : 
     238              :  end type chi_t
     239              : 
     240              :  public :: chi_new    ! Create new object (allocate memory)
     241              :  public :: chi_free   ! Free memory.
     242              : !!***
     243              : 
     244              : !!****t* m_screening/lwl_t
     245              : !! NAME
     246              : !!  lwl_t
     247              : !!
     248              : !! FUNCTION
     249              : !!
     250              : !! SOURCE
     251              : 
     252              :  type,public :: lwl_t
     253              : 
     254              :   integer :: npwe
     255              :   ! Number of G vectors.
     256              : 
     257              :   integer :: nomega
     258              :   ! Number of frequencies
     259              : 
     260              :   integer :: method
     261              :   ! 1 = Only head
     262              :   ! 2 = head + wings
     263              :   ! 3 = head + wings + body corrections.
     264              : 
     265              :   character(len=fnlen) :: fname
     266              :    ! Name of the file from which epsm1 is read.
     267              : 
     268              :    complex(dp),allocatable :: head(:,:,:)
     269              :    ! head(3,3,nomega)
     270              : 
     271              :    complex(dp),allocatable :: lwing(:,:,:)
     272              :    ! lwing(3,npwe,nomega)
     273              :    ! Lower wings
     274              : 
     275              :    complex(dp),allocatable :: uwing(:,:,:)
     276              :    ! uwing(3,npwe,nomega)
     277              :    ! Upper wings.
     278              : 
     279              :    complex(dp),allocatable :: body(:,:,:)
     280              :    ! uwing(npwe,npwe,nomega)
     281              :    ! Body terms
     282              : 
     283              :  end type lwl_t
     284              : 
     285              :  public :: lwl_write
     286              :  public :: lwl_init
     287              :  !public :: lwl_from_file
     288              :  public :: lwl_free
     289              : !!***
     290              : 
     291              : #define _MOK(integer) int(integer, kind=XMPI_OFFSET_KIND)
     292              : 
     293              : CONTAINS  !========================================================================================
     294              : !!***
     295              : 
     296              : !----------------------------------------------------------------------
     297              : 
     298              : !!****f* m_screening/epsm1_free
     299              : !! NAME
     300              : !! epsm1_free
     301              : !!
     302              : !! FUNCTION
     303              : !! Deallocate all the pointers in epsm1 that result to be associated.
     304              : !! Perform also a cleaning of the Header.
     305              : !!
     306              : !! SOURCE
     307              : 
     308          202 : subroutine epsm1_free(epsm1)
     309              : 
     310              : !Arguments ------------------------------------
     311              :  class(epsm1_t),intent(inout) :: epsm1
     312              : 
     313              :  integer :: ierr
     314              : ! *************************************************************************
     315              : 
     316              :  !integer
     317          202 :  ABI_SFREE(epsm1%gvec)
     318              : 
     319              :  !real
     320          202 :  ABI_SFREE(epsm1%qibz)
     321          202 :  ABI_SFREE(epsm1%qlwl)
     322              : 
     323              :  !complex
     324          202 :  if (epsm1%use_mpi_shared_win) then
     325           30 :    call xmpi_win_free(epsm1%epsm1_win, ierr)
     326           30 :    nullify(epsm1%epsm1)
     327           30 :    if (epsm1%epsm1_qbz_win /= xmpi_undefined) then
     328            0 :      call xmpi_win_free(epsm1%epsm1_qbz_win, ierr)
     329            0 :      nullify(epsm1%epsm1_qbz)
     330              :    end if
     331              :  else
     332          172 :    ABI_SFREE_PTR(epsm1%epsm1)
     333          172 :    ABI_SFREE_PTR(epsm1%epsm1_qbz)
     334              :  end if
     335          202 :  call epsm1%shared_comm%free()
     336              : 
     337          202 :  ABI_SFREE(epsm1%omega)
     338              : 
     339              :  !datatypes
     340          202 :  call epsm1%Hscr%free()
     341              : 
     342          202 : end subroutine epsm1_free
     343              : !!***
     344              : 
     345              : !----------------------------------------------------------------------
     346              : 
     347              : !!****f* m_screening/epsm1_print
     348              : !! NAME
     349              : !!  epsm1_print
     350              : !!
     351              : !! FUNCTION
     352              : !! Print the basic dimensions and the most important
     353              : !! quantities reported in the epsm1_t data type.
     354              : !!
     355              : !! INPUTS
     356              : !!  epsm1<epsm1_t>=The data type.
     357              : !!  unit[optional]=the unit number for output.
     358              : !!  prtvol[optional]=verbosity level.
     359              : !!
     360              : !! OUTPUT
     361              : !!  Only printing.
     362              : !!
     363              : !! SOURCE
     364              : 
     365            5 : subroutine epsm1_print(epsm1, units, prtvol)
     366              : 
     367              : !Arguments ------------------------------------
     368              :  class(epsm1_t),intent(in) :: epsm1
     369              :  integer,intent(in) :: units(:)
     370              :  integer,intent(in) :: prtvol
     371              : 
     372              : !Local variables-------------------------------
     373              :  integer :: iw,iq_ibz,iqlwl
     374              :  character(len=50) :: rfname,rforder,rfapprox,rftest,kxcname
     375              :  character(len=500) :: msg
     376              : ! *************************************************************************
     377              : 
     378              :  ! chi0 or \epsilon^{-1} ?
     379            5 :  SELECT CASE (epsm1%ID)
     380              :  CASE (0)
     381            0 :    rfname = 'Undefined'
     382              :  CASE (1)
     383            0 :    rfname = 'Irreducible Polarizability'
     384              :  CASE (2)
     385            0 :    rfname = 'Polarizability'
     386              :  CASE (3)
     387            0 :    rfname = 'Symmetrical Dielectric Matrix'
     388              :  CASE (4)
     389            5 :    rfname = 'Symmetrical Inverse Dielectric Matrix'
     390              :  CASE DEFAULT
     391            5 :    ABI_BUG(sjoin('Wrong epsm1%ID:',itoa(epsm1%ID)))
     392              :  END SELECT
     393              : 
     394              :  ! For chi, \espilon or \epsilon^{-1}, define the approximation.
     395              :  rfapprox='None'
     396              :  if (epsm1%ID>=2.or.epsm1%ID<=4) then
     397            5 :    if (epsm1%ikxc==0) then
     398            5 :      rfapprox='RPA'
     399            0 :    else if (epsm1%ikxc>0) then
     400            0 :      rfapprox='Static TDDFT'
     401              :    else
     402            0 :      rfapprox='TDDFT'
     403              :    end if
     404              :  end if
     405              : 
     406              :  ! === If TDDFT and \epsilon^{-1}, define the type ===
     407            5 :  rftest='None'
     408              : ! if (epsm1%ID==0) then
     409              : !  if (epsm1%test_type==0) then
     410              : !   rftest='TEST-PARTICLE'
     411              : !  else if (epsm1%test_type==1) then
     412              : !   rftest='TEST-ELECTRON'
     413              : !  else
     414              : !   write(msg,'(4a,i3)')ch10,&
     415              : !&   ' epsm1_print : BUG - ',ch10,&
     416              : !&   ' Wrong value of epsm1%test_type = ',epsm1%test_type
     417              : !   ABI_ERROR(msg)
     418              : !  end if
     419              : ! end if
     420              : 
     421              :  ! === Define time-ordering ===
     422            5 :  rforder='Undefined'
     423            5 :  if (epsm1%Tordering==1) then
     424            5 :    rforder='Time-Ordered'
     425            0 :  else if (epsm1%Tordering==2) then
     426            0 :    rforder='Advanced'
     427            0 :  else if (epsm1%Tordering==3) then
     428            0 :    rforder='Retarded'
     429              :  else
     430            0 :    ABI_BUG(sjoin('Wrong epsm1%tordering= ',itoa(epsm1%Tordering)))
     431              :  end if
     432              : 
     433            5 :  kxcname='None'
     434            5 :  if (epsm1%ikxc/=0) then
     435              :    !TODO Add function to retrieve kxc name
     436            0 :    ABI_ERROR('Add function to retrieve kxc name')
     437            0 :    kxcname='XXXXX'
     438              :  end if
     439              : 
     440            5 :  write(msg,'(6a,5(3a))')ch10,&
     441            5 :    ' ==== Info on the Response Function ==== ',ch10,&
     442            5 :    '  Associated File ................  ',TRIM(epsm1%fname),ch10,&
     443            5 :    '  Response Function Type .......... ',TRIM(rfname),ch10,&
     444            5 :    '  Type of Approximation ........... ',TRIM(rfapprox),ch10,&
     445            5 :    '  XC kernel used .................. ',TRIM(kxcname),ch10,&
     446            5 :    '  Type of probing particle ........ ',TRIM(rftest),ch10,&
     447           10 :    '  Time-Ordering ................... ',TRIM(rforder),ch10
     448            5 :  call wrtout(units, msg)
     449              :  write(msg,'(a,2i4,a,3(a,i4,a),a,3i4,2a,i4,a)')&
     450            5 :    '  Number of components ............ ',epsm1%nI,epsm1%nJ,ch10,&
     451            5 :    '  Number of q-points in the IBZ ... ',epsm1%nqibz,ch10,&
     452            5 :    '  Number of q-points for q-->0 .... ',epsm1%nqlwl,ch10,&
     453            5 :    '  Number of G-vectors ............. ',epsm1%npwe,ch10,&
     454            5 :    '  Number of frequencies ........... ',epsm1%nomega,epsm1%nomega_r,epsm1%nomega_i,ch10,&
     455           10 :    '  Value of mqmem .................. ',epsm1%mqmem,ch10
     456            5 :  call wrtout(units,msg)
     457              : 
     458            5 :  if (epsm1%nqlwl/=0) then
     459            5 :    write(msg,'(a,i3)')' q-points for long wavelength limit: ',epsm1%nqlwl
     460            5 :    call wrtout(units, msg)
     461           10 :    do iqlwl=1,epsm1%nqlwl
     462            5 :      write(msg,'(1x,i5,a,3es16.8)')iqlwl,') ',epsm1%qlwl(:,iqlwl)
     463           10 :      call wrtout(units, msg)
     464              :    end do
     465              :  end if
     466              : 
     467            5 :  if (prtvol > 0) then
     468              :    ! Print out head and wings in the long-wavelength limit.
     469              :    ! TODO add additional stuff.
     470            0 :    write(msg,'(a,i4)')' Calculated Frequencies: ',epsm1%nomega
     471            0 :    call wrtout(units, msg)
     472            0 :    do iw=1,epsm1%nomega
     473            0 :      write(msg,'(i4,es14.6)')iw,epsm1%omega(iw)*Ha_eV
     474            0 :      call wrtout(units, msg)
     475              :    end do
     476              : 
     477            0 :    write(msg,'(a,i4)')' Calculated q-points: ',epsm1%nqibz
     478            0 :    call wrtout(units, msg)
     479            0 :    do iq_ibz=1,epsm1%nqibz
     480            0 :      write(msg,'(1x,i4,a,3es16.8)')iq_ibz,') ',epsm1%qibz(:,iq_ibz)
     481            0 :      call wrtout(units, msg)
     482              :    end do
     483              :  end if ! prtvol > 0
     484              : 
     485            5 : end subroutine epsm1_print
     486              : !!***
     487              : 
     488              : !----------------------------------------------------------------------
     489              : 
     490              : !!****f* m_screening/Epsm1_rotate_iqbz
     491              : !! NAME
     492              : !!  Epsm1_rotate_iqbz
     493              : !!
     494              : !! FUNCTION
     495              : !!  Symmetrize the inverse dielectric matrix, namely calculate epsilon^{-1} at a generic
     496              : !!  q-point in the BZ starting from the knowledge of the matrix at a q-point in the IBZ.
     497              : !!  The procedure is quite generic and can be used for every two-point function which has
     498              : !!  the same symmetry as the crystal.
     499              : !!
     500              : !! INPUTS
     501              : !!  iq_bz=Index of the q-point in the BZ where epsilon^-1 is required.
     502              : !!  nomega=Number of frequencies required. All frequencies from 1 up to nomega are symmetrized.
     503              : !!  npwc=Number of G vectors in symmetrized matrix, has to be smaller than epsm1%npwe.
     504              : !!  Gsph<gsphere_t>=data related to the G-sphere
     505              : !!  Qmesh<kmesh_t>=Structure defining the q-mesh used for epsm1.
     506              : !!  remove_exchange=If .TRUE., return e^{-1}-1 namely remove the exchange part.
     507              : 
     508              : !! OUTPUT
     509              : !!  epsm1_qbz(npwc,npwc,nomega)=The inverse dielectric matrix at the q-point defined by iq_bz.
     510              : !!   Exchange part can be subtracted out.
     511              : !!
     512              : !! NOTES
     513              : !!  In the present implementation we are not considering a possible umklapp vector G0 in the
     514              : !!  expression Sq = q+G0. Treating this case would require some changes in the G-sphere
     515              : !!  since we have to consider G-G0. The code however stops in sigma if a nonzero G0 is required
     516              : !!  to reconstruct the BZ.
     517              : !!
     518              : !!  * Remember the symmetry properties of \tilde\espilon^{-1}
     519              : !!
     520              : !!    If q_bz = S q_ibz + G0:
     521              : !!
     522              : !!      $\epsilon^{-1}_{SG1-G0, SG2-G0}(q_bz) = e^{+iS(G2-G1).\tau} \epsilon^{-1}_{G1, G2)}(q)
     523              : !!
     524              : !!    If time-reversal symmetry can be used then:
     525              : !!
     526              : !!      $\epsilon^{-1}_{G1,G2}(-q_bz) = e^{+i(G1-G2).\tau} \epsilon^{-1}_{-S^{-1}(G1+Go), -S^{-1}(G2+G0)}^*(q)
     527              : !!
     528              : !! TODO
     529              : !!  Symmetrization can be skipped if iq_bz correspond to a point in the IBZ
     530              : !!
     531              : !! SOURCE
     532              : 
     533         5981 : subroutine Epsm1_rotate_iqbz(epsm1, iq_bz, nomega, npwc, Gsph, Qmesh, remove_exchange)
     534              : 
     535              : !Arguments ------------------------------------
     536              : !scalars
     537              :  class(epsm1_t),intent(in) :: epsm1
     538              :  integer,intent(in) :: iq_bz, nomega, npwc
     539              :  logical,intent(in) :: remove_exchange
     540              :  type(gsphere_t),target,intent(in) :: Gsph
     541              :  type(kmesh_t),intent(in) :: Qmesh
     542              : 
     543              : !Local variables-------------------------------
     544              : !scalars
     545              :  integer :: iw,ii,jj,iq_ibz,itim_q,isym_q,iq_loc,sg1,sg2, ierr, g0(3)
     546              :  complex(gwp) :: phmsg1t,phmsg2t_star
     547              : !arrays
     548              :  real(dp) :: qbz(3)
     549              : ! *********************************************************************
     550              : 
     551         5981 :  ABI_CHECK(epsm1%nomega >= nomega, 'Too many frequencies required')
     552         5981 :  ABI_CHECK(epsm1%npwe >= npwc, 'Too many G-vectors required')
     553              : 
     554              :  ! Get iq_ibz, and symmetries from iq_ibz.
     555         5981 :  call Qmesh%get_BZ_item(iq_bz, qbz, iq_ibz, isym_q, itim_q, umklp=g0)
     556        23924 :  ABI_CHECK(all(g0 == 0), "non-zero g0 is not coded")
     557              : 
     558              :  ! If out-of-memory, only epsm1%espm1(:,:,:,1) has been allocated and filled.
     559         5981 :  iq_loc = iq_ibz; if (epsm1%mqmem == 0) iq_loc=1
     560              : 
     561         5981 :  if (epsm1%use_mpi_shared_win) call xmpi_win_fence(XMPI_MODE_NOPRECEDE, epsm1%epsm1_qbz_win, ierr) ! Start the RMA epoch.
     562              : 
     563              :  ! MG: rottb is a 1-1 mapping, hence we can collapse the loops (false sharing is not an issue here).
     564              : !!$OMP PARALLEL DO COLLAPSE(2) PRIVATE(sg2,sg1,phmsg1t,phmsg2t_star) IF (NOT epsm1%use_mpi_shared_win)
     565       118367 :  do iw=1,nomega
     566       112386 :    if (epsm1%shared_comm%skip(iw)) cycle ! MPI parallelism with shared memory.
     567      2831841 :    do jj=1,npwc
     568      2738050 :      sg2 = Gsph%rottb(jj, itim_q, isym_q)
     569      2738050 :      phmsg2t_star = CONJG(Gsph%phmSGt(jj, isym_q))
     570    119899638 :      do ii=1,npwc
     571    117073778 :        sg1 = Gsph%rottb(ii,itim_q,isym_q)
     572    117073778 :        phmsg1t = Gsph%phmSGt(ii,isym_q)
     573    119811828 :        epsm1%epsm1_qbz(sg1,sg2,iw) = epsm1%epsm1(ii,jj,iw,iq_loc) * phmsg1t * phmsg2t_star
     574              :      end do
     575              :    end do
     576              :  end do
     577              : 
     578              :  ! Account for time-reversal
     579         5981 :  if (itim_q==2) then
     580              : !!$OMP PARALLEL DO IF (nomega > 1)
     581            0 :    do iw=1,nomega
     582            0 :      if (epsm1%shared_comm%skip(iw)) cycle ! MPI parallelism with shared memory.
     583            0 :      call sqmat_itranspose(npwc, epsm1%epsm1_qbz(:,:,iw))
     584              :    end do
     585              :  end if
     586              : 
     587         5981 :  if (remove_exchange) then
     588              :    ! Subtract the exchange contribution
     589              :    ! If it's a pole screening, the exchange contribution is already removed
     590              : !!$OMP PARALLEL DO IF (nomega > 1)
     591       118367 :    do iw=1,nomega
     592       112386 :      if (epsm1%shared_comm%skip(iw)) cycle ! MPI parallelism with shared memory.
     593      2831841 :      do ii=1,npwc
     594      2825860 :        epsm1%epsm1_qbz(ii,ii,iw) = epsm1%epsm1_qbz(ii,ii,iw) - cmplx(1.0_gwp,0.0_gwp)
     595              :      end do
     596              :    end do
     597              :  endif
     598              : 
     599         5981 :  if (epsm1%use_mpi_shared_win) call xmpi_win_fence(XMPI_MODE_NOSUCCEED, epsm1%epsm1_qbz_win, ierr) ! Close the RMA epoch.
     600              : 
     601         5981 : end subroutine Epsm1_rotate_iqbz
     602              : !!***
     603              : 
     604              : !----------------------------------------------------------------------
     605              : 
     606              : !!****f* m_screening/Epsm1_rotate_iqbz_inplace
     607              : !! NAME
     608              : !!  Epsm1_rotate_iqbz_inplace
     609              : !!
     610              : !! FUNCTION
     611              : !!  Same function as Epsm1_rotate_iqbz, but now the array Ep%epsm1 is modified inplace
     612              : !!  via an auxiliary work array of shape (npwc,npwc)
     613              : !!
     614              : !! INPUTS
     615              : !!  iq_bz=Index of the q-point in the BZ where epsilon^-1 is required.
     616              : !!  nomega=Number of frequencies required. All frequencies from 1 up to nomega are symmetrized.
     617              : !!  npwc=Number of G vectors in symmetrized matrix, has to be smaller than epsm1%npwe.
     618              : !!  Gsph<gsphere_t>=data related to the G-sphere
     619              : !!  Qmesh<kmesh_t>=Structure defining the q-mesh used for epsm1.
     620              : !!  remove_exchange=If .TRUE., return e^{-1}-1 namely remove the exchange part.
     621              : !!
     622              : !! OUTPUT
     623              : !!  epsm1%epsm1(npwc,npwc,nomega,iq_loc) symmetrised
     624              : !!
     625              : !! NOTES
     626              : !!  In the present implementation we are not considering a possible umklapp vector G0 in the
     627              : !!  expression Sq = q+G0. Treating this case would require some changes in the G-sphere
     628              : !!  since we have to consider G-G0. The code however stops in sigma if a nonzero G0 is required
     629              : !!  to reconstruct the BZ.
     630              : !!
     631              : !!  * Remember the symmetry properties of \tilde\espilon^{-1}
     632              : !!    If q_bz=Sq_ibz+G0:
     633              : !!
     634              : !!    $\epsilon^{-1}_{SG1-G0,SG2-G0}(q_bz) = e^{+iS(G2-G1).\tau}\epsilon^{-1}_{G1,G2)}(q)
     635              : !!
     636              : !!    If time-reversal symmetry can be used then :
     637              : !!    $\epsilon^{-1}_{G1,G2}(-q_bz) = e^{+i(G1-G2).\tau}\epsilon^{-1}_{-S^{-1}(G1+Go),-S^{-1}(G2+G0)}^*(q)
     638              : !!
     639              : !! TODO
     640              : !!  Symmetrization can be skipped if iq_bz correspond to a point in the IBZ
     641              : !!
     642              : !! SOURCE
     643              : 
     644            0 : subroutine Epsm1_rotate_iqbz_inplace(epsm1, iq_bz, nomega, npwc, Gsph, Qmesh, remove_exchange)
     645              : 
     646              : !Arguments ------------------------------------
     647              : !scalars
     648              :  class(epsm1_t),intent(inout) :: epsm1
     649              :  integer,intent(in) :: iq_bz, nomega, npwc
     650              :  type(gsphere_t),target,intent(in) :: Gsph
     651              :  type(kmesh_t),intent(in) :: Qmesh
     652              :  logical,intent(in) :: remove_exchange
     653              : 
     654              : !Local variables-------------------------------
     655              : !scalars
     656              :  integer :: iw,ii,jj,iq_ibz,itim_q,isym_q,iq_loc,sg1,sg2, g0(3)
     657              : !arrays
     658              :  real(dp) :: qbz(3)
     659              :  complex(gwp) :: phmsg1t,phmsg2t_star
     660            0 :  complex(gwp),allocatable :: work(:,:)
     661              : ! *********************************************************************
     662              : 
     663            0 :  ABI_CHECK(epsm1%nomega>=nomega,'Too many frequencies required')
     664            0 :  ABI_CHECK(epsm1%npwe  >=npwc , 'Too many G-vectors required')
     665              : 
     666            0 :  ABI_MALLOC(work, (npwc, npwc))
     667              : 
     668              :  ! Get iq_ibz, and symmetries from iq_ibz.
     669            0 :  call qmesh%get_BZ_item(iq_bz,qbz, iq_ibz, isym_q, itim_q, umklp=g0)
     670            0 :  ABI_CHECK(all(g0 == 0), "non-zero g0 is not coded")
     671              : 
     672              :  ! If out-of-memory, only epsm1%espm1(:,:,:,1) has been allocated and filled.
     673            0 :  iq_loc=iq_ibz; if (epsm1%mqmem==0) iq_loc=1
     674              : 
     675              : !$OMP PARALLEL DO PRIVATE(sg2,sg1,phmsg1t,phmsg2t_star) IF (nomega > 1)
     676            0 :  do iw=1,nomega
     677            0 :    do jj=1,npwc
     678            0 :      sg2 = Gsph%rottb(jj,itim_q,isym_q)
     679            0 :      phmsg2t_star = CONJG(Gsph%phmSGt(jj,isym_q))
     680            0 :      do ii=1,npwc
     681            0 :        sg1 = Gsph%rottb(ii,itim_q,isym_q)
     682            0 :        phmsg1t = Gsph%phmSGt(ii,isym_q)
     683            0 :        work(sg1,sg2) = epsm1%epsm1(ii,jj,iw,iq_loc) * phmsg1t * phmsg2t_star
     684              :      end do
     685              :    end do
     686            0 :    epsm1%epsm1(:,:,iw,iq_loc) = work(:,:)
     687              :  end do
     688              : 
     689              :  ! Account for time-reversal
     690            0 :  if (itim_q==2) then
     691              : !$OMP PARALLEL DO IF (nomega > 1)
     692            0 :    do iw=1,nomega
     693            0 :      call sqmat_itranspose(npwc,epsm1%epsm1(:,:,iw,iq_loc))
     694              :    end do
     695              :  end if
     696              : 
     697              :  ! Subtract the exchange contribution.
     698            0 :  if (remove_exchange) then
     699              : !$OMP PARALLEL DO IF (nomega > 1)
     700            0 :    do iw=1,nomega
     701            0 :      do ii=1,npwc
     702            0 :        epsm1%epsm1(ii,ii,iw,iq_loc)=epsm1%epsm1(ii,ii,iw,iq_loc)-1.0_gwp
     703              :      end do
     704              :    end do
     705              :  endif
     706              : 
     707            0 :  ABI_FREE(work)
     708              : 
     709            0 : end subroutine Epsm1_rotate_iqbz_inplace
     710              : !!***
     711              : 
     712              : !----------------------------------------------------------------------
     713              : 
     714              : !!****f* m_screening/epsm1_from_file
     715              : !! NAME
     716              : !!  epsm1_from_file
     717              : !!
     718              : !! FUNCTION
     719              : !!  Initialize basic dimensions and the important (small) arrays in an epsm1_t data type
     720              : !!  starting from a file containing either epsilon^{-1} (_SCR) or chi0 (_SUSC).
     721              : !!
     722              : !! INPUTS
     723              : !!  fname=The name of the external file used to read the matrix.
     724              : !!  mqmem=0 for out-of-core solution, /=0 if entire matrix has to be stored in memory.
     725              : !!  npwe_asked=Number of G-vector to be used in the calculation, if <=0 use Max allowed number.
     726              : !!  comm=MPI communicator.
     727              : !!
     728              : !! OUTPUT
     729              : !!  epsm1<epsm1_t>=The structure initialized with basic dimensions and arrays.
     730              : !!
     731              : !! SOURCE
     732              : 
     733          167 : subroutine epsm1_from_file(epsm1, fname, mqmem, npwe_asked, comm)
     734              : 
     735              : !Arguments ------------------------------------
     736              :  class(epsm1_t),intent(inout) :: epsm1
     737              :  character(len=*),intent(in) :: fname
     738              :  integer,intent(in) :: mqmem,npwe_asked,comm
     739              : 
     740              : !Local variables-------------------------------
     741              : !scalars
     742              :  integer,parameter :: master=0
     743              :  integer :: iw,fform,my_rank,unclassified
     744              :  real(dp) :: re, im, tol
     745              :  character(len=500) :: msg
     746              : ! *********************************************************************
     747              : 
     748              :  !@epsm1_t
     749          334 :  my_rank = xmpi_comm_rank(comm)
     750              : 
     751              :  ! Read header from file.
     752          167 :  call wrtout(std_out, sjoin('epsm1_from_file- testing file: ', fname))
     753          167 :  call epsm1%hscr%from_file(fname, fform, comm)
     754              : 
     755              :  ! Master echoes the header.
     756          306 :  if (my_rank==master) call epsm1%hscr%print([std_out], 0)
     757              : 
     758              :  ! Generic Info
     759          167 :  epsm1%ID         = 0       ! Not yet initialized as epsm1 is calculated in epsm1_mkdump.F90
     760          167 :  epsm1%fname      = trim(fname)
     761          167 :  epsm1%fform      = fform
     762          167 :  epsm1%Tordering  = epsm1%Hscr%Tordering
     763              : 
     764              :  !TODO these quantitities should be checked and initialized in epsm1_mkdump
     765              :  !BEGIN HARDCODED
     766          167 :  epsm1%nI       = 1
     767          167 :  epsm1%nJ       = 1
     768          167 :  epsm1%ikxc     = 0
     769          167 :  epsm1%test_type=-1
     770              : 
     771          167 :  epsm1%Hscr%headform = HSCR_LATEST_HEADFORM   ! XG20090912
     772              : !END HARDCODED
     773              : 
     774          167 :  epsm1%nqibz=epsm1%Hscr%nqibz
     775          167 :  epsm1%mqmem=mqmem ; if (mqmem/=0) epsm1%mqmem=epsm1%nqibz
     776          501 :  ABI_MALLOC(epsm1%qibz, (3,epsm1%nqibz))
     777         4523 :  epsm1%qibz(:,:) = epsm1%Hscr%qibz(:,:)
     778              : 
     779          167 :  epsm1%nqlwl = epsm1%Hscr%nqlwl
     780          501 :  ABI_MALLOC(epsm1%qlwl, (3, epsm1%nqlwl))
     781          835 :  epsm1%qlwl(:,:)=epsm1%Hscr%qlwl(:,:)
     782              : 
     783          167 :  epsm1%nomega=epsm1%Hscr%nomega
     784          501 :  ABI_MALLOC(epsm1%omega,(epsm1%nomega))
     785         1327 :  epsm1%omega(:)=epsm1%Hscr%omega(:)
     786              : 
     787              :  ! Count number of real, imaginary, and complex frequencies.
     788          167 :  epsm1%nomega_r = 1; epsm1%nomega_i = 0
     789          167 :  if (epsm1%nomega == 2) then
     790          128 :    epsm1%nomega_i = 1
     791              :  else
     792           39 :    unclassified = 0
     793           39 :    tol = tol6*Ha_eV
     794          904 :    do iw=2, epsm1%nomega
     795          865 :      re =  REAL(epsm1%omega(iw))
     796          865 :      im = AIMAG(epsm1%omega(iw))
     797          904 :      if (re > tol .and. im < tol) then
     798          207 :        epsm1%nomega_r = iw ! Real freqs are packed in the first locations.
     799          658 :      else if (re < tol .and. im > tol) then
     800          658 :        epsm1%nomega_i = epsm1%nomega_i + 1
     801              :      else
     802            0 :        unclassified = unclassified + 1
     803              :      end if
     804              :    end do
     805           39 :    if (unclassified > 0) then
     806              :      write(msg,'(3a,i0)')&
     807            0 :        'Some complex frequencies are too small to qualify as real or imaginary.',ch10,&
     808            0 :        'Number of unidentified frequencies: ', unclassified
     809            0 :      ABI_WARNING(msg)
     810              :    end if
     811              :  end if
     812              : 
     813              :  ! Get G-vectors.
     814          167 :  epsm1%npwe = epsm1%Hscr%npwe
     815          167 :  if (npwe_asked>0) then
     816          110 :    if (npwe_asked > epsm1%Hscr%npwe) then
     817              :      write(msg,'(a,i8,2a,i8)')&
     818            0 :       'Number of G-vectors saved on file is less than the value required = ',npwe_asked,ch10,&
     819            0 :       'Calculation will proceed with Max available npwe = ',epsm1%Hscr%npwe
     820            0 :      ABI_WARNING(msg)
     821              :    else
     822              :      ! Redefine the no. of G"s for W.
     823          110 :      epsm1%npwe = npwe_asked
     824              :    end if
     825              :  end if
     826              : 
     827              :  ! pointer to epsm1%Hscr%gvec ?
     828          501 :  ABI_MALLOC(epsm1%gvec, (3,epsm1%npwe))
     829        35378 :  epsm1%gvec=epsm1%Hscr%gvec(:,1:epsm1%npwe)
     830              : 
     831          167 : end subroutine epsm1_from_file
     832              : !!***
     833              : 
     834              : !----------------------------------------------------------------------
     835              : 
     836              : !!****f* m_screening/epsm1_mkdump
     837              : !! NAME
     838              : !!  epsm1_mkdump
     839              : !!
     840              : !! FUNCTION
     841              : !!  Dump the content of an epsm1_t data type on file.
     842              : !!
     843              : !! INPUTS
     844              : !!  id_required=Identifier of the matrix to be calculated
     845              : !!  Vcp<vcoul_t>=Structure gathering data on the Coulombian interaction
     846              : !!  ngfft(18)=Info on the FFT mesh.
     847              : !!  nfftot=Total number of point on the FFT mesh.
     848              : !!  gvec(3,npwe)=Reduced coordinates of plane waves for the response functions
     849              : !!  npwe=Number of plane waves.
     850              : !!  comm=MPI communicator.
     851              : !!
     852              : !! OUTPUT
     853              : !!
     854              : !! SOURCE
     855              : 
     856          166 : subroutine epsm1_mkdump(epsm1, Vcp, npwe, gvec, nkxc, kxcg, id_required, approx_type, &
     857              :                         ikxc_required, option_test, fname_dump, iomode, nfftot, ngfft, comm, &
     858            0 :                         fxc_ADA) ! optional
     859              : 
     860              : !Arguments ------------------------------------
     861              : !scalars
     862              :  class(epsm1_t),intent(inout) :: epsm1
     863              :  integer,intent(in) :: id_required, approx_type, option_test, ikxc_required, nkxc
     864              :  integer,intent(in) :: iomode, nfftot, npwe, comm
     865              :  type(vcoul_t),intent(in) :: Vcp
     866              :  character(len=*),intent(in) :: fname_dump
     867              : !arrays
     868              :  integer,intent(in) :: ngfft(18), gvec(3,npwe)
     869              :  complex(gwp),intent(in) :: kxcg(nfftot,nkxc)
     870              :  complex(gwp),intent(in), optional :: fxc_ADA(npwe*epsm1%nI,npwe*epsm1%nJ,epsm1%nqibz)
     871              : 
     872              : !Local variables-------------------------------
     873              : !scalars
     874              :  integer,parameter :: master=0
     875              :  integer :: dim_wing,iq_ibz,is_qeq0,mqmem_,npwe_asked,unt_dump,fform,rdwr,ierr,my_rank,iomode__, nprocs
     876              :  real(dp) :: ucvol
     877              :  character(len=500) :: msg
     878              :  character(len=fnlen) :: ofname
     879              :  character(len=nctk_slen) :: in_varname,out_varname
     880          664 :  type(hscr_t) :: Hscr_cp
     881          166 :  type(spectra_t) :: spectra
     882              :  integer :: comm__
     883              :  type(c_ptr) :: void_ptr
     884              :  integer(kind=XMPI_ADDRESS_KIND) :: count
     885              :  type(xcomm_t) :: xcomm
     886              : !arrays
     887              :  integer :: units(2)
     888              :  real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3)
     889          166 :  complex(gwp),allocatable :: tmp_epsm1(:,:,:)
     890          166 :  complex(dp),allocatable :: dummy_lwing(:,:,:),dummy_uwing(:,:,:),dummy_head(:,:,:)
     891              : ! *********************************************************************
     892              : 
     893            0 :  ABI_CHECK_IEQ(id_required, 4, 'Value of id_required not coded')
     894          166 :  ABI_CHECK_IEQ(npwe, epsm1%npwe, "mismatch in npwe")
     895              : 
     896          498 :  units = [std_out, ab_out]
     897              : 
     898          166 :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
     899          166 :  call metric(gmet,gprimd,-1,rmet,Vcp%rprimd,ucvol)
     900              : 
     901              :  ! if (epsm1%ID/=0) call reset_Epsilonm1(epsm1)
     902          166 :  epsm1%ID=id_required
     903              : 
     904          166 :  ofname = fname_dump
     905          166 :  in_varname = ncname_from_id(epsm1%hscr%id)
     906          166 :  out_varname = ncname_from_id(id_required)
     907              : 
     908              :  !write(std_out,*)'epsm1%ID: ',epsm1%ID,', epsm1%Hscr%ID: ',epsm1%Hscr%ID
     909              : 
     910          166 :  if (epsm1%ID == epsm1%Hscr%ID) then
     911              :    ! The two-point function we are asking for is already stored on file.
     912              :    ! According to mqmem either read and store the entire matrix in memory or do nothing.
     913              : 
     914          161 :    if (epsm1%mqmem > 0) then
     915              :      ! In-core solution.
     916              :      epsm1%use_mpi_shared_win = .False.
     917              : #ifdef HAVE_MPI_ALLOCATE_SHARED_CPTR
     918          145 :      epsm1%use_mpi_shared_win = nprocs > 1
     919              :      !epsm1%use_mpi_shared_win = .True.     ! This to test shared memory with one proc.
     920              : #endif
     921              :      !epsm1%use_mpi_shared_win = .False.    ! This to go back to the old non-scalable version.
     922              : 
     923          145 :      iomode__ = iomode
     924          145 :      if (iomode__ == IO_MODE_MPI) then
     925            0 :        ABI_WARNING("SUSC files with IO_MODE_MPI is buggy. Using Fortran IO")
     926            0 :        iomode__ = IO_MODE_FORTRAN
     927              :      end if
     928              : 
     929          145 :      write(msg,'(a,f12.1,a)')' Memory for epsm1%epsm1: ',two*gwp*npwe**2*epsm1%nomega*epsm1%nqibz*b2Mb,' [Mb] <<< MEM'
     930          145 :      call wrtout(std_out, msg)
     931              : 
     932          145 :      if (.not. epsm1%use_mpi_shared_win) then
     933          115 :        call epsm1%shared_comm%set_to_self()
     934              : 
     935          115 :        if (nprocs > 1) then
     936              :          msg = strcat("- WARNING: Cannot use MPI shared memory as MPI library does not support MPI_WIN_ALLOCATE_SHARED_CPTR", ch10, &
     937            0 :                       "- Memory for epsm1 will increase with nprocs per node!")
     938            0 :          ABI_WARNING(msg)
     939            0 :          call wrtout(ab_out, msg)
     940              :        end if
     941              : 
     942          690 :        ABI_MALLOC_OR_DIE(epsm1%epsm1, (npwe, npwe, epsm1%nomega, epsm1%nqibz), ierr)
     943          115 :        call read_screening(in_varname, epsm1%fname, epsm1%npwe, epsm1%nqibz, epsm1%nomega, epsm1%epsm1, iomode__, comm)
     944              : 
     945              :      else
     946           30 :        call wrtout(std_out, "- HAPPY: Using MPI shared memory, memory for epsm1 won't increase with nprocs per node!")
     947           30 :        comm__ = comm
     948           30 :        xcomm = xcomm_from_mpi_int(comm__)
     949           30 :        epsm1%shared_comm = xcomm%split_type()
     950              : 
     951           30 :        count = _MOK(2 * npwe) * _MOK(npwe) * _MOK(epsm1%nomega * epsm1%nqibz)
     952           30 :        call epsm1%shared_comm%allocate_shared_master(count, gwp, xmpi_info_null, void_ptr, epsm1%epsm1_win)
     953          150 :        call c_f_pointer(void_ptr, epsm1%epsm1, shape=[npwe, npwe, epsm1%nomega, epsm1%nqibz])
     954              : 
     955              :        ! Only one proc in shared_comm reads from file.
     956           30 :        call xmpi_win_fence(XMPI_MODE_NOPRECEDE, epsm1%epsm1_win, ierr) ! Start the RMA epoch.
     957           30 :        ABI_CHECK_MPI(ierr, "")
     958           30 :        if (epsm1%shared_comm%me == 0) then
     959           10 :          call read_screening(in_varname, epsm1%fname, epsm1%npwe, epsm1%nqibz, epsm1%nomega, epsm1%epsm1, iomode__, xmpi_comm_self)
     960              :        end if
     961           30 :        call xmpi_win_fence(XMPI_MODE_NOSUCCEED, epsm1%epsm1_win, ierr) ! Close the RMA epoch.
     962           30 :        ABI_CHECK_MPI(ierr, "")
     963           30 :        call xcomm%free()
     964              :      end if
     965              : 
     966              :    else
     967              :      ! Out-of-core solution
     968           16 :      ABI_COMMENT("mqmem==0 => allocating a single q-slice of (W|chi0) (slower but less memory).")
     969              :      continue
     970              :    end if
     971              : 
     972          161 :    return
     973              : 
     974              :  else
     975              :    ! === The matrix stored on file do not correspond to the quantity required ===
     976              :    ! * Presently only the transformation chi0 => e^-1 is coded
     977              :    ! * According to epsm1%mqmem either calculate e^-1 dumping the result to a file
     978              :    !   for a subsequent use or calculate e^-1 keeping everything in memory.
     979              : 
     980            5 :    if (epsm1%mqmem == 0) then
     981              :      ! Open file and write the header for the SCR file. For the moment only master works.
     982              : 
     983            1 :      if (my_rank==master) then
     984            1 :        if (iomode == IO_MODE_ETSF) then
     985            1 :           ofname = nctk_ncify(ofname)
     986            1 :           NCF_CHECK(nctk_open_create(unt_dump, ofname, xmpi_comm_self))
     987              :        else
     988            0 :          if (open_file(ofname,msg,newunit=unt_dump,form="unformatted",status="unknown",action="write") /= 0) then
     989            0 :            ABI_ERROR(msg)
     990              :          end if
     991              :        end if
     992            1 :        call wrtout(std_out,sjoin('epsm1_mkdump: calculating and writing epsilon^-1 matrix on file: ',ofname))
     993              : 
     994              :        ! Update the entries in the header that have been modified.
     995              :        ! TODO, write function to return title, just for info
     996            1 :        call epsm1%Hscr%copy(Hscr_cp)
     997            1 :        Hscr_cp%ID = id_required
     998            1 :        Hscr_cp%ikxc = ikxc_required
     999            1 :        Hscr_cp%test_type = option_test
    1000            1 :        Hscr_cp%titles(1)  = 'SCR file: epsilon^-1'
    1001            1 :        Hscr_cp%titles(2)  = 'TESTPARTICLE'
    1002              :        ! Treat the case in which a smaller matrix is used.
    1003            1 :        Hscr_cp%npwe = npwe
    1004              : 
    1005            1 :        rdwr=2; fform=Hscr_cp%fform
    1006            1 :        call hscr_cp%io(fform,rdwr,unt_dump,xmpi_comm_self,master,iomode)
    1007            1 :        call Hscr_cp%free()
    1008              : 
    1009            5 :        ABI_MALLOC_OR_DIE(tmp_epsm1, (npwe, npwe, epsm1%nomega), ierr)
    1010              : 
    1011            7 :        do iq_ibz=1,epsm1%nqibz
    1012            6 :          is_qeq0=0
    1013            6 :          if (normv(epsm1%qibz(:,iq_ibz),gmet,'G')<GW_TOLQ0) is_qeq0=1
    1014              : 
    1015            6 :          call read_screening(in_varname,epsm1%fname,npwe,1,epsm1%nomega,tmp_epsm1,iomode,xmpi_comm_self,iqiA=iq_ibz)
    1016              : 
    1017            6 :          dim_wing=0; if (is_qeq0==1) dim_wing=3
    1018           30 :          ABI_MALLOC(dummy_lwing,(npwe*epsm1%nI,epsm1%nomega,dim_wing))
    1019           30 :          ABI_MALLOC(dummy_uwing,(npwe*epsm1%nJ,epsm1%nomega,dim_wing))
    1020           30 :          ABI_MALLOC(dummy_head,(dim_wing,dim_wing,epsm1%nomega))
    1021              : 
    1022            6 :          if (approx_type<2 .or. approx_type>3) then
    1023            6 :            ABI_WARNING('Entering out-of core RPA or Kxc branch')
    1024              :            call make_epsm1_driver(iq_ibz,dim_wing,npwe,epsm1%nI,epsm1%nJ,epsm1%nomega,epsm1%omega,&
    1025              :                                   approx_type,option_test,Vcp,nfftot,ngfft,nkxc,kxcg,gvec,dummy_head,&
    1026            6 :                                   dummy_lwing,dummy_uwing,tmp_epsm1,spectra,xmpi_comm_self,xmpi_undefined)
    1027              :          else
    1028            0 :            ABI_WARNING('Entering out-of core fxc_ADA branch')
    1029              :            call make_epsm1_driver(iq_ibz,dim_wing,npwe,epsm1%nI,epsm1%nJ,epsm1%nomega,epsm1%omega,&
    1030              :                                   approx_type,option_test,Vcp,nfftot,ngfft,nkxc,kxcg,gvec,dummy_head,&
    1031              :                                   dummy_lwing,dummy_uwing,tmp_epsm1,spectra,xmpi_comm_self, xmpi_undefined, &
    1032            0 :                                   fxc_ADA=fxc_ADA(:,:,iq_ibz))
    1033              :          end if
    1034              : 
    1035            6 :          ABI_FREE(dummy_head)
    1036            6 :          ABI_FREE(dummy_uwing)
    1037            6 :          ABI_FREE(dummy_lwing)
    1038              : 
    1039            6 :          if (is_qeq0==1) then
    1040            1 :            call spectra%repr(msg)
    1041            1 :            call wrtout(units, msg)
    1042              :          end if
    1043            6 :          call spectra%free()
    1044              : 
    1045            7 :          call write_screening(out_varname,unt_dump,iomode,npwe,epsm1%nomega,iq_ibz,tmp_epsm1)
    1046              :        end do
    1047              : 
    1048            1 :        if (iomode == IO_MODE_ETSF) then
    1049            1 :          NCF_CHECK(nf90_close(unt_dump))
    1050              :        else
    1051            0 :          close(unt_dump)
    1052              :        endif
    1053              : 
    1054            1 :        ABI_FREE(tmp_epsm1)
    1055              :      end if !master
    1056              : 
    1057              :      ! Master broadcasts ofname.
    1058              :      ! NOTE: A synchronization is required here, else the other procs start to read the
    1059              :      ! SCR file before it is written by the master. xmpi_bcast will synch the procs.
    1060            1 :      call xmpi_bcast(ofname,  master, comm, ierr)
    1061              : 
    1062              :      ! Now epsm1% "belongs" to the file "ofname", thus
    1063              :      ! each proc has to destroy and re-initialize the object.
    1064            1 :      call epsm1%free()
    1065              : 
    1066            1 :      mqmem_=epsm1%mqmem; npwe_asked=npwe
    1067            1 :      call epsm1%from_file(ofname, mqmem_, npwe_asked, comm)
    1068              : 
    1069              :      ! Now epsm1% has been reinitialized and ready-to-use.
    1070            1 :      epsm1%id = id_required
    1071            2 :      call epsm1%print([std_out], 0)
    1072              :    else
    1073              :      ! ========================
    1074              :      ! === In-core solution ===
    1075              :      ! ========================
    1076              :      ! In-core solution.
    1077              :      epsm1%use_mpi_shared_win = .False.
    1078              : #ifdef HAVE_MPI_ALLOCATE_SHARED_CPTR
    1079            4 :      epsm1%use_mpi_shared_win = nprocs > 1
    1080              :      !epsm1%use_mpi_shared_win = .True.     ! This to test shared memory with one proc.
    1081              : #endif
    1082              :      !epsm1%use_mpi_shared_win = .False.    ! This to go back to the old non-scalable version.
    1083              : 
    1084            4 :      if (.not. epsm1%use_mpi_shared_win) then
    1085            4 :        call epsm1%shared_comm%set_to_self()
    1086              : 
    1087              :        if (nprocs > 1) then
    1088              :          msg = strcat("- WARNING: Cannot use MPI shared memory as MPI library does not support MPI_WIN_ALLOCATE_SHARED_CPTR", ch10, &
    1089              :                       "- Memory for epsm1 will increase with nprocs per node!")
    1090              :          ABI_WARNING(msg)
    1091              :          call wrtout(ab_out, msg)
    1092              :        end if
    1093              : 
    1094           24 :        ABI_MALLOC_OR_DIE(epsm1%epsm1, (npwe,npwe,epsm1%nomega,epsm1%nqibz), ierr)
    1095            4 :        call read_screening(in_varname, epsm1%fname, npwe, epsm1%nqibz, epsm1%nomega, epsm1%epsm1, iomode, comm)
    1096              : 
    1097              :      else
    1098            0 :        call wrtout(std_out, "- HAPPY: Using MPI shared memory, memory for epsm1 won't increase with nprocs per node!")
    1099            0 :        comm__ = comm
    1100            0 :        xcomm = xcomm_from_mpi_int(comm__)
    1101            0 :        epsm1%shared_comm = xcomm%split_type()
    1102              : 
    1103            0 :        count = _MOK(2 * npwe) * _MOK(npwe) * _MOK(epsm1%nomega * epsm1%nqibz)
    1104            0 :        call epsm1%shared_comm%allocate_shared_master(count, gwp, xmpi_info_null, void_ptr, epsm1%epsm1_win)
    1105            0 :        call c_f_pointer(void_ptr, epsm1%epsm1, shape=[npwe, npwe, epsm1%nomega, epsm1%nqibz])
    1106              : 
    1107              :        ! Only one proc in shared_comm reads from file.
    1108            0 :        call xmpi_win_fence(XMPI_MODE_NOPRECEDE, epsm1%epsm1_win, ierr) ! Start the RMA epoch.
    1109            0 :        ABI_CHECK_MPI(ierr, "")
    1110            0 :        if (epsm1%shared_comm%me == 0) then
    1111            0 :          call read_screening(in_varname, epsm1%fname, epsm1%npwe, epsm1%nqibz, epsm1%nomega, epsm1%epsm1, iomode__, xmpi_comm_self)
    1112              :        end if
    1113            0 :        call xmpi_win_fence(XMPI_MODE_NOSUCCEED, epsm1%epsm1_win, ierr) ! Close the RMA epoch.
    1114            0 :        ABI_CHECK_MPI(ierr, "")
    1115            0 :        call xcomm%free()
    1116              :      end if
    1117              : 
    1118           26 :      do iq_ibz=1,epsm1%nqibz
    1119           22 :        is_qeq0=0; if (normv(epsm1%qibz(:,iq_ibz),gmet,'G')<GW_TOLQ0) is_qeq0=1
    1120              : 
    1121           22 :        dim_wing=0; if (is_qeq0==1) dim_wing=3 ! FIXME
    1122          110 :        ABI_MALLOC(dummy_lwing,(npwe*epsm1%nI,epsm1%nomega,dim_wing))
    1123          110 :        ABI_MALLOC(dummy_uwing,(npwe*epsm1%nJ,epsm1%nomega,dim_wing))
    1124          110 :        ABI_MALLOC(dummy_head,(dim_wing,dim_wing,epsm1%nomega))
    1125              : 
    1126           22 :        comm__ = comm
    1127           22 :        if (epsm1%use_mpi_shared_win) comm__ = epsm1%shared_comm%value
    1128              : 
    1129           22 :        if (approx_type<2 .or. approx_type>3) then
    1130           22 :          ABI_COMMENT('Entering in-core RPA and Kxc branch')
    1131              :          call make_epsm1_driver(iq_ibz,dim_wing,npwe,epsm1%nI,epsm1%nJ,epsm1%nomega,epsm1%omega,&
    1132              :                   approx_type,option_test,Vcp,nfftot,ngfft,nkxc,kxcg,gvec,dummy_head,&
    1133           22 :                   dummy_lwing,dummy_uwing,epsm1%epsm1(:,:,:,iq_ibz),spectra,comm__, epsm1%epsm1_win)
    1134              :        else
    1135            0 :          ABI_COMMENT('Entering in-core fxc_ADA branch')
    1136              :          call make_epsm1_driver(iq_ibz,dim_wing,npwe,epsm1%nI,epsm1%nJ,epsm1%nomega,epsm1%omega,&
    1137              :                   approx_type,option_test,Vcp,nfftot,ngfft,nkxc,kxcg,gvec,dummy_head,&
    1138              :                   dummy_lwing,dummy_uwing,epsm1%epsm1(:,:,:,iq_ibz),spectra,comm__, epsm1%epsm1_win, &
    1139            0 :                   fxc_ADA=fxc_ADA(:,:,iq_ibz))
    1140              :        end if
    1141              : 
    1142           22 :        ABI_FREE(dummy_lwing)
    1143           22 :        ABI_FREE(dummy_uwing)
    1144           22 :        ABI_FREE(dummy_head)
    1145              : 
    1146           22 :        if (is_qeq0==1) then
    1147            4 :          call spectra%repr(msg)
    1148            4 :          call wrtout(units, msg)
    1149              :        end if
    1150              : 
    1151           26 :        call spectra%free()
    1152              :      end do
    1153              : 
    1154            4 :      epsm1%id = id_required
    1155            8 :      call epsm1%print([std_out], 0)
    1156              :    end if
    1157              :  end if
    1158              : 
    1159          498 : end subroutine epsm1_mkdump
    1160              : !!***
    1161              : 
    1162          132 : subroutine epsm1_malloc_epsm1_qbz(epsm1, npwc, nomega)
    1163              : 
    1164              : !Arguments ------------------------------------
    1165              :  class(epsm1_t),intent(inout) :: epsm1
    1166              :  integer,intent(in) :: npwc, nomega
    1167              : 
    1168              : !Local variables-------------------------------
    1169              :  integer :: ierr
    1170              :  integer(kind=XMPI_ADDRESS_KIND) :: count
    1171              :  type(c_ptr) :: void_ptr
    1172              : ! *********************************************************************
    1173              : 
    1174          132 :  ABI_CHECK(epsm1%npwe >= npwc, 'Too many G-vectors required')
    1175              : 
    1176          132 :  if (.not. epsm1%use_mpi_shared_win) then
    1177          420 :    ABI_MALLOC_OR_DIE(epsm1%epsm1_qbz, (npwc, npwc, nomega), ierr)
    1178              :  else
    1179           48 :    count = _MOK(2 * npwc) * _MOK(npwc) * _MOK(nomega)
    1180           48 :    call epsm1%shared_comm%allocate_shared_master(count, gwp, xmpi_info_null, void_ptr, epsm1%epsm1_qbz_win)
    1181          192 :    call c_f_pointer(void_ptr, epsm1%epsm1_qbz, shape=[npwc, npwc, nomega])
    1182              :  end if
    1183              : 
    1184          132 : end subroutine epsm1_malloc_epsm1_qbz
    1185              : !!***
    1186              : 
    1187              : !----------------------------------------------------------------------
    1188              : 
    1189              : !!****f* m_screening/epsm1_free_epsm1_qbz
    1190              : !! NAME
    1191              : !!  epsm1_free_epsm1_qbz
    1192              : !!
    1193              : !! FUNCTION
    1194              : !!  Free the internal buffer %epsm1_qbz
    1195              : 
    1196          460 : subroutine epsm1_free_epsm1_qbz(epsm1)
    1197              : 
    1198              : !Arguments ------------------------------------
    1199              :  class(epsm1_t),intent(inout) :: epsm1
    1200              : 
    1201              : !Local variables-------------------------------
    1202              :  integer :: ierr
    1203              : ! *********************************************************************
    1204              : 
    1205          460 :  if (.not. epsm1%use_mpi_shared_win) then
    1206          304 :    ABI_SFREE_PTR(epsm1%epsm1_qbz)
    1207              :  else
    1208          156 :    if (epsm1%epsm1_qbz_win /= xmpi_undefined) then
    1209           48 :      call xmpi_win_free(epsm1%epsm1_qbz_win, ierr)
    1210           48 :      nullify(epsm1%epsm1_qbz)
    1211              :    end if
    1212              :  end if
    1213              : 
    1214          460 : end subroutine epsm1_free_epsm1_qbz
    1215              : !!***
    1216              : 
    1217              : !----------------------------------------------------------------------
    1218              : 
    1219              : !!****f* m_screening/get_epsm1
    1220              : !! NAME
    1221              : !!  get_epsm1
    1222              : !!
    1223              : !! FUNCTION
    1224              : !!  Work in progress but the main is idea is as follows:
    1225              : !!
    1226              : !!  Return the symmetrized inverse dielectric matrix.
    1227              : !!  This method implements both in-core and the out-of-core solution
    1228              : !!  In the later, epsilon^-1 or chi0 are read from file.
    1229              : !!  It is possible to specify options to retrieve (RPA |TDDDT, [TESTCHARGE|TESTPARTICLE]).
    1230              : !!  All dimensions are already initialized in the epsm1% object, this method
    1231              : !!  should act as a wrapper around rdscr and make_epsm1_driver. A better
    1232              : !!  implementation will be done in the following once the coding of file handlers is completed.
    1233              : !!
    1234              : !! INPUTS
    1235              : !!  Vcp<vcoul_t>=Structure gathering data on the Coulombian interaction
    1236              : !!  iqibzA[optional]=Index of the q-point to be read from file (only for out-of-memory solutions)
    1237              : !!  iomode=option definig the file format.
    1238              : !!  option_test
    1239              : !!  comm=MPI communicator.
    1240              : !!
    1241              : !! OUTPUT
    1242              : !!  epsm1%epsm1
    1243              : !!
    1244              : !! TODO
    1245              : !!  Remove this routine. Now everything should be done with epsm1_mkdump
    1246              : !!
    1247              : !! SOURCE
    1248              : 
    1249          290 : subroutine get_epsm1(epsm1,Vcp,approx_type,option_test,iomode,comm,iqibzA)
    1250              : 
    1251              : !Arguments ------------------------------------
    1252              : !scalars
    1253              :  class(epsm1_t),intent(inout) :: epsm1
    1254              :  integer,intent(in) :: iomode,option_test,approx_type,comm
    1255              :  integer,optional,intent(in) :: iqibzA
    1256              :  type(vcoul_t),intent(in) :: Vcp
    1257              : 
    1258              : !Local variables-------------------------------
    1259              : !scalars
    1260              :  integer :: my_approx_type,my_option_test,ng,ierr
    1261              : ! *********************************************************************
    1262              : 
    1263          290 :  my_approx_type = approx_type; my_option_test = option_test
    1264              : 
    1265              :  ! Vcp not yet used.
    1266          290 :  ng = Vcp%ng
    1267              : 
    1268          580 :  select case (epsm1%mqmem)
    1269              :  case (0)
    1270              :    !  Out-of-core solution
    1271          290 :    ABI_SFREE_PTR(epsm1%epsm1)
    1272         1450 :    ABI_MALLOC_OR_DIE(epsm1%epsm1,(epsm1%npwe,epsm1%npwe,epsm1%nomega,1), ierr)
    1273              : 
    1274          290 :    call read_screening(em1_ncname,epsm1%fname,epsm1%npwe,epsm1%nqibz,epsm1%nomega,epsm1%epsm1,iomode,comm,iqiA=iqibzA)
    1275              : 
    1276          290 :    if (epsm1%id == 4) then
    1277              :      ! If q-slice of epsilon^-1 has been read then return
    1278              :      !call epsm1%print()
    1279              :      return
    1280              :    else
    1281            0 :      ABI_ERROR(sjoin('Wrong epsm1%ID', itoa(epsm1%id)))
    1282              :    end if
    1283              : 
    1284              :  case default
    1285              :    ! In-core solution.
    1286          290 :    ABI_ERROR("you should not be here")
    1287              :  end select
    1288              : 
    1289              : end subroutine get_epsm1
    1290              : !!***
    1291              : 
    1292              : !----------------------------------------------------------------------
    1293              : 
    1294              : !!****f* m_screening/decompose_epsm1
    1295              : !! NAME
    1296              : !! decompose_epsm1
    1297              : !!
    1298              : !! FUNCTION
    1299              : !! Decompose the complex symmetrized dielectric
    1300              : !!
    1301              : !! INPUTS
    1302              : !!
    1303              : !! OUTPUT
    1304              : !!
    1305              : !! SOURCE
    1306              : 
    1307            0 : subroutine decompose_epsm1(epsm1, iq_ibz, eigs)
    1308              : 
    1309              : !Arguments ------------------------------------
    1310              : !scalars
    1311              :  class(epsm1_t),intent(in) :: epsm1
    1312              :  integer,intent(in) :: iq_ibz
    1313              : !arrays
    1314              :  complex(dp),intent(out) :: eigs(epsm1%npwe,epsm1%nomega)
    1315              : 
    1316              : !Local variables-------------------------------
    1317              : !scalars
    1318              :  integer :: info,lwork,iw,negw,ig1,ig2,idx,sdim,npwe,ierr
    1319              :  character(len=500) :: msg
    1320              : !arrays
    1321            0 :  real(dp),allocatable :: ww(:),rwork(:)
    1322            0 :  complex(dp),allocatable :: work(:),Adpp(:),eigvec(:,:),Afull(:,:),vs(:,:),wwc(:)
    1323            0 :  logical,allocatable :: bwork(:)
    1324              :  logical :: sortcplx !BUG in abilint
    1325              : ! *********************************************************************
    1326              : 
    1327            0 :  ABI_CHECK(epsm1%mqmem /= 0, 'mqmem==0 not implemented')
    1328              : 
    1329            0 :  npwe = epsm1%npwe
    1330              : 
    1331            0 :  do iw=1,epsm1%nomega
    1332              : 
    1333            0 :    if (ABS(REAL(epsm1%omega(iw)))>0.00001) then
    1334              :      ! Eigenvalues for a generic complex matrix
    1335            0 :      lwork=4*2*npwe
    1336            0 :      ABI_MALLOC(wwc,(npwe))
    1337            0 :      ABI_MALLOC(work,(lwork))
    1338            0 :      ABI_MALLOC(rwork,(npwe))
    1339            0 :      ABI_MALLOC(bwork,(npwe))
    1340            0 :      ABI_MALLOC(vs,(npwe,npwe))
    1341            0 :      ABI_MALLOC(Afull,(npwe,npwe))
    1342              : 
    1343            0 :      Afull=epsm1%epsm1(:,:,iw,iq_ibz)
    1344              : 
    1345              :      !for the moment no sort, maybe here I should sort using the real part?
    1346            0 :      call ZGEES('V','N',sortcplx,npwe,Afull,npwe,sdim,wwc,vs,npwe,work,lwork,rwork,bwork,info)
    1347            0 :      if (info/=0) then
    1348            0 :        ABI_ERROR(sjoin("ZGEES returned info:",itoa(info)))
    1349              :      end if
    1350              : 
    1351            0 :      eigs(:,iw)=wwc(:)
    1352              : 
    1353            0 :      ABI_FREE(wwc)
    1354            0 :      ABI_FREE(work)
    1355            0 :      ABI_FREE(rwork)
    1356            0 :      ABI_FREE(bwork)
    1357            0 :      ABI_FREE(vs)
    1358            0 :      ABI_FREE(Afull)
    1359              : 
    1360              :    else
    1361              :      ! Hermitian version.
    1362            0 :      lwork=2*npwe-1
    1363            0 :      ABI_MALLOC(ww,(npwe))
    1364            0 :      ABI_MALLOC(work,(lwork))
    1365            0 :      ABI_MALLOC(rwork,(3*npwe-2))
    1366            0 :      ABI_MALLOC(eigvec,(npwe,npwe))
    1367            0 :      ABI_MALLOC_OR_DIE(Adpp,(npwe*(npwe+1)/2), ierr)
    1368              : 
    1369              :      idx=0 ! Pack the matrix
    1370            0 :      do ig2=1,npwe
    1371            0 :        do ig1=1,ig2
    1372            0 :          idx=idx+1
    1373            0 :          Adpp(idx)=epsm1%epsm1(ig1,ig2,iw,iq_ibz)
    1374              :        end do
    1375              :      end do
    1376              : 
    1377              :      ! For the moment we require also the eigenvectors.
    1378            0 :      call ZHPEV('V','U',npwe,Adpp,ww,eigvec,npwe,work,rwork,info)
    1379            0 :      if (info/=0) then
    1380            0 :        ABI_ERROR(sjoin('ZHPEV returned info=', itoa(info)))
    1381              :      end if
    1382              : 
    1383            0 :      negw=(COUNT((REAL(ww)<tol6)))
    1384            0 :      if (negw/=0) then
    1385              :        write(msg,'(a,i5,a,i3,a,f8.4)')&
    1386            0 :         'Found negative eigenvalues. No. ',negw,' at iq_ibz= ',iq_ibz,' minval= ',MINVAL(REAL(ww))
    1387            0 :        ABI_WARNING(msg)
    1388              :      end if
    1389              : 
    1390            0 :      eigs(:,iw)=ww(:)
    1391              : 
    1392            0 :      ABI_FREE(ww)
    1393            0 :      ABI_FREE(work)
    1394            0 :      ABI_FREE(rwork)
    1395            0 :      ABI_FREE(eigvec)
    1396            0 :      ABI_FREE(Adpp)
    1397              :    end if
    1398              :  end do !iw
    1399              : 
    1400              : ! contains
    1401              : ! function sortcplx(carg) result(res)
    1402              : !  implicit none
    1403              : !  complex(dp),intent(in) :: carg
    1404              : !  logical :: res
    1405              : !  res=.TRUE.
    1406              : ! end function sortcplx
    1407              : 
    1408            0 : end subroutine decompose_epsm1
    1409              : !!***
    1410              : 
    1411              : !----------------------------------------------------------------------
    1412              : 
    1413              : !!****f* m_screening/make_epsm1_driver
    1414              : !! NAME
    1415              : !! make_epsm1_driver
    1416              : !!
    1417              : !! FUNCTION
    1418              : !!  Driver routine to calculate the inverse symmetrical dielectric matrix starting
    1419              : !!  from the irreducible polarizability. The routine considers a single q-point, and
    1420              : !!  performs the following tasks:
    1421              : !!
    1422              : !!  1) Calculate $\tilde\epsilon^{-1}$ using different approximations:
    1423              : !!      * RPA
    1424              : !!      * ALDA within TDDFT
    1425              : !!
    1426              : !!  2) Use a special treatment of non-Analytic behavior of heads and wings in reciprocal space
    1427              : !!     calculating these quantities for different small q-directions specified by the user
    1428              : !!     (Not yet operative)
    1429              : !!
    1430              : !!  3) Output the electron energy loss function and the macroscopic dielectric function with and
    1431              : !!     without local field effects (only if non-zero real frequencies are available)
    1432              : !!
    1433              : !! INPUTS
    1434              : !!  iq_ibz=index of the q-point in the array Vcp%qibz where epsilon^-1 has to be calculated
    1435              : !!  dim_wing=Dimension of the wings (0 or 3 if q-->0)
    1436              : !!  npwe=Number of G-vectors in chi0.
    1437              : !!  nI,nJ=Number of rows/columns in chi0_ij (1,1 if collinear case)
    1438              : !!  nomega=Number of frequencies.
    1439              : !!  omega(nomega)=Frequencines in Hartree
    1440              : !!  approx_type=Integer flag defining the type of approximation
    1441              : !!   == 0 for RPA   ==
    1442              : !!   == 1 for TDDFT ==
    1443              : !!  option_test=Only for TDDFT:
    1444              : !!   == 0 for TESTPARTICLE ==
    1445              : !!   == 1 for TESTELECTRON ==
    1446              : !!  Vcp<vcoul_t>=Structure gathering data on the Coulombian interaction
    1447              : !!  nfftot=Total number of points in the FFT mesh.
    1448              : !!  ngfft(18)=Info on the FFT mesh.
    1449              : !!  nkxc=Dimension of the kernel in reciprocal space. 0 if kernel is not needed
    1450              : !!  kxcg(nfftot,nkxc)=TDDFT kernel in reciprocal space on the FFT mesh. Used only if approx_type==1
    1451              : !!  gvec(3,npwe)=G-vectors
    1452              : !!  comm=MPI communicator.
    1453              : !!  chi0_lwing(npwe*nI,nomega,dim_wing)=Lower wings of chi0 (only for q-->0)
    1454              : !!  chi0_uwing(npwe*nJ,nomega,dim_wing)=Upper wings of chi0 (only for q-->0)
    1455              : !!  chi0_head(dim_wing,dim_wing,nomega)=Head of of chi0 (only for q-->0)
    1456              : !!
    1457              : !! OUTPUT
    1458              : !!  spectra<spectra_t>Object containing e_macro(w) and EELS(w)
    1459              : !!
    1460              : !! SIDE EFFECTS
    1461              : !!  chi0(npwe*nI,npwe*nJ,nomega): in input the irreducible polarizability, in output
    1462              : !!   the symmetrized inverse dielectric matrix.
    1463              : !!
    1464              : !! SOURCE
    1465              : 
    1466          950 : subroutine make_epsm1_driver(iq_ibz, dim_wing, npwe, nI, nJ, nomega, omega,&
    1467          950 :   approx_type, option_test, Vcp, nfftot, ngfft, nkxc, kxcg, gvec, &
    1468          950 :   chi0_head, chi0_lwing, chi0_uwing, chi0, spectra, comm, epsm1_win, &
    1469          950 :   fxc_ADA, rhor) ! optional argument
    1470              : 
    1471              : !Arguments ------------------------------------
    1472              : !scalars
    1473              :  integer,intent(in) :: iq_ibz,nI,nJ,npwe,nomega,dim_wing,approx_type,option_test,nkxc,nfftot,comm, epsm1_win
    1474              :  real(dp),intent(in),optional :: rhor
    1475              :  type(vcoul_t),target,intent(in) :: Vcp
    1476              :  type(spectra_t),intent(out) :: Spectra
    1477              : !arrays
    1478              :  integer,intent(in) :: ngfft(18),gvec(3,npwe)
    1479              :  complex(gwp),intent(in) :: kxcg(nfftot,nkxc)
    1480              :  complex(dp),intent(in) :: omega(nomega)
    1481              :  complex(dp),intent(inout) :: chi0_lwing(:,:,:)   !(npwe*nI,nomega,dim_wing)
    1482              :  complex(dp),intent(inout) :: chi0_uwing(:,:,:)   !(npwe*nJ,nomega,dim_wing)
    1483              :  complex(dp),intent(inout) :: chi0_head(:,:,:)   !(dim_wing,dim_wing,nomega)
    1484              :  complex(gwp),intent(inout) :: chi0(npwe*nI,npwe*nJ,nomega)
    1485              :  complex(gwp),intent(in),optional :: fxc_ADA(npwe*nI,npwe*nJ)
    1486              : 
    1487              : !Local variables-------------------------------
    1488              : !scalars
    1489              :  integer,parameter :: master=0
    1490              :  integer :: i1,i2,ig1,ig2,io,ierr,irank,my_nqlwl !iqlwl
    1491              :  integer :: nor,my_rank,nprocs,g1mg2_idx
    1492              :  real(dp) :: ucvol
    1493              :  logical :: is_qeq0, use_MPI, use_mpi_shared_win
    1494              :  character(len=500) :: msg
    1495              : !arrays
    1496         1900 :  integer :: omega_distrb(nomega)
    1497          950 :  integer,allocatable :: istart(:),istop(:)
    1498              :  real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3)
    1499          950 :  real(dp),allocatable :: eelf(:,:),tmp_eelf(:)
    1500          950 :  complex(dp),allocatable :: epsm_lf(:,:),epsm_nlf(:,:),tmp_lf(:),tmp_nlf(:)
    1501          950 :  complex(dp),allocatable :: buffer_lwing(:,:),buffer_uwing(:,:)
    1502          950 :  complex(gwp),allocatable :: kxcg_mat(:,:)
    1503              : 
    1504              : !bootstrap and LR
    1505              :  integer :: istep,nstep
    1506              :  real(dp) :: conv_err, alpha, Zr, qpg2(3), qpg2_nrm, cpu, wall, gflops
    1507              :  real(gwp) :: chi00_head, fxc_head
    1508          950 :  complex(gwp),allocatable :: vfxc_boot(:,:), vfxc_boot0(:,:), vfxc_lr(:,:), vfxc_tmp(:,:), chi0_tmp(:,:), chi0_save(:,:,:)
    1509          950 :  complex(gwp), contiguous, pointer :: vc_sqrt(:)
    1510              : ! *************************************************************************
    1511              : 
    1512          950 :  if (nI/=1.or.nJ/=1) then
    1513            0 :    ABI_ERROR("nI or nJ=/1 not yet implemented")
    1514              :  end if
    1515              : 
    1516          950 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
    1517          950 :  call cwtime(cpu, wall, gflops, "start")
    1518              : 
    1519          950 :  call metric(gmet,gprimd,-1,rmet,Vcp%rprimd,ucvol)
    1520              : 
    1521          950 :  is_qeq0 = normv(Vcp%qibz(:,iq_ibz),gmet,'G') < GW_TOLQ0
    1522              : 
    1523         6713 :  omega_distrb = my_rank
    1524          950 :  use_mpi_shared_win = (epsm1_win /= xmpi_undefined)
    1525          950 :  use_MPI = .FALSE.
    1526          950 :  use_MPI = nprocs >= nomega  ! Parallelism is not used
    1527              : 
    1528              :  ! FIXME: MPI mode is temporarily disabled here because we need to know if
    1529              :  ! screening is allocated in shared memory or not.
    1530              :  ! Perhaps now it makes mores sense to use Scalapack/ELPA instead of parallelizing the loop over frequencies
    1531              :  !use_MPI = .FALSE.
    1532              : 
    1533          950 :  if (use_MPI) then
    1534              :    ! Initialize distribution table for frequencies.
    1535          891 :    ABI_MALLOC(istart,(nprocs))
    1536          594 :    ABI_MALLOC(istop,(nprocs))
    1537          297 :    call xmpi_split_work2_i4b(nomega,nprocs,istart,istop)
    1538          852 :    omega_distrb(:)=xmpi_undefined_rank
    1539         1196 :    do irank=0,nprocs-1
    1540          899 :      i1 = istart(irank+1)
    1541          899 :      i2 = istop (irank+1)
    1542         1751 :      if (i1<=i2) omega_distrb(i1:i2) = irank
    1543              :    end do
    1544          297 :    ABI_FREE(istart)
    1545          297 :    ABI_FREE(istop)
    1546              :  end if
    1547              : 
    1548              :  ! Initialize container for spectral results
    1549         3677 :  do nor=1,nomega
    1550         3677 :    if (ABS(AIMAG(omega(nor)))>1.e-3) EXIT
    1551              :  end do
    1552          950 :  nor=nor-1; if (nor==0) nor = 1 ! only imag !?
    1553              : 
    1554          950 :  if (dim_wing==3) then
    1555          151 :    call wrtout(std_out,' Analyzing long wavelength limit for several q')
    1556          564 :    call spectra_init(Spectra,nor,REAL(omega(1:nor)),Vcp%nqlwl,Vcp%qlwl)
    1557          151 :    my_nqlwl = 1
    1558              :    !my_nqlwl = dim_wing ! TODO
    1559              :    !ABI_CHECK(dim_wing==SIZE(Vcp%vcqlwl_sqrt,DIM=2),"WRONG DIMS")
    1560              :  else
    1561         3119 :    call spectra_init(Spectra,nor,REAL(omega(1:nor)),1,Vcp%qibz(:,iq_ibz))
    1562          799 :    my_nqlwl = 1
    1563              :  end if
    1564              :  !
    1565              :  ! NOTE: all processors have to perform this operation in order to have the
    1566              :  !       epsm1 matrix when performing a sigma calculation starting with the file _SUS
    1567              :  !
    1568              :  ! Temporary arrays to store spectra.
    1569         3800 :  ABI_MALLOC(epsm_lf,(nomega,my_nqlwl))
    1570         2850 :  ABI_MALLOC(epsm_nlf,(nomega,my_nqlwl))
    1571         3800 :  ABI_MALLOC(eelf,(nomega,my_nqlwl))
    1572        21089 :  epsm_lf=czero; epsm_nlf=czero; eelf=zero
    1573              : 
    1574              :  ! Temporary arrays used to store output results.
    1575         2850 :  ABI_MALLOC(tmp_lf, (my_nqlwl))
    1576         1900 :  ABI_MALLOC(tmp_nlf, (my_nqlwl))
    1577         2850 :  ABI_MALLOC(tmp_eelf, (my_nqlwl))
    1578              : 
    1579          950 :  if (use_mpi_shared_win) call xmpi_win_fence(XMPI_MODE_NOPRECEDE, epsm1_win, ierr) ! Start the RMA epoch.
    1580              : 
    1581         1872 :  select case (approx_type)
    1582              : 
    1583              :  case (0)
    1584              :    ! RPA: \tepsilon = 1 - Vc^{1/2} chi0 Vc^{1/2}
    1585              :    ! vc_sqrt contains vc^{1/2}(q,G), complex-valued to allow for a possible cutoff.
    1586         6273 :    do io=1,nomega
    1587         6273 :      if (omega_distrb(io) == my_rank) then
    1588              :        !write(std_out,*)"dim_wing",dim_wing
    1589              :        call rpa_symepsm1(iq_ibz,Vcp,npwe,nI,nJ,chi0(:,:,io),my_nqlwl,dim_wing, &
    1590              :                          chi0_head(:,:,io),chi0_lwing(:,io,:),chi0_uwing(:,io,:), &
    1591         5007 :                          tmp_lf,tmp_nlf,tmp_eelf,xmpi_comm_self)
    1592              : 
    1593              :          ! Store results.
    1594        10014 :          epsm_lf(io,:) = tmp_lf
    1595        10014 :          epsm_nlf(io,:) = tmp_nlf
    1596        10014 :          eelf(io,:) = tmp_eelf
    1597              :      end if
    1598              :    end do ! nomega
    1599              : 
    1600              :  case (1)
    1601              :    ! Vertex correction from Adiabatic TDDFT. chi_{G1,G2} = [\delta -\chi0 (vc+kxc)]^{-1}_{G1,G3} \chi0_{G3,G2}
    1602           12 :    ABI_CHECK(Vcp%nqlwl==1,"nqlwl/=1 not coded")
    1603           12 :    ABI_CHECK(nkxc==1,"nkxc/=1 not coded")
    1604              : 
    1605              :    ! Make kxcg_mat(G1,G2) = kxcg(G1-G2) from kxcg defined on the FFT mesh.
    1606           48 :    ABI_MALLOC_OR_DIE(kxcg_mat,(npwe,npwe), ierr)
    1607              : 
    1608           12 :    ierr=0
    1609          264 :    do ig2=1,npwe
    1610         5988 :      do ig1=1,npwe
    1611        22896 :        g1mg2_idx = g2ifft(gvec(:,ig1)-gvec(:,ig2),ngfft)
    1612         5976 :        if (g1mg2_idx>0) then
    1613         5724 :          kxcg_mat(ig1,ig2) = kxcg(g1mg2_idx,1)
    1614              :        else
    1615            0 :          ierr=ierr+1
    1616            0 :          kxcg_mat(ig1,ig2) = czero
    1617              :        end if
    1618              :      end do
    1619              :    end do
    1620              : 
    1621           12 :    if (ierr/=0) then
    1622              :      write(msg,'(a,i4,3a)')&
    1623            0 :      'Found ',ierr,' G1-G2 vectors falling outside the FFT box. ',ch10,&
    1624            0 :      'Enlarge the FFT mesh to get rid of this problem. '
    1625            0 :      ABI_WARNING(msg)
    1626              :    end if
    1627              : 
    1628              :    !FIXME "recheck TDDFT code and parallel"
    1629           12 :    ABI_CHECK(nkxc==1,"nkxc/=1 not coded")
    1630          264 :    do io=1,nomega
    1631          264 :      if (omega_distrb(io) == my_rank) then
    1632              :        call atddft_symepsm1(iq_ibz,Vcp,npwe,nI,nJ,chi0(:,:,io),kxcg_mat,option_test,my_nqlwl,dim_wing,omega(io),&
    1633        21404 :          chi0_head(:,:,io),chi0_lwing(:,io,:),chi0_uwing(:,io,:),tmp_lf,tmp_nlf,tmp_eelf, xmpi_comm_self)
    1634              : 
    1635              :        ! Store results.
    1636          504 :        epsm_lf(io,:) = tmp_lf
    1637          504 :        epsm_nlf(io,:) = tmp_nlf
    1638          504 :        eelf(io,:) = tmp_eelf
    1639              :      end if
    1640              :    end do
    1641              : 
    1642           12 :    ABI_FREE(kxcg_mat)
    1643          264 :    do io=1,nomega
    1644          252 :      write(msg,'(a,i4,a,2f9.4,a)')' Symmetrical epsilon^-1(G,G'') at the ',io,' th omega',omega(io)*Ha_eV,' [eV]'
    1645          252 :      call wrtout(std_out, msg)
    1646          516 :      call print_arr([std_out], chi0(:,:,io))
    1647              :    end do
    1648              : 
    1649              :  case (2)
    1650              :    ! ADA nonlocal vertex correction contained in fxc_ADA
    1651            0 :    ABI_WARNING('Entered fxc_ADA branch: EXPERIMENTAL!')
    1652              :    ! Test that argument was passed
    1653            0 :    if (.not.present(fxc_ADA)) then
    1654            0 :      ABI_ERROR('make_epsm1_driver was not called with optional argument fxc_ADA')
    1655              :    end if
    1656            0 :    ABI_CHECK(Vcp%nqlwl==1,"nqlwl/=1 not coded")
    1657              : 
    1658            0 :    do io=1,nomega
    1659            0 :      if (omega_distrb(io) == my_rank) then
    1660              :        call atddft_symepsm1(iq_ibz,Vcp,npwe,nI,nJ,chi0(:,:,io),fxc_ADA,option_test,my_nqlwl,dim_wing,omega(io),&
    1661            0 :                             chi0_head(:,:,io),chi0_lwing(:,io,:),chi0_uwing(:,io,:),tmp_lf,tmp_nlf,tmp_eelf,xmpi_comm_self)
    1662              : 
    1663              :        ! Store results.
    1664            0 :        epsm_lf(io,:) = tmp_lf
    1665            0 :        epsm_nlf(io,:) = tmp_nlf
    1666            0 :        eelf(io,:) = tmp_eelf
    1667              :      end if
    1668              :    end do
    1669              : 
    1670            0 :    do io=1,nomega
    1671            0 :      write(msg,'(a,i4,a,2f9.4,a)')' Symmetrical epsilon^-1(G,G'') at the ',io,' th omega',omega(io)*Ha_eV,' [eV]'
    1672            0 :      call wrtout(std_out,msg)
    1673            0 :      call print_arr([std_out], chi0(:,:,io))
    1674              :    end do
    1675              : 
    1676              :  case (4)
    1677              :    ! Bootstrap vertex kernel by Sharma [[cite:Sharma2011]]
    1678           32 :    ABI_MALLOC_OR_DIE(vfxc_boot,(npwe*nI,npwe*nJ), ierr)
    1679           24 :    ABI_MALLOC_OR_DIE(vfxc_boot0,(npwe*nI,npwe*nJ), ierr)
    1680           24 :    ABI_MALLOC_OR_DIE(chi0_tmp,(npwe*nI,npwe*nJ), ierr)
    1681           40 :    ABI_MALLOC_OR_DIE(chi0_save,(npwe*nI,npwe*nJ,nomega), ierr)
    1682              : 
    1683            8 :    if (iq_ibz==1) then
    1684            2 :      vc_sqrt => Vcp%vcqlwl_sqrt(:,1)  ! Use Coulomb term for q-->0
    1685              :    else
    1686            6 :      vc_sqrt => Vcp%vc_sqrt(:,iq_ibz)
    1687              :    end if
    1688              : 
    1689        19296 :    chi0_save = chi0 ! a copy of chi0 (ks)
    1690            8 :    nstep = 50 ! max iteration steps
    1691            8 :    alpha = 0.6 ! mixing
    1692            8 :    chi00_head = chi0(1,1,1)*vc_sqrt(1)**2
    1693         3848 :    fxc_head = czero; vfxc_boot = czero; chi0_tmp = czero
    1694          272 :    epsm_lf = czero; epsm_nlf = czero; eelf = zero
    1695            8 :    write(msg,'(a,2f10.6)') ' -> chi0_dft(head): ', chi00_head
    1696            8 :    call wrtout(std_out,msg)
    1697              :    ! loop
    1698            8 :    conv_err = 0.1
    1699           71 :    do istep=1, nstep
    1700       171181 :      chi0 = chi0_save
    1701           71 :      io=1 ! for now only at omega=0
    1702              :      call atddft_symepsm1(iq_ibz,Vcp,npwe,nI,nJ,chi0(:,:,io),vfxc_boot,0,my_nqlwl,dim_wing,omega(io),&
    1703         6151 :         chi0_head(:,:,io),chi0_lwing(:,io,:),chi0_uwing(:,io,:),tmp_lf,tmp_nlf,tmp_eelf,xmpi_comm_self)
    1704           71 :      conv_err = smallest_real
    1705         1136 :      do ig2=1,npwe*nJ
    1706        17111 :        do ig1=1,npwe*nI
    1707        17040 :          conv_err= MAX(conv_err, ABS(chi0(ig1,ig2,1) - chi0_tmp(ig1,ig2)))
    1708              :        end do
    1709              :      end do
    1710           71 :      write(msg,'(a,i4,a,f10.6)') ' => bootstrap itr# ', istep, ', eps^-1 max error: ', conv_err
    1711           71 :      call wrtout(std_out,msg)
    1712           71 :      write(msg,'(a,2f10.6)')  '    eps^-1(head):   ', chi0(1,1,1)
    1713           71 :      call wrtout(std_out,msg)
    1714           71 :      write(msg,'(a,2f10.6)')  '    v^-1*fxc(head): ', fxc_head
    1715           71 :      call wrtout(std_out,msg)
    1716           71 :      if (conv_err <= tol4) exit
    1717              :      !
    1718        15246 :      chi0_tmp = chi0(:,:,1)
    1719        15246 :      vfxc_boot = chi0(:,:,1)/chi00_head
    1720           63 :      if (istep > 1) then
    1721        13310 :        vfxc_boot = alpha*vfxc_boot0 + (one-alpha)*vfxc_boot
    1722              :      end if
    1723        15246 :      vfxc_boot0 = vfxc_boot
    1724           63 :      fxc_head = vfxc_boot(1,1)
    1725         1016 :      do ig1=1,npwe
    1726        15183 :        vfxc_boot(ig1,:) = vc_sqrt(ig1)*vc_sqrt(:)*vfxc_boot(ig1,:)
    1727              :      end do
    1728              :    end do
    1729              :    ! end loop
    1730            8 :    if (istep <= nstep) then
    1731            8 :      write(msg,'(a,i4,a)') ' => bootstrap fxc converged after ', istep, ' iterations'
    1732            8 :      call wrtout(std_out,msg)
    1733              :    else
    1734            0 :      write(msg,'(a,i4,a)') ' -> bootstrap fxc not converged after ', nstep, ' iterations'
    1735            0 :      ABI_WARNING(msg)
    1736              :    end if
    1737              :    !
    1738        19288 :    chi0 = chi0_save
    1739           88 :    do io=1,nomega
    1740           88 :      if (omega_distrb(io) == my_rank) then
    1741              :        call atddft_symepsm1(iq_ibz,Vcp,npwe,nI,nJ,chi0(:,:,io),vfxc_boot,option_test,my_nqlwl,dim_wing,omega(io),&
    1742         7760 :          chi0_head(:,:,io),chi0_lwing(:,io,:),chi0_uwing(:,io,:),tmp_lf,tmp_nlf,tmp_eelf,xmpi_comm_self)
    1743          160 :        epsm_lf(io,:) = tmp_lf
    1744          160 :        epsm_nlf(io,:) = tmp_nlf
    1745          160 :        eelf(io,:) = tmp_eelf
    1746              :      end if
    1747              :    end do
    1748              : 
    1749            8 :    ABI_FREE(chi0_tmp)
    1750            8 :    ABI_FREE(chi0_save)
    1751            8 :    ABI_FREE(vfxc_boot)
    1752            8 :    ABI_FREE(vfxc_boot0)
    1753              : 
    1754           88 :    do io=1,nomega
    1755           80 :      write(msg,'(a,i4,a,2f9.4,a)')' Symmetrical epsilon^-1(G,G'') at the ',io,' th omega',omega(io)*Ha_eV,' [eV]'
    1756           80 :      call wrtout(std_out,msg)
    1757          168 :      call print_arr([std_out], chi0(:,:,io))
    1758              :    end do
    1759              : 
    1760              :  case (5)
    1761              :    ! One-shot scalar bootstrap approximation
    1762           16 :    ABI_MALLOC_OR_DIE(vfxc_boot,(npwe*nI,npwe*nJ), ierr)
    1763           20 :    ABI_MALLOC_OR_DIE(chi0_save,(npwe*nI,npwe*nJ,nomega), ierr)
    1764              : 
    1765            4 :    if (iq_ibz==1) then
    1766            1 :      vc_sqrt => Vcp%vcqlwl_sqrt(:,1)  ! Use Coulomb term for q-->0
    1767              :    else
    1768            3 :      vc_sqrt => Vcp%vc_sqrt(:,iq_ibz)
    1769              :    end if
    1770              : 
    1771         9648 :    chi0_save = chi0 ! a copy of chi0
    1772          964 :    fxc_head = czero; vfxc_boot = czero;
    1773          136 :    epsm_lf = czero; epsm_nlf = czero; eelf = zero
    1774            4 :    chi00_head = chi0(1,1,1)*vc_sqrt(1)**2
    1775            4 :    write(msg,'(a,2f10.6)') ' -> chi0_dft(head): ',chi00_head
    1776            4 :    call wrtout(std_out,msg)
    1777              : 
    1778            4 :    fxc_head = vc_sqrt(1)**2/chi00_head + vc_sqrt(1)**2/chi00_head - vc_sqrt(1)**2
    1779            4 :    fxc_head = 0.5*fxc_head + 0.5*sqrt(fxc_head**2 - 4.0*vc_sqrt(1)**4/(chi00_head*chi00_head))
    1780            4 :    vfxc_boot(1,1) = fxc_head
    1781            4 :    write(msg,'(a,2f10.6)') ' -> v^-1*fxc(head): ',fxc_head/vc_sqrt(1)**2
    1782            4 :    call wrtout(std_out,msg)
    1783              : 
    1784         9644 :    chi0 = chi0_save
    1785           44 :    do io=1,nomega
    1786           44 :      if (omega_distrb(io) == my_rank) then
    1787              :        call atddft_symepsm1(iq_ibz,Vcp,npwe,nI,nJ,chi0(:,:,io),vfxc_boot,option_test,my_nqlwl,dim_wing,omega(io),&
    1788         3880 :           chi0_head(:,:,io),chi0_lwing(:,io,:),chi0_uwing(:,io,:),tmp_lf,tmp_nlf,tmp_eelf,xmpi_comm_self)
    1789           80 :        epsm_lf(io,:) = tmp_lf
    1790           80 :        epsm_nlf(io,:) = tmp_nlf
    1791           80 :        eelf(io,:) = tmp_eelf
    1792              :      end if
    1793              :    end do
    1794            4 :    write(msg,'(a,2f10.6)')  '    eps^-1(head):   ',chi0(1,1,1)
    1795            4 :    call wrtout(std_out,msg)
    1796              : 
    1797            4 :    ABI_FREE(chi0_save)
    1798            4 :    ABI_FREE(vfxc_boot)
    1799              : 
    1800           44 :    do io=1,nomega
    1801           40 :      write(msg,'(a,i4,a,2f9.4,a)')' Symmetrical epsilon^-1(G,G'') at the ',io,' th omega',omega(io)*Ha_eV,' [eV]'
    1802           40 :      call wrtout(std_out,msg)
    1803           84 :      call print_arr([std_out], chi0(:,:,io))
    1804              :    end do
    1805              : 
    1806              :  case (6)
    1807              :    ! RPA bootstrap by Rigamonti [[cite:Rigamonti2015]] and Berger [[cite:Berger2015]]
    1808            0 :    ABI_MALLOC_OR_DIE(vfxc_boot,(npwe*nI,npwe*nJ), ierr)
    1809            0 :    ABI_MALLOC_OR_DIE(chi0_save,(npwe*nI,npwe*nJ,nomega), ierr)
    1810            0 :    ABI_MALLOC_OR_DIE(chi0_tmp,(npwe*nI,npwe*nJ), ierr)
    1811              : 
    1812            0 :    if (iq_ibz==1) then
    1813            0 :      vc_sqrt => Vcp%vcqlwl_sqrt(:,1)  ! Use Coulomb term for q-->0
    1814              :    else
    1815            0 :      vc_sqrt => Vcp%vc_sqrt(:,iq_ibz)
    1816              :    end if
    1817              : 
    1818            0 :    chi0_save = chi0 ! a copy of chi0
    1819            0 :    fxc_head = czero; vfxc_boot = czero;
    1820            0 :    epsm_lf = czero; epsm_nlf = czero; eelf = zero
    1821              :    !chi00_head = chi0(1,1,1)*vc_sqrt(1)**2
    1822            0 :    write(msg,'(a,2f10.6)') ' -> chi0_dft(head): ',chi00_head
    1823            0 :    call wrtout(std_out,msg)
    1824              : 
    1825            0 :    io = 1 ! static
    1826              :    call atddft_symepsm1(iq_ibz,Vcp,npwe,nI,nJ,chi0(:,:,io),vfxc_boot,0,my_nqlwl,dim_wing,omega(io),&
    1827            0 :      chi0_head(:,:,io),chi0_lwing(:,io,:),chi0_uwing(:,io,:),tmp_lf,tmp_nlf,tmp_eelf,xmpi_comm_self)
    1828            0 :    epsm_lf(1,:) = tmp_lf
    1829              : 
    1830              :    ! chi(RPA) = chi0 * (1 - chi0 * v_c)^-1
    1831            0 :    chi0 = chi0_save
    1832            0 :    do ig2=2,npwe
    1833            0 :      do ig1=2,npwe
    1834            0 :        chi0(ig1,ig2,io)=-vc_sqrt(ig1)*chi0(ig1,ig2,io)*vc_sqrt(ig2)
    1835              :      end do
    1836            0 :      chi0(ig2,ig2,io)=one+chi0(ig2,ig2,io)
    1837              :    end do
    1838            0 :    chi0(1,:,io) = czero; chi0(:,1,io) = czero; chi0(1,1,io) = one
    1839            0 :    chi0_tmp = chi0(:,:,io)
    1840            0 :    call xginv(chi0_tmp,npwe,comm=comm)
    1841            0 :    chi0 = chi0_save
    1842            0 :    chi0_tmp = MATMUL(chi0(:,:,io), chi0_tmp(:,:)) ! chi(RPA)
    1843            0 :    do ig1=1,npwe
    1844            0 :      chi0_tmp(ig1,:) = vc_sqrt(ig1)*vc_sqrt(:)*chi0_tmp(ig1,:)
    1845              :    end do
    1846              :    !call xginv(chi0_tmp,npwe,comm=comm) ! chi(RPA)^-1
    1847              :    !vfxc_boot = chi0_tmp/epsm_lf(1,1)
    1848              :    !
    1849              :    !vfxc_boot(1,1) = chi0_tmp(1,1)/epsm_lf(1,1)
    1850            0 :    vfxc_boot(1,1) = one/chi0_tmp(1,1)/epsm_lf(1,1)
    1851              :    !@WC: alternatively:
    1852              :    !chi00_head = chi0(1,1,io)*vc_sqrt(1)**2
    1853              :    !vfxc_boot(1,1) = one/chi00_head/epsm_lf(1,1)
    1854            0 :    fxc_head = vfxc_boot(1,1)
    1855            0 :    do ig1=1,npwe
    1856            0 :      vfxc_boot(ig1,:) = vc_sqrt(ig1)*vc_sqrt(:)*vfxc_boot(ig1,:)
    1857              :    end do
    1858            0 :    write(msg,'(a,2f10.6)') ' -> v^-1*fxc(head): ',fxc_head
    1859            0 :    call wrtout(std_out,msg)
    1860              : 
    1861            0 :    chi0 = chi0_save
    1862            0 :    do io=1,nomega
    1863            0 :      if (omega_distrb(io) == my_rank) then
    1864              :        call atddft_symepsm1(iq_ibz,Vcp,npwe,nI,nJ,chi0(:,:,io),vfxc_boot,option_test,my_nqlwl,dim_wing,omega(io),&
    1865            0 :          chi0_head(:,:,io),chi0_lwing(:,io,:),chi0_uwing(:,io,:),tmp_lf,tmp_nlf,tmp_eelf,xmpi_comm_self)
    1866            0 :        epsm_lf(io,:) = tmp_lf
    1867            0 :        epsm_nlf(io,:) = tmp_nlf
    1868            0 :        eelf(io,:) = tmp_eelf
    1869              :      end if
    1870              :    end do
    1871            0 :    write(msg,'(a,2f10.6)')  '    eps^-1(head):   ',chi0(1,1,1)
    1872            0 :    call wrtout(std_out,msg)
    1873              : 
    1874            0 :    ABI_FREE(chi0_save)
    1875            0 :    ABI_FREE(vfxc_boot)
    1876            0 :    ABI_FREE(chi0_tmp)
    1877              : 
    1878            0 :    do io=1,nomega
    1879            0 :      write(msg,'(a,i4,a,2f9.4,a)')' Symmetrical epsilon^-1(G,G'') at the ',io,' th omega',omega(io)*Ha_eV,' [eV]'
    1880            0 :      call wrtout(std_out,msg)
    1881            0 :      call print_arr([std_out], chi0(:,:,io))
    1882              :    end do
    1883              : 
    1884              :  case (7)
    1885              :    ! LR+ALDA hybrid vertex kernel by Tal
    1886              :    ! First ALDA
    1887            4 :    ABI_CHECK(Vcp%nqlwl==1,"nqlwl/=1 not coded")
    1888            4 :    ABI_CHECK(nkxc==1,"nkxc/=1 not coded")
    1889              :    ! Make kxcg_mat(G1,G2) = kxcg(G1-G2) from kxcg defined on the FFT mesh.
    1890           16 :    ABI_MALLOC_OR_DIE(kxcg_mat,(npwe,npwe), ierr)
    1891            4 :    ierr=0
    1892           64 :    do ig2=1,npwe
    1893          964 :      do ig1=1,npwe
    1894         3600 :        g1mg2_idx = g2ifft(gvec(:,ig1)-gvec(:,ig2),ngfft)
    1895          960 :        if (g1mg2_idx>0) then
    1896          900 :          kxcg_mat(ig1,ig2) = kxcg(g1mg2_idx,1)
    1897              :        else
    1898            0 :          ierr=ierr+1
    1899            0 :          kxcg_mat(ig1,ig2) = czero
    1900              :        end if
    1901              :      end do
    1902              :    end do
    1903            4 :    if (ierr/=0) then
    1904              :      write(msg,'(a,i4,3a)')&
    1905            0 :       'Found ',ierr,' G1-G2 vectors falling outside the FFT box. ',ch10,&
    1906            0 :       'Enlarge the FFT mesh to get rid of this problem. '
    1907            0 :      ABI_WARNING(msg)
    1908              :    end if
    1909              :    !FIXME "recheck TDDFT code and parallel"
    1910            4 :    ABI_CHECK(nkxc==1,"nkxc/=1 not coded")
    1911              : 
    1912              :    ! Now LR: (1-Z)*chi0^-1
    1913           16 :    ABI_MALLOC_OR_DIE(vfxc_lr,(npwe*nI,npwe*nJ), ierr)
    1914           12 :    ABI_MALLOC_OR_DIE(vfxc_tmp,(npwe*nI,npwe*nJ), ierr)
    1915           12 :    ABI_MALLOC_OR_DIE(chi0_tmp,(npwe*nI,npwe*nJ), ierr)
    1916              : 
    1917            4 :    if (iq_ibz==1) then
    1918            1 :      vc_sqrt => Vcp%vcqlwl_sqrt(:,1)  ! Use Coulomb term for q-->0
    1919              :    else
    1920            3 :      vc_sqrt => Vcp%vc_sqrt(:,iq_ibz)
    1921              :    end if
    1922              : 
    1923            4 :    Zr = 0.78
    1924            4 :    chi00_head = chi0(1,1,1)*vc_sqrt(1)**2
    1925         1924 :    fxc_head = czero; vfxc_lr = czero; vfxc_tmp = czero
    1926          136 :    epsm_lf = czero; epsm_nlf = czero; eelf = zero
    1927            4 :    write(msg,'(a,2f10.6)') ' -> chi0_dft(head): ', chi00_head
    1928            4 :    call wrtout(std_out,msg)
    1929              :    !
    1930          968 :    chi0_tmp = chi0(:,:,1)
    1931            4 :    call xginv(chi0_tmp,npwe,comm=comm)
    1932          968 :    vfxc_lr = (one-Zr)*chi0_tmp(:,:)
    1933            4 :    write(msg,'(a)') ' Constructing LR+ALDA fxc kernel'
    1934            4 :    call wrtout(std_out,msg)
    1935              :    !
    1936           64 :    do ig1=1,npwe
    1937          964 :       do ig2=1,npwe
    1938         3600 :        qpg2 = Vcp%qibz(:,iq_ibz) + gvec(:,ig1)
    1939          900 :        qpg2_nrm = normv(qpg2,gmet,"G")
    1940         3600 :        qpg2 =  Vcp%qibz(:,iq_ibz) + gvec(:,ig2)
    1941          900 :        qpg2_nrm = SQRT(qpg2_nrm * normv(qpg2,gmet,"G"))
    1942              :        vfxc_tmp(ig1,ig2) = vfxc_lr(ig1,ig2)*exp(-(qpg2_nrm/k_thfermi(rhor))**2) + &
    1943          960 :          kxcg_mat(ig1,ig2)*(one - exp(-(qpg2_nrm/k_thfermi(rhor))**2))
    1944              :        !write(std_out,*) ig1, qpg2_nrm, k_thfermi(rhor), vfxc_lr(ig1,ig1), kxcg_mat(ig1,ig1), vfxc_tmp(ig1,ig1)
    1945              :       end do
    1946              :    end do
    1947              :    !
    1948          968 :    vfxc_lr = vfxc_tmp
    1949              : 
    1950           44 :    do io=1,nomega
    1951           44 :      if (omega_distrb(io) == my_rank) then
    1952              :        call atddft_hyb_symepsm1(iq_ibz,Vcp,npwe,nI,nJ,chi0(:,:,io),vfxc_lr,kxcg_mat,option_test,my_nqlwl,dim_wing,omega(io),&
    1953         3880 :          chi0_head(:,:,io),chi0_lwing(:,io,:),chi0_uwing(:,io,:),tmp_lf,tmp_nlf,tmp_eelf,xmpi_comm_self)
    1954           80 :        epsm_lf(io,:) = tmp_lf
    1955           80 :        epsm_nlf(io,:) = tmp_nlf
    1956           80 :        eelf(io,:) = tmp_eelf
    1957              :      end if
    1958              :    end do
    1959              : 
    1960            4 :    ABI_FREE(kxcg_mat)
    1961            4 :    ABI_FREE(chi0_tmp)
    1962            4 :    ABI_FREE(vfxc_lr)
    1963            4 :    ABI_FREE(vfxc_tmp)
    1964              : 
    1965           44 :    do io=1,nomega
    1966           40 :      write(msg,'(a,i4,a,2f9.4,a)')' Symmetrical epsilon^-1(G,G'') at the ',io,' th omega',omega(io)*Ha_eV,' [eV]'
    1967           40 :      call wrtout(std_out,msg)
    1968           84 :      call print_arr([std_out], chi0(:,:,io))
    1969              :    end do
    1970              : 
    1971              :  case default
    1972          950 :    ABI_BUG(sjoin('Wrong approx_type:',itoa(approx_type)))
    1973              :  end select
    1974              : 
    1975          950 :  if (use_mpi_shared_win) call xmpi_win_fence(XMPI_MODE_NOSUCCEED, epsm1_win, ierr) ! Close the RMA epoch.
    1976              : 
    1977          950 :  if (use_MPI .and. .not. use_mpi_shared_win) then
    1978              :    ! Collect results on each node.
    1979         1188 :    ABI_MALLOC(buffer_lwing, (size(chi0_lwing,dim=1), size(chi0_lwing, dim=3)))
    1980         1188 :    ABI_MALLOC(buffer_uwing, (size(chi0_uwing,dim=1), size(chi0_uwing, dim=3)))
    1981              : 
    1982          852 :    do io=1,nomega
    1983          555 :      if (omega_distrb(io)/=my_rank) then
    1984              :        ! Zero arrays.
    1985       967208 :        chi0(:,:,io) = czero_gw
    1986          344 :        if(dim_wing>0) then
    1987         5904 :           chi0_lwing(:,io,:) = zero
    1988         5904 :           chi0_uwing(:,io,:) = zero
    1989          624 :           chi0_head(:,:,io)  = czero
    1990              :        endif
    1991          688 :        epsm_lf(io,:) = czero
    1992          688 :        epsm_nlf(io,:) = czero
    1993          688 :        eelf(io,:) = zero
    1994              :      end if
    1995              : 
    1996          555 :      call xmpi_sum(chi0(:,:,io), comm,ierr)
    1997              : 
    1998          852 :      if (dim_wing>0) then
    1999              :         ! Build contiguous arrays
    2000        10562 :         buffer_lwing = chi0_lwing(:,io,:)
    2001        10562 :         buffer_uwing = chi0_uwing(:,io,:)
    2002           79 :         call xmpi_sum(buffer_lwing,comm,ierr)
    2003           79 :         call xmpi_sum(buffer_uwing,comm,ierr)
    2004        10483 :         chi0_lwing(:,io,:) = buffer_lwing
    2005        10483 :         chi0_uwing(:,io,:) = buffer_uwing
    2006          237 :         if (size(chi0_head(:,:,io))/= zero) then
    2007           79 :           call xmpi_sum(chi0_head(:,:,io),comm,ierr)
    2008              :         end if
    2009              :      end if
    2010              : 
    2011              :    end do ! iw
    2012              : 
    2013          297 :    call xmpi_sum(epsm_lf, comm, ierr)
    2014          297 :    call xmpi_sum(epsm_nlf,comm, ierr)
    2015          297 :    call xmpi_sum(eelf,    comm, ierr)
    2016          297 :    ABI_FREE(buffer_lwing)
    2017          594 :    ABI_FREE(buffer_uwing)
    2018              :  end if
    2019              : 
    2020              :  ! Save results in Spectra%, mind the slicing.
    2021         4633 :  Spectra%emacro_nlf(:,:) = epsm_nlf(1:nor,:)
    2022         4633 :  Spectra%emacro_lf (:,:) = epsm_lf (1:nor,:)
    2023         4633 :  Spectra%eelf      (:,:) = eelf    (1:nor,:)
    2024              : 
    2025          950 :  ABI_FREE(epsm_lf)
    2026          950 :  ABI_FREE(epsm_nlf)
    2027          950 :  ABI_FREE(eelf)
    2028          950 :  ABI_FREE(tmp_lf)
    2029          950 :  ABI_FREE(tmp_nlf)
    2030          950 :  ABI_FREE(tmp_eelf)
    2031              : 
    2032          950 :  call cwtime_report(" make_epsm1_driver", cpu, wall, gflops)
    2033              : 
    2034         2850 : end subroutine make_epsm1_driver
    2035              : !!***
    2036              : 
    2037              : !----------------------------------------------------------------------
    2038              : 
    2039              : !!****f* m_screening/rpa_symepsm1
    2040              : !! NAME
    2041              : !! rpa_symepsm1
    2042              : !!
    2043              : !! FUNCTION
    2044              : !!  Calculate RPA $\tilde\epsilon^{-1}$
    2045              : !!
    2046              : !!  Use a special treatment of non-Analytic behavior of heads and wings in reciprocal space
    2047              : !!  calculating these quantities for different small q-directions specified by the user
    2048              : !!  (Not yet operative)
    2049              : !!
    2050              : !! INPUTS
    2051              : !!  iq_ibz=index of the q-point in the array Vcp%qibz where epsilon^-1 has to be calculated
    2052              : !!  Vcp<vcoul_t>=Structure gathering data on the Coulombian interaction
    2053              : !!  npwe=Number of G-vectors in chi0.
    2054              : !!  nI,nJ=Number of rows/columns in chi0_ij (1,1 in collinear case)
    2055              : !!  dim_wing=Dimension of the wings (0 or 3 if q-->0)
    2056              : !!  chi0_head(dim_wing,dim_wing)=Head of of chi0 (only for q-->0)
    2057              : !!  chi0_lwing(npwe*nI,dim_wing)=Lower wings of chi0 (only for q-->0)
    2058              : !!  chi0_uwing(npwe*nJ,dim_wing)=Upper wings of chi0 (only for q-->0)
    2059              : !!  comm=MPI communicator.
    2060              : !!
    2061              : !! SIDE EFFECTS
    2062              : !!  chi0(npwe*nI,npwe*nJ): in input the irreducible polarizability,
    2063              : !!                         in output the symmetrized inverse dielectric matrix.
    2064              : !!
    2065              : !! SOURCE
    2066              : 
    2067         5007 : subroutine rpa_symepsm1(iq_ibz,Vcp,npwe,nI,nJ,chi0,my_nqlwl,dim_wing,chi0_head,chi0_lwing,chi0_uwing,epsm_lf,epsm_nlf,eelf,comm)
    2068              : 
    2069              : !Arguments ------------------------------------
    2070              : !scalars
    2071              :  integer,intent(in) :: iq_ibz,nI,nJ,npwe,dim_wing,my_nqlwl,comm
    2072              :  type(vcoul_t),target,intent(in) :: Vcp
    2073              : !arrays
    2074              :  complex(gwp),intent(inout) :: chi0(npwe*nI,npwe*nJ)
    2075              :  complex(dp),intent(inout) :: chi0_lwing(:,:) !(npwe*nI,dim_wing)
    2076              :  complex(dp),intent(inout) :: chi0_uwing(:,:) !(npwe*nJ,dim_wing)
    2077              :  complex(dp),intent(inout) :: chi0_head(:,:) !(dim_wing,dim_wing)
    2078              :  real(dp),intent(out) :: eelf(my_nqlwl)
    2079              :  complex(dp),intent(out) :: epsm_lf(my_nqlwl),epsm_nlf(my_nqlwl)
    2080              : 
    2081              : !Local variables-------------------------------
    2082              : !scalars
    2083              :  integer,parameter :: master=0,prtvol=0
    2084              :  integer :: ig1,ig2,iqlwl,my_rank,nprocs
    2085              :  real(dp) :: ucvol
    2086              :  logical :: is_qeq0
    2087              :  !character(len=500) :: msg
    2088              : !arrays
    2089              :  real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3)
    2090         5007 :  complex(gwp), contiguous, pointer :: vc_sqrt(:)
    2091         5007 :  complex(gwp),allocatable :: chi0_save(:,:)
    2092              : ! *************************************************************************
    2093              : 
    2094              :  ABI_UNUSED(chi0_head(1,1))
    2095              : 
    2096         5007 :  if (nI/=1.or.nJ/=1) then
    2097            0 :    ABI_ERROR("nI or nJ=/1 not yet implemented")
    2098              :  end if
    2099              : 
    2100         5007 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
    2101              : 
    2102         5007 :  call metric(gmet,gprimd,-1,rmet,Vcp%rprimd,ucvol)
    2103              : 
    2104         5007 :  is_qeq0 = (normv(Vcp%qibz(:,iq_ibz),gmet,'G')<GW_TOLQ0)
    2105         5007 :  if (is_qeq0) then
    2106          790 :    ABI_CHECK(iq_ibz==1, "q is 0 but iq_ibz /= 1")
    2107              :  end if
    2108              : 
    2109         5007 :  if (my_nqlwl>1) then
    2110            0 :    ABI_MALLOC(chi0_save,(npwe*nI,npwe*nJ))
    2111            0 :    chi0_save = chi0
    2112              :  end if
    2113              :  !
    2114              :  ! Symmetrized RPA epsilon: 1 - Vc^{1/2} chi0 Vc^{1/2}
    2115              :  ! vc_sqrt contains vc^{1/2}(q, G)
    2116              :  !
    2117              :  ! Loop over small q"s (if any) to treat the nonanalytical behavior.
    2118        10014 :  do iqlwl=my_nqlwl,1,-1
    2119              : 
    2120         5007 :    if (my_nqlwl>1) then
    2121            0 :      chi0(:,:) = chi0_save           ! restore pristine polarizability
    2122            0 :      chi0(:,1) = chi0_lwing(:,iqlwl) ! change the wings
    2123            0 :      chi0(1,:) = chi0_uwing(:,iqlwl)
    2124              :    end if
    2125              : 
    2126         5007 :    if (iq_ibz==1) then
    2127          790 :      vc_sqrt => Vcp%vcqlwl_sqrt(:,iqlwl)  ! Use Coulomb term for q-->0
    2128              :    else
    2129         4217 :      vc_sqrt => Vcp%vc_sqrt(:,iq_ibz)
    2130              :    end if
    2131              : 
    2132       227716 :    do ig2=1,npwe*nJ
    2133     17303524 :      do ig1=1,npwe*nI
    2134     17303524 :        chi0(ig1,ig2) = -vc_sqrt(ig1) * chi0(ig1,ig2) * vc_sqrt(ig2)
    2135              :      end do
    2136       227716 :      chi0(ig2,ig2) = one + chi0(ig2,ig2)
    2137              :    end do
    2138              :    ! chi0, now contains \tepsilon.
    2139              : 
    2140         5007 :    epsm_nlf(iqlwl)=chi0(1,1)
    2141              : 
    2142              :    if (prtvol > 0) then
    2143              :      call wrtout(std_out,' Symmetrical epsilon(G,G'') ')
    2144              :      call print_arr([std_out], chi0)
    2145              :    end if
    2146              :    !
    2147              :    ! === Invert tepsilon and calculate macroscopic dielectric constant ===
    2148              :    ! * epsm_lf(w) = 1 / epsm1(G=0,Gp=0,w).
    2149              :    ! * Since G=Gp=0, there is no difference btw symmetrical and not symmetrical.
    2150              : 
    2151         5007 :    call xginv(chi0,npwe,comm=comm)
    2152              : 
    2153         5007 :    epsm_lf(iqlwl) = one/chi0(1,1)
    2154         5007 :    eelf(iqlwl) = -AIMAG(chi0(1,1))
    2155              : 
    2156              :    if (prtvol > 0) then
    2157              :      call wrtout(std_out," Symmetrical epsilon^-1(G,G'')")
    2158              :      call print_arr([std_out], chi0)
    2159              :    end if
    2160              :    !
    2161              :    ! Save wings of e^-1 overwriting input values.
    2162         5007 :    if (dim_wing>0.and..FALSE.) then
    2163              :      chi0_lwing(:,iqlwl) = chi0(:,1)
    2164              :      chi0_uwing(:,iqlwl) = chi0(1,:)
    2165              :    end if
    2166              : 
    2167              :  end do !iqlwl
    2168              : 
    2169         5007 :  ABI_SFREE(chi0_save)
    2170              : 
    2171         5007 : end subroutine rpa_symepsm1
    2172              : !!***
    2173              : 
    2174              : !----------------------------------------------------------------------
    2175              : 
    2176              : !!****f* m_screening/atddft_symepsm1
    2177              : !! NAME
    2178              : !! atddft_symepsm1
    2179              : !!
    2180              : !! FUNCTION
    2181              : !!  Calculate $\tilde\epsilon^{-1}$ using ALDA within TDDFT
    2182              : !!
    2183              : !!  2) Use a special treatment of non-Analytic behavior of heads and wings in reciprocal space
    2184              : !!     calculating these quantities for different small q-directions specified by the user
    2185              : !!     (Not yet operative)
    2186              : !!
    2187              : !!  Output the electron energy loss function and the macroscopic dielectric function with and
    2188              : !!  without local field effects (only if non-zero real frequencies are available)
    2189              : !!
    2190              : !! INPUTS
    2191              : !!  iq_ibz=index of the q-point in the array Vcp%qibz where epsilon^-1 has to be calculated
    2192              : !!  npwe=Number of G-vectors in chi0.
    2193              : !!  nI,nJ=Number of rows/columns in chi0_ij (1,1 in collinear case)
    2194              : !!  dim_wing=Dimension of the wings (0 or 3 if q-->0)
    2195              : !!  option_test=Only for TDDFT:
    2196              : !!   == 0 for TESTPARTICLE ==
    2197              : !!   == 1 for TESTELECTRON ==
    2198              : !!  Vcp<vcoul_t>=Structure gathering data on the Coulombian interaction
    2199              : !!   %nqibz=Number of q-points.
    2200              : !!   %qibz(3,nqibz)=q-points in the IBZ.
    2201              : !!  comm=MPI communicator.
    2202              : !!  chi0_lwing(npwe*nI,dim_wing)=Lower wings of chi0 (only for q-->0)
    2203              : !!  chi0_uwing(npwe*nJ,dim_wing)=Upper wings of chi0 (only for q-->0)
    2204              : !!  chi0_head(dim_wing,dim_wing)=Head of of chi0 (only for q-->0)
    2205              : !!
    2206              : !! OUTPUT
    2207              : !!
    2208              : !! SIDE EFFECTS
    2209              : !!  chi0(npwe*nI,npwe*nJ): in input the irreducible polarizability, in output
    2210              : !!   the symmetrized inverse dielectric matrix.
    2211              : !!
    2212              : !! SOURCE
    2213              : 
    2214          443 : subroutine atddft_symepsm1(iq_ibz,Vcp,npwe,nI,nJ,chi0,kxcg_mat,option_test,my_nqlwl,dim_wing,omega,&
    2215          443 : & chi0_head,chi0_lwing,chi0_uwing,epsm_lf,epsm_nlf,eelf,comm)
    2216              : 
    2217              : !Arguments ------------------------------------
    2218              : !scalars
    2219              :  integer,intent(in) :: iq_ibz,nI,nJ,npwe,dim_wing,my_nqlwl
    2220              :  integer,intent(in) :: option_test,comm
    2221              :  type(vcoul_t),target,intent(in) :: Vcp
    2222              : !arrays
    2223              :  complex(gwp),intent(in) :: kxcg_mat(npwe,npwe)
    2224              :  complex(dp),intent(in) :: omega
    2225              :  complex(dp),intent(inout) :: chi0_lwing(npwe*nI,dim_wing)
    2226              :  complex(dp),intent(inout) :: chi0_uwing(npwe*nJ,dim_wing)
    2227              :  complex(dp),intent(inout) :: chi0_head(dim_wing,dim_wing)
    2228              :  complex(gwp),intent(inout) :: chi0(npwe*nI,npwe*nJ)
    2229              :  real(dp),intent(out) :: eelf(my_nqlwl)
    2230              :  complex(dp),intent(out) :: epsm_lf(my_nqlwl),epsm_nlf(my_nqlwl)
    2231              : 
    2232              : !Local variables-------------------------------
    2233              : !scalars
    2234              :  integer,parameter :: master=0,prtvol=0
    2235              :  integer :: ig1,ig2,my_rank,nprocs,ierr
    2236              :  real(dp) :: ucvol
    2237              :  logical :: is_qeq0
    2238              :  character(len=500) :: msg
    2239              : !arrays
    2240              :  real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3)
    2241          443 :  complex(gwp),allocatable :: chitmp(:,:)
    2242          443 :  complex(gwp), contiguous, pointer :: vc_sqrt(:)
    2243              : ! *************************************************************************
    2244              : 
    2245              :  ABI_UNUSED(chi0_head(1,1))
    2246              :  ABI_UNUSED(chi0_lwing(1,1))
    2247              :  ABI_UNUSED(chi0_uwing(1,1))
    2248              : 
    2249          443 :  if (nI/=1.or.nJ/=1) then
    2250            0 :    ABI_ERROR("nI or nJ=/1 not yet implemented")
    2251              :  end if
    2252              : 
    2253          443 :  ABI_CHECK(Vcp%nqlwl==1,"nqlwl/=1 not coded")
    2254          443 :  ABI_CHECK(my_nqlwl==1,"my_nqlwl/=1 not coded")
    2255              : 
    2256          443 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
    2257              : 
    2258          443 :  call metric(gmet,gprimd,-1,rmet,Vcp%rprimd,ucvol)
    2259              : 
    2260          443 :  is_qeq0 = (normv(Vcp%qibz(:,iq_ibz),gmet,'G')<GW_TOLQ0)
    2261              : 
    2262          443 :  if (iq_ibz==1) then
    2263              :    !%vc_sqrt => Vcp%vcqlwl_sqrt(:,iqlwl)  ! Use Coulomb term for q-->0
    2264           84 :    vc_sqrt => Vcp%vcqlwl_sqrt(:,1)  ! TODO add treatment of non-Analytic behavior
    2265              :  else
    2266          359 :    vc_sqrt => Vcp%vc_sqrt(:,iq_ibz)
    2267              :  end if
    2268              : 
    2269          443 :  write(msg,'(a,f8.2,a)')" chitmp requires: ",npwe**2*gwp*b2Mb," Mb"
    2270         1772 :  ABI_MALLOC_OR_DIE(chitmp, (npwe,npwe), ierr)
    2271              :  !
    2272              :  ! Calculate chi0*fxc.
    2273      3607552 :  chitmp = MATMUL(chi0,kxcg_mat)
    2274              :  ! First calculate the NLF contribution
    2275         7232 :  do ig1=1,npwe
    2276       112512 :    do ig2=1,npwe
    2277       112512 :      chitmp(ig1,ig2)=-chitmp(ig1,ig2)
    2278              :    end do
    2279         7232 :    chitmp(ig1,ig1)=chitmp(ig1,ig1)+one
    2280              :  end do
    2281              : 
    2282          443 :  call xginv(chitmp,npwe,comm=comm)
    2283              : 
    2284      7102592 :  chitmp = MATMUL(chitmp,chi0)
    2285              :  !if (.not. ABS(REAL(omega))> tol3) call hermitianize(chitmp,"All")
    2286          443 :  chitmp(1,1)=-vc_sqrt(1)*chitmp(1,1)*vc_sqrt(1)
    2287          443 :  chitmp(1,1)=chitmp(1,1)+one
    2288              : 
    2289          443 :  epsm_nlf(1)=chitmp(1,1)
    2290              : 
    2291      3607109 :  chitmp = MATMUL(chi0,kxcg_mat)
    2292              :  ! * Calculate (1-chi0*Vc-chi0*Kxc) and put it in chitmp.
    2293         7232 :  do ig1=1,npwe
    2294       112512 :    do ig2=1,npwe
    2295       112512 :      chitmp(ig1,ig2)=-chitmp(ig1,ig2)-chi0(ig1,ig2)*vc_sqrt(ig2)**2
    2296              :    end do
    2297         7232 :    chitmp(ig1,ig1)=chitmp(ig1,ig1)+one
    2298              :  end do
    2299              : 
    2300              :  ! * Invert (1-chi0*Vc-chi0*Kxc) and Multiply by chi0.
    2301          443 :  call xginv(chitmp,npwe,comm=comm)
    2302      7102592 :  chitmp=MATMUL(chitmp,chi0)
    2303              : 
    2304              :  ! * Save result, now chi0 contains chi.
    2305       112955 :  chi0=chitmp
    2306              : 
    2307          874 :  select case (option_test)
    2308              :  case (0)
    2309              :    ! Symmetrized TESTPARTICLE epsilon^-1
    2310          431 :    call wrtout(std_out,' Calculating TESTPARTICLE epsilon^-1(G,G") = 1 + Vc*chi')
    2311         6896 :    do ig1=1,npwe
    2312       103440 :      chi0(ig1,:)=(vc_sqrt(ig1)*vc_sqrt(:))*chi0(ig1,:)
    2313         6896 :      chi0(ig1,ig1)=one+chi0(ig1,ig1)
    2314              :    end do
    2315              : 
    2316              :  case (1)
    2317              :    ! Symmetrized TESTELECTRON epsilon^-1
    2318           12 :    call wrtout(std_out,' Calculating TESTELECTRON epsilon^-1(G,G") = 1 + (Vc + fxc)*chi')
    2319       490560 :    chitmp=MATMUL(kxcg_mat,chi0)
    2320              : 
    2321              :    ! Perform hermitianization, only valid along the imaginary axis.
    2322           12 :    if (.not. ABS(REAL(omega))> tol3) call hermitianize(chitmp,"All")
    2323              : 
    2324          336 :    do ig1=1,npwe
    2325         9072 :      chi0(ig1,:)=(vc_sqrt(ig1)*vc_sqrt(:))*chi0(ig1,:)+chitmp(ig1,:)
    2326          336 :      chi0(ig1,ig1)=one+chi0(ig1,ig1)
    2327              :    end do
    2328              : 
    2329              :  case default
    2330          443 :    ABI_BUG(sjoin('Wrong option_test:',itoa(option_test)))
    2331              :  end select
    2332              : 
    2333          443 :  ABI_FREE(chitmp)
    2334              :  !
    2335              :  ! === chi0 now contains symmetrical epsm1 ===
    2336              :  ! * Calculate macroscopic dielectric constant epsm_lf(w)=1/epsm1(G=0,Gp=0,w).
    2337          443 :  epsm_lf(1) =  one/chi0(1,1)
    2338          443 :  eelf   (1) = -AIMAG(chi0(1,1))
    2339              : 
    2340              :  if (prtvol > 0) then
    2341              :    write(msg,'(a,2f9.4,a)')' Symmetrical epsilon^-1(G,G'') at omega',omega*Ha_eV,' [eV]'
    2342              :    call wrtout(std_out,msg)
    2343              :    call print_arr([std_out], chi0)
    2344              :  end if
    2345              : 
    2346          443 : end subroutine atddft_symepsm1
    2347              : !!***
    2348              : 
    2349              : !----------------------------------------------------------------------
    2350              : 
    2351              : !!****f* m_screening/atddft_hyb_symepsm1
    2352              : !! NAME
    2353              : !! atddft_hyb_symepsm1
    2354              : !!
    2355              : !! FUNCTION
    2356              : !!  Calculate $\tilde\epsilon^{-1}$ using ALDA within TDDFT
    2357              : !!
    2358              : !!  Based on atddft_symepsm1, modified for the LR+ALDA hybrid kernel
    2359              : !!
    2360              : !!  Output the electron energy loss function and the macroscopic dielectric function with and
    2361              : !!  without local field effects (only if non-zero real frequencies are available)
    2362              : !!
    2363              : !! INPUTS
    2364              : !!  iq_ibz=index of the q-point in the array Vcp%qibz where epsilon^-1 has to be calculated
    2365              : !!  npwe=Number of G-vectors in chi0.
    2366              : !!  nI,nJ=Number of rows/columns in chi0_ij (1,1 in collinear case)
    2367              : !!  dim_wing=Dimension of the wings (0 or 3 if q-->0)
    2368              : !!  kxcg_mat_sr=Short-range fxc kernel used in the test-electron epsilon^-1
    2369              : !!  option_test=Only for TDDFT:
    2370              : !!   == 0 for TESTPARTICLE ==
    2371              : !!   == 1 for TESTELECTRON ==
    2372              : !!  Vcp<vcoul_t>=Structure gathering data on the Coulombian interaction
    2373              : !!   %nqibz=Number of q-points.
    2374              : !!   %qibz(3,nqibz)=q-points in the IBZ.
    2375              : !!  comm=MPI communicator.
    2376              : !!  chi0_lwing(npwe*nI,dim_wing)=Lower wings of chi0 (only for q-->0)
    2377              : !!  chi0_uwing(npwe*nJ,dim_wing)=Upper wings of chi0 (only for q-->0)
    2378              : !!  chi0_head(dim_wing,dim_wing)=Head of of chi0 (only for q-->0)
    2379              : !!
    2380              : !! OUTPUT
    2381              : !!
    2382              : !! SIDE EFFECTS
    2383              : !!  chi0(npwe*nI,npwe*nJ): in input the irreducible polarizability, in output
    2384              : !!   the symmetrized inverse dielectric matrix.
    2385              : !!
    2386              : !! SOURCE
    2387              : 
    2388           40 : subroutine atddft_hyb_symepsm1(iq_ibz,Vcp,npwe,nI,nJ,chi0,kxcg_mat,kxcg_mat_sr,option_test,my_nqlwl,dim_wing,omega,&
    2389           40 : & chi0_head,chi0_lwing,chi0_uwing,epsm_lf,epsm_nlf,eelf,comm)
    2390              : 
    2391              : !Arguments ------------------------------------
    2392              : !scalars
    2393              :  integer,intent(in) :: iq_ibz,nI,nJ,npwe,dim_wing,my_nqlwl
    2394              :  integer,intent(in) :: option_test,comm
    2395              :  type(vcoul_t),target,intent(in) :: Vcp
    2396              : !arrays
    2397              :  complex(gwp),intent(in) :: kxcg_mat(npwe,npwe), kxcg_mat_sr(npwe,npwe)
    2398              :  complex(dp),intent(in) :: omega
    2399              :  complex(dp),intent(inout) :: chi0_lwing(npwe*nI,dim_wing)
    2400              :  complex(dp),intent(inout) :: chi0_uwing(npwe*nJ,dim_wing)
    2401              :  complex(dp),intent(inout) :: chi0_head(dim_wing,dim_wing)
    2402              :  complex(gwp),intent(inout) :: chi0(npwe*nI,npwe*nJ)
    2403              :  real(dp),intent(out) :: eelf(my_nqlwl)
    2404              :  complex(dp),intent(out) :: epsm_lf(my_nqlwl),epsm_nlf(my_nqlwl)
    2405              : 
    2406              : !Local variables-------------------------------
    2407              : !scalars
    2408              :  integer,parameter :: master=0,prtvol=0
    2409              :  integer :: ig1,ig2,my_rank,nprocs,ierr
    2410              :  real(dp) :: ucvol, Zr
    2411              :  logical :: is_qeq0
    2412              :  character(len=500) :: msg
    2413              : !arrays
    2414              :  real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3)
    2415           40 :  complex(gwp),allocatable :: chitmp(:,:)
    2416           40 :  complex(gwp), contiguous, pointer :: vc_sqrt(:)
    2417              : ! *************************************************************************
    2418              : 
    2419              :  ABI_UNUSED(chi0_head(1,1))
    2420              :  ABI_UNUSED(chi0_lwing(1,1))
    2421              :  ABI_UNUSED(chi0_uwing(1,1))
    2422              : 
    2423           40 :  if (nI/=1.or.nJ/=1) then
    2424            0 :    ABI_ERROR("nI or nJ=/1 not yet implemented")
    2425              :  end if
    2426              : 
    2427           40 :  ABI_CHECK(Vcp%nqlwl==1,"nqlwl/=1 not coded")
    2428           40 :  ABI_CHECK(my_nqlwl==1,"my_nqlwl/=1 not coded")
    2429              : 
    2430           40 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
    2431              : 
    2432           40 :  call metric(gmet,gprimd,-1,rmet,Vcp%rprimd,ucvol)
    2433              : 
    2434           40 :  is_qeq0 = (normv(Vcp%qibz(:,iq_ibz),gmet,'G')<GW_TOLQ0)
    2435              : 
    2436           40 :  if (iq_ibz==1) then
    2437              :    !%vc_sqrt => Vcp%vcqlwl_sqrt(:,iqlwl)  ! Use Coulomb term for q-->0
    2438           10 :    vc_sqrt => Vcp%vcqlwl_sqrt(:,1)  ! TODO add treatment of non-Analytic behavior
    2439              :  else
    2440           30 :    vc_sqrt => Vcp%vc_sqrt(:,iq_ibz)
    2441              :  end if
    2442              : 
    2443           40 :  write(msg,'(a,f8.2,a)')" chitmp requires: ",npwe**2*gwp*b2Mb," Mb"
    2444          160 :  ABI_MALLOC_OR_DIE(chitmp,(npwe,npwe), ierr)
    2445              :  !
    2446              :  ! * Calculate chi0*fxc.
    2447       289280 :  chitmp = MATMUL(chi0,kxcg_mat)
    2448              :  ! * First calculate the NLF contribution
    2449          640 :  do ig1=1,npwe
    2450         9600 :    do ig2=1,npwe
    2451         9600 :      chitmp(ig1,ig2)=-chitmp(ig1,ig2)
    2452              :    end do
    2453          640 :    chitmp(ig1,ig1)=chitmp(ig1,ig1)+one
    2454              :  end do
    2455              : 
    2456           40 :  call xginv(chitmp,npwe,comm=comm)
    2457              : 
    2458       568960 :  chitmp = MATMUL(chitmp,chi0)
    2459              :  !if (.not. ABS(REAL(omega))> tol3) call hermitianize(chitmp,"All")
    2460           40 :  chitmp(1,1)=-vc_sqrt(1)*chitmp(1,1)*vc_sqrt(1)
    2461           40 :  chitmp(1,1)=chitmp(1,1)+one
    2462              : 
    2463           40 :  epsm_nlf(1)=chitmp(1,1)
    2464              : 
    2465       289240 :  chitmp = MATMUL(chi0,kxcg_mat)
    2466              :  ! * Calculate (1-chi0*Vc-chi0*Kxc) and put it in chitmp.
    2467          640 :  do ig1=1,npwe
    2468         9600 :    do ig2=1,npwe
    2469         9600 :      chitmp(ig1,ig2)=-chitmp(ig1,ig2)-chi0(ig1,ig2)*vc_sqrt(ig2)**2
    2470              :    end do
    2471          640 :    chitmp(ig1,ig1)=chitmp(ig1,ig1)+one
    2472              :  end do
    2473              : 
    2474              :  ! * Invert (1-chi0*Vc-chi0*Kxc) and Multiply by chi0.
    2475           40 :  call xginv(chitmp,npwe,comm=comm)
    2476       568960 :  chitmp=MATMUL(chitmp,chi0)
    2477              : 
    2478              :  ! * Save result, now chi0 contains chi.
    2479         9640 :  chi0=chitmp
    2480              : 
    2481           40 :  select case (option_test)
    2482              :  case (0)
    2483              :    ! Symmetrized TESTPARTICLE epsilon^-1
    2484            0 :    call wrtout(std_out,' Calculating TESTPARTICLE epsilon^-1(G,G") = 1 + Vc*chi')
    2485            0 :    do ig1=1,npwe
    2486            0 :      chi0(ig1,:)=(vc_sqrt(ig1)*vc_sqrt(:))*chi0(ig1,:)
    2487            0 :      chi0(ig1,ig1)=one+chi0(ig1,ig1)
    2488              :    end do
    2489              : 
    2490              :  case (1)
    2491              :    ! Symmetrized TESTELECTRON epsilon^-1
    2492           40 :    call wrtout(std_out,' Calculating TESTELECTRON epsilon^-1(G,G") = 1 + Vc*chi + Zr*Kxc_sr*chi')
    2493       289280 :    chitmp=MATMUL(kxcg_mat_sr,chi0)
    2494           40 :    Zr = 0.78
    2495              : 
    2496              :    ! Perform hermitianization, only valid along the imaginary axis.
    2497           40 :    if (.not. ABS(REAL(omega))> tol3) call hermitianize(chitmp,"All")
    2498              : 
    2499          640 :    do ig1=1,npwe
    2500         9600 :      chi0(ig1,:)=(vc_sqrt(ig1)*vc_sqrt(:))*chi0(ig1,:)+chitmp(ig1,:)*Zr
    2501          640 :      chi0(ig1,ig1)=one+chi0(ig1,ig1)
    2502              :    end do
    2503              : 
    2504              :  case default
    2505           40 :    ABI_BUG(sjoin('Wrong option_test:',itoa(option_test)))
    2506              :  end select
    2507              : 
    2508           40 :  ABI_FREE(chitmp)
    2509              :  !
    2510              :  ! === chi0 now contains symmetrical epsm1 ===
    2511              :  ! * Calculate macroscopic dielectric constant epsm_lf(w)=1/epsm1(G=0,Gp=0,w).
    2512           40 :  epsm_lf(1) =  one/chi0(1,1)
    2513           40 :  eelf   (1) = -AIMAG(chi0(1,1))
    2514              : 
    2515              :  if (prtvol > 0) then
    2516              :    write(msg,'(a,2f9.4,a)')' Symmetrical epsilon^-1(G,G'') at omega',omega*Ha_eV,' [eV]'
    2517              :    call wrtout(std_out,msg)
    2518              :    call print_arr([std_out], chi0)
    2519              :  end if
    2520              : 
    2521           40 : end subroutine atddft_hyb_symepsm1
    2522              : !!***
    2523              : 
    2524              : !----------------------------------------------------------------------
    2525              : 
    2526              : !!****f* m_screening/mkem1_q0
    2527              : !! NAME
    2528              : !! mkem1_q0
    2529              : !!
    2530              : !! FUNCTION
    2531              : !!   This routine construct the microscopic dieletric matrix for q-->0 starting from the heads, wings and the body
    2532              : !!   of the irreducible polarizability. Afterwards it calculates the symmetrized inverse dieletric matrix
    2533              : !!   via a block wise inversion thus obtaining the heads and the wings of e^{-1} that can be
    2534              : !!   used to describe the non-analytic behavior for q-->0.
    2535              : !!
    2536              : !! INPUTS
    2537              : !! npwe=Number of Gs used to describe chi0
    2538              : !! nomega=Number of frequencies in chi0.
    2539              : !! n1,n2=Factors used to define the same of the chi0 matrix (1,1 if collinear, the typical case)
    2540              : !! Cryst<crystal_t>=Structure describing the crystal structure.
    2541              : !! Vcp<vcoul_t>=datatypes gathering info on the Coulomb term
    2542              : !! gvec(3,npwe)=G-vector for chi0 in reduced coordinates.
    2543              : !! comm=MPI communicator
    2544              : !!
    2545              : !! OUTPUT
    2546              : !! eps_head(3,3,nomega)=The macroscopic dieletric tensor in reduced coordinates.
    2547              : !!   The dieletric matrix along versor \hat q can be obtained with
    2548              : !!     e(\hat q) = \hat q.eps_head \hat q if all quantities are given in Cartesian coordinates.
    2549              : !!
    2550              : !! SIDE EFFECTS
    2551              : !! chi0(npwe*n1,npwe*n2,nomega)= Input: polarizability. output: inverse dieletric matrix (only the body is used)
    2552              : !! chi0_lwing(npwe*n1,nomega,3)
    2553              : !! chi0_uwing(npwe*n2,nomega,3)  Input:  the lower and upper wings of the polarizability
    2554              : !!                               Output: the "lower" and "upper" wings of the inverse dieletric matrix. See notes below.
    2555              : !! chi0_head(3,3,nomega)= Input: the polarizability tensor in Cartesian coordinates.
    2556              : !!                        Output: The "head" of the inverse dieletric matrix. See notes below.
    2557              : !!
    2558              : !! NOTES
    2559              : !!  Matrix inversion in block form.
    2560              : !!
    2561              : !!         1  n-1
    2562              : !!  M =  | c  u^t| 1     ==>   M^{-1} =  |  1/k          -u^t A^{-1}/k                    |
    2563              : !!       | v  A  | n-1                   | -A^{-1} v/k    A^{-1} + (A^{-1}v u^t A^{-1})/k |
    2564              : !!
    2565              : !!                             where k = c - u^t A^{-1} v
    2566              : !!
    2567              : !!  Let q be a versor in reciprocal space, the symmetrized dielectric matrix with bare coulomb interaction
    2568              : !!  can be written as
    2569              : !!
    2570              : !!  \tilde\epsilon = | q.Eq      q.Wl(G2) |  where   E_ij = \delta_ij -4\pi chi0_head_ij
    2571              : !!                   | q.Wl(G1)  B(G1,G2  |          Wl(G1) = -4\pi chi0_lwing(G1)
    2572              : !!                                                   Wu(G2) = -4\pi chi0_uwing(G1)
    2573              : !!  therefore, in Cartesian coordinates, we have:
    2574              : !!
    2575              : !!  1) e^{-1}_{00}(q) = [ q_i q_j (E_{ij} - \sum_{GG'} Wu_i(G)a B_{GG'}^{-1} Wl_j(G')) ]^{-1} = 1/(q.Lq)
    2576              : !!
    2577              : !!  2) e^{-1}_{0G'}(q) = -e^{-1}_{00}(q) [ \sum_{iG} q_i Wu_i(G)a B_{GG'}^{-1} ] = (q.Su) /(q.Lq)
    2578              : !!
    2579              : !!  3) e^{-1}_{G0}(q)  = -e^{-1}_{00}(q) [ \sum_{iG'} q_i B_{GG'}^{-1} Wl_i(G') ] = (q.Sl) /(q.Lq)
    2580              : !!
    2581              : !!  4) e^{-1}_{GG'}(q) = B_{GG'}^{-1} +
    2582              : !!     [ \sum_{ij} q_i q_j ( \sum_T B^{-1}_{GT}^{-1} Wl_i(T)) (\sum_T' Wu_j(T') B^{-1}_{T'G'}^{-1} ] / (q.Lq)
    2583              : !!
    2584              : !!  where Su(G,3) and Sl(G,3) are the "upper" and "lower" wings of the inverse dielectric matrix and
    2585              : !!  L is the inverse dielectric tensor. Similar equations hold even if vectors and tensors are given in terms
    2586              : !!  of the reciprocal lattice vectors provided that the metric tensor is taken into account.
    2587              : !!  The main difference is in the expression for the tensor as only one metric tensor can be
    2588              : !!  absorbed in the scalar product, the second metric multiplies one of the wings.
    2589              : !!
    2590              : !!  *) The present implementation assumes that no cutoff technique is used in the Coulomb term.
    2591              : !!
    2592              : !!  *) Once the tensor in know it is possible to average the quadratic form on the sphere exactly.
    2593              : !!  In Cartesian coordinates one obtains.
    2594              : !!
    2595              : !!    \dfrac{1}{4\pi} \int v.Tv d\Omega = Trace(T)/3
    2596              : !!
    2597              : !!  For the inverse dielectric matrix we have to resort to a numerical integration
    2598              : !!
    2599              : !! SOURCE
    2600              : 
    2601            0 : subroutine mkem1_q0(npwe,n1,n2,nomega,Cryst,Vcp,gvec,chi0_head,chi0_lwing,chi0_uwing,chi0,eps_head,comm)
    2602              : 
    2603              : !Arguments ------------------------------------
    2604              : !scalars
    2605              :  integer,intent(in) :: npwe,nomega,n1,n2,comm
    2606              :  type(crystal_t),intent(in) :: Cryst
    2607              :  type(vcoul_t),intent(in) :: Vcp
    2608              : !arrays
    2609              :  integer,intent(in) :: gvec(3,npwe)
    2610              :  complex(gwp),intent(in) :: chi0(npwe*n1,npwe*n2,nomega)
    2611              :  complex(dp),intent(inout) :: chi0_lwing(npwe*n1,nomega,3)
    2612              :  complex(dp),intent(inout) :: chi0_uwing(npwe*n2,nomega,3)
    2613              :  complex(dp),intent(inout) :: chi0_head(3,3,nomega)
    2614              :  complex(dp),intent(out) :: eps_head(3,3,nomega)
    2615              : 
    2616              : !Local variables ------------------------------
    2617              : !scalars
    2618              :  integer :: iw,ig,ig1,ig2,idir,jdir
    2619              : !arrays
    2620            0 :  real(dp),allocatable :: modg_inv(:)
    2621            0 :  complex(dp),allocatable :: eps_lwing(:,:),eps_uwing(:,:),eps_body(:,:),cvec(:)
    2622              : !************************************************************************
    2623              : 
    2624            0 :  ABI_CHECK(npwe /= 1, "npwe must be >1")
    2625              :  ABI_UNUSED(comm)
    2626              : 
    2627              :  ! Precompute 1/|G|.
    2628            0 :  ABI_MALLOC(modg_inv,(npwe-1))
    2629            0 :  do ig=1,npwe-1
    2630            0 :    modg_inv(ig) = one/normv(gvec(:,ig+1),Cryst%gmet,'G')
    2631              :  end do
    2632              : 
    2633            0 :  ABI_MALLOC(eps_uwing,((npwe-1)*n1,3))
    2634            0 :  ABI_MALLOC(eps_lwing,((npwe-1)*n2,3))
    2635            0 :  ABI_MALLOC(eps_body,(npwe-1,npwe-1))
    2636            0 :  ABI_MALLOC(cvec,(npwe-1))
    2637              : 
    2638            0 :  do iw=1,nomega
    2639              :    !
    2640              :    ! Head and wings of the symmetrized epsilon.
    2641            0 :    eps_head(:,:,iw) = -four_pi*chi0_head(:,:,iw)
    2642            0 :    do idir=1,3
    2643            0 :      eps_head(idir,idir,iw) = one + eps_head(idir,idir,iw)
    2644            0 :      eps_lwing(:,idir) = -four_pi * modg_inv * chi0_lwing(2:,iw,idir)
    2645            0 :      eps_uwing(:,idir) = -four_pi * modg_inv * chi0_uwing(2:,iw,idir)
    2646              :      !eps_lwing(:,idir) = -chi0_lwing(2:,iw,idir) * SQRT(four_pi) * Vcp%vcqlwl_sqrt(2:npwe,1)
    2647              :      !eps_uwing(:,idir) = -chi0_uwing(2:,iw,idir) * SQRT(four_pi) * Vcp%vcqlwl_sqrt(2:npwe,1)
    2648              :    end do
    2649              : 
    2650            0 :    write(std_out,*)" espilon head"
    2651            0 :    call print_arr([std_out], eps_head(:,:,iw))
    2652              :    !
    2653              :    ! Construct the body of the symmetrized epsilon then invert it.
    2654            0 :    do ig2=1,npwe-1
    2655            0 :      do ig1=1,npwe-1
    2656            0 :        eps_body(ig1,ig2) = -four_pi * modg_inv(ig1)*chi0(ig1+1,ig2+1,iw )*modg_inv(ig2)
    2657              :        !eps_body(ig1,ig2) = -Vcp%vcqlwl_sqrt(ig1+1,1)*chi0(ig1+1,ig2+1,iw)* Vcp%vcqlwl_sqrt(ig2+1,1)
    2658              :      end do
    2659            0 :      eps_body(ig2,ig2) = one + eps_body(ig2,ig2)
    2660              :    end do
    2661              : 
    2662            0 :    call xginv(eps_body,npwe-1)
    2663              :    !
    2664              :    ! Overwrite chi0_head and chi0_wings with the head and the wings of the inverse dielectric matrix.
    2665            0 :    do jdir=1,3
    2666              :      !
    2667              :      ! Head.
    2668            0 :      cvec=czero
    2669            0 :      do idir=1,3
    2670            0 :        cvec = cvec + two_pi*Cryst%gmet(jdir,idir)*MATMUL(eps_body,eps_lwing(:,idir)) ! as we work in reciprocal coords.
    2671              :      end do
    2672              :      !cvec = MATMUL(eps_body,eps_lwing(:,jdir))
    2673            0 :      do idir=1,3
    2674            0 :        chi0_head(idir,jdir,iw) = eps_head(idir,jdir,iw) - xdotu(npwe-1,eps_uwing(:,idir),1,cvec,1)
    2675              :      end do
    2676              :      !
    2677              :      ! Now the wings.
    2678            0 :      chi0_uwing(2:,iw,jdir) = -MATMUL(eps_uwing(:,jdir),eps_body)
    2679            0 :      chi0_lwing(2:,iw,jdir) = -MATMUL(eps_body,eps_lwing(:,jdir))
    2680              :      !
    2681              :    end do !jdir
    2682              : 
    2683            0 :    call wrtout(std_out, "espilon^1 head after block inversion")
    2684            0 :    call print_arr([std_out], chi0_head(:,:,iw))
    2685              :    !
    2686              :    ! Change the body but do not add the corrections due to the head and the wings.
    2687              :    ! since they can be obtained on the fly from eps_body and the wings of eps^{-1}.
    2688              :    !%chi0(2:,2:,iw) = eps_body
    2689              :  end do !iw
    2690              : 
    2691            0 :  ABI_FREE(modg_inv)
    2692            0 :  ABI_FREE(cvec)
    2693            0 :  ABI_FREE(eps_lwing)
    2694            0 :  ABI_FREE(eps_uwing)
    2695            0 :  ABI_FREE(eps_body)
    2696              : 
    2697              :  RETURN
    2698              :  ABI_UNUSED(Vcp%ng)
    2699              : 
    2700              : end subroutine mkem1_q0
    2701              : !!***
    2702              : 
    2703              : !----------------------------------------------------------------------
    2704              : 
    2705              : !!****f* m_screening/lebedev_laikov_int
    2706              : !! NAME
    2707              : !!  lebedev_laikov_int
    2708              : !!
    2709              : !! FUNCTION
    2710              : !!
    2711              : !! INPUTS
    2712              : !!
    2713              : !! OUTPUT
    2714              : !!
    2715              : !! SOURCE
    2716              : 
    2717              : subroutine lebedev_laikov_int()
    2718              : 
    2719              : !Arguments ------------------------------------
    2720              : 
    2721              : !Local variables-------------------------------
    2722              : !scalars
    2723              :  integer :: on,npts,ii,ll,mm,lmax,leb_idx !ierr,
    2724              :  real(dp) :: accuracy
    2725              :  complex(dp) :: ang_int
    2726              : !arrays
    2727              :  real(dp) :: cart_vpt(3) !,real_pars(0)
    2728              :  real(dp),allocatable :: vx(:),vy(:),vz(:),ww(:)
    2729              :  complex(dp) :: tensor(3,3),cplx_pars(9)
    2730              :  complex(dp),allocatable :: ref_func(:),expd_func(:) !tmp_momenta(:)
    2731              : ! *************************************************************************
    2732              : 
    2733              :  ABI_ERROR("lebedev_laikov_int is still under development")
    2734              : 
    2735              :  !tensor=RESHAPE((/4.0,2.0,4.0,0.5,2.1,0.0,5.4,2.1,5.0/),(/3,3/))
    2736              :  tensor=RESHAPE((/4.0,0.0,0.0,0.0,4.0,0.0,0.0,0.0,5.0/),(/3,3/))
    2737              :  !tensor=RESHAPE((/1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0/),(/3,3/))
    2738              : 
    2739              :  npts=26
    2740              :  ABI_MALLOC(vx,(npts))
    2741              :  ABI_MALLOC(vy,(npts))
    2742              :  ABI_MALLOC(vz,(npts))
    2743              :  ABI_MALLOC(ww,(npts))
    2744              : 
    2745              :  !call LD0026(vx,vy,vz,ww,on)
    2746              : 
    2747              :  ang_int=czero
    2748              :  do ii=1,npts
    2749              :    cart_vpt = [vx(ii),vy(ii),vz(ii)]
    2750              :    ang_int = ang_int + ww(ii)*DOT_PRODUCT(cart_vpt,MATMUL(tensor,cart_vpt))
    2751              :  end do
    2752              : 
    2753              :  !write(std_out,*)"quadratic form associated to tensor=",tensor
    2754              :  write(std_out,*)"on ang_int",on,ang_int
    2755              : 
    2756              :  ABI_FREE(vx)
    2757              :  ABI_FREE(vy)
    2758              :  ABI_FREE(vz)
    2759              :  ABI_FREE(ww)
    2760              : 
    2761              :  !call init_lebedev_gridset()
    2762              :  cplx_pars = RESHAPE(tensor,(/9/)); accuracy=tol10
    2763              : 
    2764              :  ! This is the function to be expanded evaluated on the lebedev_laikov grid of index leb_idx
    2765              :  leb_idx=3; npts=lebedev_npts(leb_idx)
    2766              :  ABI_MALLOC(ref_func,(npts))
    2767              :  do ii=1,npts
    2768              :    !cart_vpt = Lgridset(leb_idx)%versor(:,ii)
    2769              :    ref_func(ii) = one/DOT_PRODUCT(cart_vpt,MATMUL(tensor,cart_vpt))
    2770              :  end do
    2771              : 
    2772              :  ! Calculate the expansion in angular momenta of 1/{q.Tq}.
    2773              :  ! Only even l-components contribute thanks to the parity of the integrand.
    2774              :  ! tol6 seems to be an acceptable error, convergence wrt lmax is very slow even for simple tensors.
    2775              :  ABI_MALLOC(expd_func,(npts))
    2776              :  expd_func=czero
    2777              :  lmax=10
    2778              :  do ll=0,lmax,2
    2779              :    !allocate(tmp_momenta(-ll:ll))
    2780              :    do mm=-ll,ll
    2781              :      ! MG: Commented because it causes problems with the new version of abilint
    2782              :      !call lebedev_quadrature(ylmstar_over_qTq,(/ll,mm/),real_pars,cplx_pars,ang_int,ierr,accuracy)
    2783              :      write(std_out,*)ll,mm,ang_int
    2784              :      !tmp_momenta(mm) = ang_int
    2785              :      do ii=1,npts
    2786              :        !cart_vpt = Lgridset(leb_idx)%versor(:,ii)
    2787              :        expd_func(ii) = expd_func(ii) + four_pi*ang_int*ylmc(ll,mm,cart_vpt)
    2788              :      end do
    2789              :    end do
    2790              :    !deallocate(tmp_momenta)
    2791              :    write(std_out,*)"Error in angular expansion at l=",ll," is ",MAXVAL(ABS(expd_func-ref_func))
    2792              :  end do
    2793              : 
    2794              : !BEGINDEBUG
    2795              : ! do ii=1,npts
    2796              : !   write(777,*)ref_func(ii)
    2797              : !   write(778,*)expd_func(ii)
    2798              : ! end do
    2799              : !ENDDEBUG
    2800              : 
    2801              :  ABI_FREE(expd_func)
    2802              :  ABI_FREE(ref_func)
    2803              : 
    2804              :  ABI_ERROR("Exiting from lebedev_laikov_int")
    2805              : 
    2806              : end subroutine lebedev_laikov_int
    2807              : !!***
    2808              : 
    2809              : !----------------------------------------------------------------------
    2810              : 
    2811              : !!****f* m_screening/ylmstar_over_qTq
    2812              : !! NAME
    2813              : !!  ylmstar_over_qTq
    2814              : !!
    2815              : !! FUNCTION
    2816              : !!  Return Ylm(q)^*/(q.Tq) where q is a versor in Cartesian coordinates.
    2817              : !!  and Ylm is a complex spherical Harmonics whose index (l,m) are
    2818              : !!  passed via int_pars(1:2). T is a tensore in Cartesian coordinates
    2819              : !!  passed via cplx_pars(1:9).
    2820              : !!
    2821              : !! INPUTS
    2822              : !!  cart_vers(3)=Cartesian components of the versor
    2823              : !!  int_pars(1:2)=(l,m) indices in Ylm. l>=0 and  m \in [-l,l]
    2824              : !!  cplx_pars(1:9)=Tensor T in Cartesian coordinates.
    2825              : !!  real_pars=Not used.
    2826              : !!
    2827              : !! OUTPUT
    2828              : !!  Value of Ylm(q)^*/(q.Tq)
    2829              : !!
    2830              : !! SOURCE
    2831              : 
    2832              : function ylmstar_over_qTq(cart_vers,int_pars,real_pars,cplx_pars)
    2833              : 
    2834              : !Arguments ------------------------------------
    2835              : !scalars
    2836              :  real(dp),intent(in) :: cart_vers(3)
    2837              :  integer,intent(in) :: int_pars(:)
    2838              :  real(dp),intent(in) :: real_pars(:)
    2839              :  complex(dp),intent(in) :: cplx_pars(:)
    2840              :  complex(dp) :: ylmstar_over_qTq
    2841              : !arrays
    2842              : 
    2843              : !Local variables-------------------------------
    2844              : !scalars
    2845              :  integer :: ll,mm
    2846              : !arrays
    2847              :  complex(dp) :: tensor(3,3)
    2848              : ! *************************************************************************
    2849              : 
    2850              :  tensor = RESHAPE(cplx_pars(1:9),(/3,3/))
    2851              :  ll = int_pars(1) ! ll starts from zero.
    2852              :  mm = int_pars(2) ! m \in [-l,l]
    2853              : 
    2854              :  ylmstar_over_qTq = CONJG(ylmc(ll,mm,cart_vers))/DOT_PRODUCT(cart_vers,MATMUL(tensor,cart_vers))
    2855              : 
    2856              :  RETURN
    2857              :  ABI_UNUSED(real_pars(1))
    2858              : 
    2859              : end function ylmstar_over_qTq
    2860              : !!***
    2861              : 
    2862              : !----------------------------------------------------------------------
    2863              : 
    2864              : !!****f* m_screening/ylmstar_wtq_over_qTq
    2865              : !! NAME
    2866              : !!  ylmstar_wtq_over_qTq
    2867              : !!
    2868              : !! FUNCTION
    2869              : !!  Return Ylm(q)^* weight(q)/(q.Tq) where q is a versor in Cartesian coordinates.
    2870              : !!  Ylm is a complex spherical Harmonics whose index (l,m) are
    2871              : !!  passed via int_pars(1:2). T is a tensor in Cartesian coordinates
    2872              : !!  passed via cplx_pars(1:9). weight(q) is the weighting function giving
    2873              : !!  the length of the vector parallel to versor q that connects the origin
    2874              : !!  of the lattice to one of the boundaries of the small cell centered at Gamma
    2875              : !!
    2876              : !! INPUTS
    2877              : !!  cart_vers(3)=Cartesian components of the versor
    2878              : !!  int_pars(1:2)=(l,m) indices in Ylm. l>=0 and  m \in [-l,l]
    2879              : !!  cplx_pars(1:9)=Tensor T in Cartesian coordinates.
    2880              : !!  real_pars(1:9)=The Cartesian vectors defining the small box centered around gamma point
    2881              : !!    when referred to this vectors the points in the box are given by {(x,y,z) | x,y,z \in [-1,1]}.
    2882              : !!
    2883              : !! OUTPUT
    2884              : !!  Value of Ylm(q)^* weigh(q)/(q.Tq)
    2885              : !!
    2886              : !! SOURCE
    2887              : 
    2888              : function ylmstar_wtq_over_qTq(cart_vers,int_pars,real_pars,cplx_pars)
    2889              : 
    2890              : !Arguments ------------------------------------
    2891              : !scalars
    2892              :  real(dp),intent(in) :: cart_vers(3)
    2893              :  integer,intent(in) :: int_pars(:)
    2894              :  real(dp),intent(in) :: real_pars(:)
    2895              :  complex(dp),intent(in) :: cplx_pars(:)
    2896              :  complex(dp) :: ylmstar_wtq_over_qTq
    2897              : !arrays
    2898              : 
    2899              : !Local variables-------------------------------
    2900              : !scalars
    2901              :  integer :: ll,mm
    2902              :  real(dp) :: wtq
    2903              : !arrays
    2904              :  real(dp) :: gprimd(3,3),rprimd(3,3),red_vers(3)
    2905              :  complex(dp) :: tensor(3,3)
    2906              : ! *************************************************************************
    2907              : 
    2908              :  ABI_ERROR("Work in progress")
    2909              :  ! box_len has to be tested
    2910              : 
    2911              :  gprimd = RESHAPE(real_pars(1:9),(/3,3/))
    2912              :  red_vers = MATMUL(rprimd,cart_vers)
    2913              :  wtq = box_len(red_vers,gprimd)
    2914              : 
    2915              :  tensor = RESHAPE(cplx_pars(1:9),(/3,3/))
    2916              :  ll = int_pars(1) ! true ll i.e. not shifted
    2917              :  mm = int_pars(2)
    2918              : 
    2919              :  ylmstar_wtq_over_qTq = CONJG(ylmc(ll,mm,cart_vers))*wtq/DOT_PRODUCT(cart_vers,MATMUL(tensor,cart_vers))
    2920              : 
    2921              : end function ylmstar_wtq_over_qTq
    2922              : !!***
    2923              : 
    2924              : !----------------------------------------------------------------------
    2925              : 
    2926              : !!****f* m_screening/mdielf_bechstedt
    2927              : !! NAME
    2928              : !!  mdielf_bechstedt
    2929              : !!
    2930              : !! FUNCTION
    2931              : !!  Calculates the model dielectric function for the homogeneous system
    2932              : !!  as proposed by F. Bechstedt, in Solid State Commun. 84, 765 1992.
    2933              : !!
    2934              : !! INPUTS
    2935              : !!  eps_inf=Dielectric constant of the material
    2936              : !!  qnrm=The modulus of the q-point.
    2937              : !!  rhor=The local value of the density
    2938              : !!
    2939              : !! SOURCE
    2940              : 
    2941    140216832 : elemental function mdielf_bechstedt(eps_inf, qnrm, rhor) result(mdielf)
    2942              : 
    2943              : !Arguments ------------------------------------
    2944              : !scalars
    2945              :  real(dp),intent(in) :: eps_inf,qnrm,rhor
    2946              :  real(dp) :: mdielf
    2947              : ! *************************************************************************
    2948              : 
    2949              :  mdielf = one + &
    2950    140216832 :           one / ( one/(eps_inf-one) + (qnrm/k_thfermi(rhor))**2 + (three*qnrm**4)/(four*k_fermi(rhor)**2 * k_thfermi(rhor)**2) )
    2951              : 
    2952    140216832 : end function mdielf_bechstedt
    2953              : !!***
    2954              : 
    2955              : !----------------------------------------------------------------------
    2956              : 
    2957              : !!****f* m_screening/screen_mdielf
    2958              : !! NAME
    2959              : !!  screen_mdielf
    2960              : !!
    2961              : !! FUNCTION
    2962              : !!  Calculates W_{G,G'}(q,w) for a given q-point in the BZ using a model dielectric function.
    2963              : !!
    2964              : !! INPUTS
    2965              : !!  iq_bz=The index of the q-point in the BZ where W(q) is calculated.
    2966              : !!  npw=Number of plane waves for W
    2967              : !!  nomega=Number of frequency points.
    2968              : !!  model_type=Flag defining the model.
    2969              : !!  eps_inf=Dielectric constant of the material.
    2970              : !!  Cryst<crystal_t>=Info on the unit cell
    2971              : !!  Qmesh<kmesh_t>=Info on the set of q-points.
    2972              : !!  Vcp<vcoul_t datatype>= containing information on the cutoff technique
    2973              : !!  Gsph<Gsphere>=The G-sphere for W.
    2974              : !!  nspden=Number of spin density components of the density.
    2975              : !!  nfft=Number of FFT points on the dense FFT mesh
    2976              : !!  ngfft(18)=contain all needed information about 3D FFT.
    2977              : !!  rhor(nfft,nspden)=Electron density in real space (The PAW AE term is included)
    2978              : !!  which= Set it to "EM1" if the symmetrized inverse dielectric matrix is wanted.
    2979              : !!   By default the routines returns W.
    2980              : !!  comm=MPI communicator.
    2981              : !!
    2982              : !! OUTPUT
    2983              : !!  w_qbz(npw,npw,nomega)
    2984              : !!
    2985              : !! NOTES
    2986              : !!   W_{G1,G2} =  1/2 {
    2987              : !!     v(q+G1) \int em1(|q+G1|,r) e^{-i(G1-G2).r} dr  +
    2988              : !!     v(q+G2) \int em1(|q+G2|,r) e^{-i(G1-G2).r} dr } / \Omega
    2989              : !!
    2990              : !! SOURCE
    2991              : 
    2992          631 : subroutine screen_mdielf(iq_bz,npw,nomega,model_type,eps_inf,Cryst,Qmesh,Vcp,Gsph,nspden,nfft,ngfft,rhor,which,w_qbz,comm)
    2993              : 
    2994              : !Arguments ------------------------------------
    2995              : !scalars
    2996              :  integer,intent(in) :: npw,nomega,nfft,nspden,iq_bz,comm,model_type
    2997              :  real(dp),intent(in) :: eps_inf
    2998              :  character(len=*),intent(in) :: which
    2999              :  type(kmesh_t),intent(in) :: Qmesh
    3000              :  type(crystal_t),intent(in) :: Cryst
    3001              :  type(vcoul_t),target,intent(in) :: Vcp
    3002              :  type(gsphere_t),intent(in) :: Gsph
    3003              : !arrays
    3004              :  integer,intent(in) :: ngfft(18)
    3005              :  real(dp),intent(in) :: rhor(nfft,nspden)
    3006              :  complex(gwp),intent(out) :: w_qbz(npw,npw,nomega)
    3007              : 
    3008              : !Local variables-------------------------------
    3009              : !scalars
    3010              :  integer,parameter :: tim_fourdp0=0,paral_kgb0=0,cplex1=1
    3011              :  integer :: my_gstart,my_gstop,iq_ibz,ig,itim_q,isym_q
    3012              :  integer :: ig1,ig2,g1mg2_fft,iw,ii,ierr,nprocs,isg,ifft !,row ,col
    3013              :  real(dp) :: qpg2_nrm
    3014              :  complex(dp) :: ph_mqbzt
    3015              :  logical :: is_qeq0,isirred
    3016              :  !character(len=500) :: msg
    3017          631 :  type(MPI_type) :: MPI_enreg_seq
    3018              : !arrays
    3019              :  integer :: umklp(3)
    3020          631 :  integer,allocatable :: igfft(:),g1mg2(:,:)
    3021              :  real(dp) :: qpg2(3),qpt_bz(3)
    3022          631 :  real(dp),allocatable :: em1_qpg2r(:),fofg(:,:)
    3023          631 :  complex(gwp),contiguous, pointer :: vc_sqrt_ibz(:)
    3024          631 :  complex(gwp),allocatable :: vc_qbz(:),ctmp(:,:)
    3025          631 :  logical,allocatable :: mask(:)
    3026              : ! *************************************************************************
    3027              : 
    3028            0 :  ABI_CHECK(nomega==1,"screen_mdielf does not support nomega>1")
    3029              : 
    3030              :  ! Fake MPI_type for the sequential part.
    3031          631 :  call initmpi_seq(MPI_enreg_seq)
    3032          631 :  call MPI_enreg_seq%distribfft%init_seq('c',ngfft(2),ngfft(3),'all')
    3033              : 
    3034          631 :  nprocs = xmpi_comm_size(comm)
    3035          631 :  call xmpi_split_work(npw,comm,my_gstart,my_gstop)
    3036              : 
    3037          631 :  call qmesh%get_bz_item(iq_bz,qpt_bz,iq_ibz,isym_q,itim_q,ph_mqbzt,umklp,isirred)
    3038              : 
    3039              :  !if (itim_q/=1.or.isym_q/=1.or.ANY(umklp/=0) ) then
    3040              :  !  ABI_ERROR("Bug in mdielf_bechstedt")
    3041              :  !end if
    3042              :  !
    3043              :  ! Symmetrize Vc in the full BZ.
    3044          631 :  is_qeq0 = (normv(qpt_bz,Cryst%gmet,'G')<GW_TOLQ0) ! Check if q==0
    3045          631 :  if (is_qeq0) then
    3046           49 :    vc_sqrt_ibz => Vcp%vcqlwl_sqrt(:,1)  ! Use Coulomb term for q-->0, only first Q is used, shall we average if nqlwl>1?
    3047              :  else
    3048          582 :    vc_sqrt_ibz => Vcp%vc_sqrt(:,iq_ibz)
    3049              :  end if
    3050              : 
    3051         1893 :  ABI_MALLOC(vc_qbz,(npw))
    3052        33260 :  do ig=1,npw
    3053        32629 :    isg = Gsph%rottb(ig,itim_q,isym_q)
    3054        33260 :    vc_qbz(isg) = vc_sqrt_ibz(ig)**2
    3055              :  end do
    3056              : 
    3057         1893 :  ABI_MALLOC(igfft,(npw))
    3058         1893 :  ABI_MALLOC(g1mg2,(3,npw))
    3059         1893 :  ABI_MALLOC(fofg,(2,nfft))
    3060         1893 :  ABI_MALLOC(em1_qpg2r,(nfft))
    3061         1262 :  ABI_MALLOC(mask,(npw))
    3062              : 
    3063      1724402 :  w_qbz=czero
    3064        31372 :  do ig2=my_gstart,my_gstop
    3065              :    !
    3066              :    ! Compute the index of G-G2 wave in the FFT grid.
    3067      1609860 :    do ii=1,npw
    3068      6347217 :      g1mg2(:,ii) = Gsph%gvec(:,ii) - Gsph%gvec(:,ig2)
    3069              :    end do
    3070        30741 :    call kgindex(igfft,g1mg2,mask,MPI_enreg_seq,ngfft,npw)
    3071              : 
    3072              :    ! TODO can use zero-padding FFT to speed up the transform.
    3073              :    !call sphereboundary(gbound,istwfk1,g1mg2,mgfft,npw)
    3074              : 
    3075              :    ! Evaluate em1_qpg2r = \int em1(|q+G2|,r) e^{-i(G1-G2).r} dr }.
    3076       122964 :    qpg2 = qpt_bz + Gsph%gvec(:,ig2)
    3077        30741 :    qpg2_nrm = normv(qpg2,Cryst%gmet,"G")
    3078              : 
    3079        62113 :    do iw=1,nomega
    3080              :      !
    3081        30741 :      select case (model_type)
    3082              :      case (1)
    3083    140247573 :        do ifft=1,nfft
    3084    140247573 :          em1_qpg2r(ifft) = one / mdielf_bechstedt(eps_inf,qpg2_nrm,rhor(ifft,1))
    3085              :        end do
    3086              :      case default
    3087        30741 :        ABI_ERROR(sjoin("Unknown model_type:",itoa(model_type)))
    3088              :      end select
    3089              : 
    3090        30741 :      call fourdp(cplex1,fofg,em1_qpg2r,-1,MPI_enreg_seq,nfft,1,ngfft,tim_fourdp0)
    3091              :      !
    3092              :      ! Here, unlike the other parts of the code, the unsymmetrized e^{-1} is used.
    3093      1640601 :      do ig1=1,npw
    3094      1579119 :        g1mg2_fft = igfft(ig1)
    3095      1609860 :        w_qbz(ig1,ig2,iw) = DCMPLX(fofg(1,g1mg2_fft), fofg(2,g1mg2_fft)) * vc_qbz(ig2) !/ Cryst%ucvol
    3096              :      end do
    3097              :    end do ! iw
    3098              :  end do ! ig2
    3099              : 
    3100          631 :  ABI_FREE(em1_qpg2r)
    3101          631 :  ABI_FREE(fofg)
    3102          631 :  ABI_FREE(igfft)
    3103          631 :  ABI_FREE(g1mg2)
    3104          631 :  ABI_FREE(mask)
    3105              :  !
    3106              :  ! W = 1/2 * (A + A^H)
    3107              :  ! The MPI sum is done inside the loop to avoid problems with the size of the packet.
    3108         2524 :  ABI_MALLOC_OR_DIE(ctmp,(npw,npw), ierr)
    3109              : 
    3110         1262 :  do iw=1,nomega
    3111              :    !ctmp = TRANSPOSE(CONJG(w_qbz(:,:,iw)))
    3112      1724402 :    ctmp = GWPC_CONJG(w_qbz(:,:,iw))
    3113          631 :    call sqmat_itranspose(npw,ctmp)
    3114      1723771 :    w_qbz(:,:,iw) = half * (ctmp + w_qbz(:,:,iw))
    3115         1262 :    call xmpi_sum(w_qbz(:,:,iw),comm,ierr)
    3116              :  end do
    3117              :  !
    3118              :  ! Calculate the symmetrized Em1. W = vc(G1)^{1/2} \tilde Em1 vc(G2)^{1/2} -------------------------
    3119          631 :  if (toupper(which)=="EM1") then
    3120        33260 :    do ig=1,npw
    3121        32629 :      isg = Gsph%rottb(ig,itim_q,isym_q)
    3122        33260 :      vc_qbz(isg) = vc_sqrt_ibz(ig)  ! Workspace storing vc*{1/2}(q_BZ,G).
    3123              :    end do
    3124              : 
    3125        33260 :    do ig2=1,npw
    3126      1723771 :      do ig1=1,npw
    3127      1723140 :        ctmp(ig1,ig2) =  one / (vc_qbz(ig1) * vc_qbz(ig2))
    3128              :      end do
    3129              :    end do
    3130              : 
    3131         1893 :    do iw=1,nomega
    3132      1724402 :      w_qbz(:,:,iw) = w_qbz(:,:,iw) * ctmp(:,:)
    3133              :    end do
    3134              :  end if
    3135              : 
    3136          631 :  call destroy_mpi_enreg(MPI_enreg_seq)
    3137              : 
    3138          631 :  ABI_FREE(vc_qbz)
    3139          631 :  ABI_SFREE(ctmp)
    3140              : 
    3141         1893 : end subroutine screen_mdielf
    3142              : !!***
    3143              : 
    3144              : !----------------------------------------------------------------------
    3145              : 
    3146              : !!****f* m_screening/chi_new
    3147              : !! NAME
    3148              : !! chi_new
    3149              : !!
    3150              : !! FUNCTION
    3151              : !!
    3152              : !! INPUTS
    3153              : !!
    3154              : !! OUTPUT
    3155              : !!
    3156              : !! SOURCE
    3157              : 
    3158            0 : type(chi_t) function chi_new(npwe, nomega) result(chi)
    3159              : 
    3160              : !Arguments ------------------------------------
    3161              :  integer,intent(in) :: npwe,nomega
    3162              : ! *************************************************************************
    3163              : 
    3164            0 :  chi%nomega = nomega; chi%npwe = npwe
    3165              : 
    3166            0 :  ABI_MALLOC(chi%mat, (npwe,npwe,nomega))
    3167              : 
    3168            0 :  ABI_MALLOC(chi%head, (3,3,nomega))
    3169            0 :  ABI_MALLOC(chi%lwing, (npwe, nomega,3))
    3170            0 :  ABI_MALLOC(chi%uwing, (npwe, nomega,3))
    3171              : 
    3172            0 : end function chi_new
    3173              : !!***
    3174              : 
    3175              : !----------------------------------------------------------------------
    3176              : 
    3177              : !!****f* m_screening/chi_free
    3178              : !! NAME
    3179              : !! chi_free
    3180              : !!
    3181              : !! FUNCTION
    3182              : !!
    3183              : !! INPUTS
    3184              : !!
    3185              : !! OUTPUT
    3186              : !!
    3187              : !! SOURCE
    3188              : 
    3189            0 : subroutine chi_free(chi)
    3190              : 
    3191              : !Arguments ------------------------------------
    3192              : !scalars
    3193              :  class(chi_t),intent(inout) :: chi
    3194              : ! *************************************************************************
    3195              : 
    3196            0 :  ABI_SFREE(chi%mat)
    3197            0 :  ABI_SFREE(chi%head)
    3198            0 :  ABI_SFREE(chi%lwing)
    3199            0 :  ABI_SFREE(chi%uwing)
    3200              : 
    3201            0 : end subroutine chi_free
    3202              : !!***
    3203              : 
    3204              : !----------------------------------------------------------------------
    3205              : 
    3206              : !!****f* m_screening/lwl_write
    3207              : !! NAME
    3208              : !! lwl_write
    3209              : !!
    3210              : !! FUNCTION
    3211              : !!
    3212              : !! INPUTS
    3213              : !!
    3214              : !! OUTPUT
    3215              : !!
    3216              : !! SOURCE
    3217              : 
    3218            0 : subroutine lwl_write(path, cryst, vcp, npwe, nomega, gvec, chi0, chi0_head, chi0_lwing, chi0_uwing, comm)
    3219              : 
    3220              : !Arguments ------------------------------------
    3221              : !scalars
    3222              :  integer,intent(in) :: npwe,nomega,comm
    3223              :  character(len=*),intent(in) :: path
    3224              :  type(crystal_t),intent(in) :: cryst
    3225              :  type(vcoul_t),intent(in) :: Vcp
    3226              : !arrays
    3227              :  integer,intent(in) :: gvec(3,npwe)
    3228              :  complex(gwp),intent(in) :: chi0(npwe,npwe,nomega)
    3229              :  complex(dp),intent(inout)  :: chi0_head(3,3,nomega),chi0_lwing(npwe,nomega,3),chi0_uwing(npwe,nomega,3)
    3230              : 
    3231              : !Local variables-------------------------------
    3232              : !scalars
    3233              :  integer,parameter :: master=0,prtvol=0
    3234              :  integer :: iw,ii,iomode,unt,my_rank
    3235              :  character(len=500) :: msg
    3236              :  real(dp) :: length
    3237              :  complex(dp) :: wng(3),em1_00
    3238              : ! type(hscr_t),intent(out) :: hscr
    3239              : !arrays
    3240            0 :  complex(dp),allocatable :: wtest(:),eps_head(:,:,:)
    3241              : ! *************************************************************************
    3242              : 
    3243              :  !if (xmpi_comm_rank(comm) /= master) goto 100
    3244            0 :  my_rank = xmpi_comm_rank(comm)
    3245              : 
    3246            0 :  ABI_MALLOC(wtest,(npwe))
    3247              : 
    3248              :  if (prtvol > 0 .and. my_rank == master) then
    3249              :    call wrtout(std_out, "head of chi0")
    3250              :    do iw=1,nomega
    3251              :      call print_arr([std_out], chi0_head(:,:,iw), max_r=3, max_c=3)
    3252              :    end do
    3253              : 
    3254              :    do iw=1,nomega
    3255              :      call wrtout(std_out, "symmetrized e_00 via tensor")
    3256              :      wng = MATMUL(chi0_head(:,:,iw),GW_Q0_DEFAULT)
    3257              :      write(std_out,*) one - vdotw(GW_Q0_DEFAULT,wng,cryst%gmet,"G") * Vcp%vcqlwl_sqrt(1,1)*Vcp%vcqlwl_sqrt(1,1)
    3258              : 
    3259              :      call wrtout(std_out, "symmetrized e_0G via tensor")
    3260              :      do ii=1,npwe
    3261              :        wng = chi0_uwing(ii,iw,:)
    3262              :        wtest(ii) = - vdotw(GW_Q0_DEFAULT,wng,cryst%gmet,"G") * Vcp%vcqlwl_sqrt(1,1) * Vcp%vcqlwl_sqrt(ii,1)
    3263              :      end do
    3264              :      call print_arr([std_out], wtest,max_r=9)
    3265              : 
    3266              :      call wrtout(std_out, "symmetrized e_G0 via tensor")
    3267              :      do ii=1,npwe
    3268              :        wng = chi0_lwing(ii,iw,:)
    3269              :        wtest(ii) = - vdotw(GW_Q0_DEFAULT,wng,cryst%gmet,"G") * Vcp%vcqlwl_sqrt(1,1) * Vcp%vcqlwl_sqrt(ii,1)
    3270              :      end do
    3271              :      call print_arr([std_out], wtest,max_r=9)
    3272              :    end do
    3273              :  end if
    3274              : 
    3275              :  ! Write chi0 data
    3276            0 :  iomode = IO_MODE_FORTRAN; if (endswith(path, ".nc")) iomode = IO_MODE_ETSF
    3277              : 
    3278            0 :  if (my_rank == master) then
    3279            0 :    if (iomode == IO_MODE_FORTRAN) then
    3280            0 :      if (open_file(path,msg,newunit=unt,form="unformatted", action="write") /= 0) then
    3281            0 :        ABI_ERROR(msg)
    3282              :      end if
    3283              :      !call epsm1%hscr%io(fform,rdwr,unt,comm,master,iomode)
    3284            0 :      do iw=1,nomega
    3285            0 :        write(unt)chi0_head(:,:,iw)
    3286              :      end do
    3287              :      !do iw=1,nomega
    3288              :      !  write(unt)chi0_lwing(:,iw,:)
    3289              :      !end do
    3290              :      !do iw=1,nomega
    3291              :      !  write(unt)chi0_uwing(:,iw,:)
    3292              :      !end do
    3293              : 
    3294              :    else
    3295            0 :      ABI_ERROR(sjoin("iomode", itoa(iomode), "is not supported"))
    3296              :    end if
    3297              :  end if
    3298              : 
    3299            0 :  ABI_MALLOC(eps_head,(3,3,nomega))
    3300            0 :  call mkem1_q0(npwe,1,1,nomega,cryst,Vcp,gvec,chi0_head,chi0_lwing,chi0_uwing,chi0,eps_head,comm)
    3301              : 
    3302            0 :  if (my_rank == master) then
    3303            0 :    if (iomode == IO_MODE_FORTRAN) then
    3304            0 :      do iw=1,nomega
    3305            0 :        write(unt)eps_head(:,:,iw)
    3306              :      end do
    3307              :      !do iw=1,nomega
    3308              :      !  write(unt)chi0_lwing(:,iw,:)
    3309              :      !end do
    3310              :      !do iw=1,nomega
    3311              :      !  write(unt)chi0_uwing(:,iw,:)
    3312              :      !end do
    3313              :    else
    3314            0 :      ABI_ERROR(sjoin("iomode:", itoa(iomode), "is not supported"))
    3315              :    end if
    3316              :  end if
    3317              : 
    3318            0 :  ABI_FREE(eps_head)
    3319              : 
    3320              :  if (prtvol > 0 .and. my_rank == master) then
    3321              :    length = normv(GW_Q0_DEFAULT,cryst%gmet,"G")
    3322              : 
    3323              :    do iw=1,nomega
    3324              :      em1_00 = one / vdotw(GW_Q0_DEFAULT/length, MATMUL(chi0_head(:,:,iw),GW_Q0_DEFAULT/length),cryst%gmet,"G")
    3325              :      call wrtout(std_out, "e^1_{00} from tensor")
    3326              :      write(std_out,*) em1_00
    3327              : 
    3328              :      call wrtout(std_out, "symmetrized e^-1_0G via tensor")
    3329              :      do ii=1,npwe
    3330              :        wng = chi0_uwing(ii,iw,:)
    3331              :        wtest(ii) = em1_00*vdotw(GW_Q0_DEFAULT/length,wng,cryst%gmet,"G")
    3332              :      end do
    3333              :      wtest(1) = em1_00
    3334              :      call print_arr([std_out], wtest,max_r=9)
    3335              : 
    3336              :      call wrtout(std_out, "symmetrized e^-1_G0 via tensor")
    3337              :      do ii=1,npwe
    3338              :        wng = chi0_lwing(ii,iw,:)
    3339              :        wtest(ii) = em1_00*vdotw(GW_Q0_DEFAULT/length,wng,cryst%gmet,"G")
    3340              :      end do
    3341              :      wtest(1) = em1_00
    3342              :      call print_arr([std_out], wtest,max_r=9)
    3343              :    end do !iw
    3344              :  end if
    3345              : 
    3346            0 :  ABI_FREE(wtest)
    3347              : 
    3348            0 :  if (my_rank == master) then
    3349            0 :    if (iomode == IO_MODE_FORTRAN) then
    3350            0 :      close(unt)
    3351              :    else
    3352            0 :      NCF_CHECK(nf90_close(unt))
    3353              :    end if
    3354              :  end if
    3355              : 
    3356              : !100 call xmpi_barrier(comm)
    3357              : 
    3358            0 : end subroutine lwl_write
    3359              : !!***
    3360              : 
    3361              : !----------------------------------------------------------------------
    3362              : 
    3363              : !!****f* m_screening/lwl_init
    3364              : !! NAME
    3365              : !! lwl_init
    3366              : !!
    3367              : !! FUNCTION
    3368              : !!
    3369              : !! INPUTS
    3370              : !!
    3371              : !! OUTPUT
    3372              : !!
    3373              : !! SOURCE
    3374              : 
    3375            0 : subroutine lwl_init(lwl, path, method, cryst, vcp, npwe, gvec, comm)
    3376              : 
    3377              : !Arguments ------------------------------------
    3378              : !scalars
    3379              :  integer,intent(in) :: comm,method,npwe
    3380              :  character(len=*),intent(in) :: path
    3381              :  type(crystal_t),intent(in) :: cryst
    3382              :  type(vcoul_t),intent(in) :: vcp
    3383              :  type(lwl_t),intent(out) :: lwl
    3384              : !arrays
    3385              :  integer,intent(in) :: gvec(3,npwe)
    3386              : 
    3387              : !Local variables-------------------------------
    3388              : !scalars
    3389              :  integer,parameter :: master=0
    3390              :  integer :: iomode,my_rank,nproc,unt
    3391              :  character(len=500) :: msg
    3392              : ! *************************************************************************
    3393              : 
    3394              :  ABI_UNUSED((/cryst%natom, gvec(1,1), vcp%ng/))
    3395              : 
    3396            0 :  my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
    3397              : 
    3398            0 :  lwl%fname = path
    3399            0 :  lwl%method = method
    3400            0 :  ABI_CHECK(any(method == [1,2,3]), sjoin("Wrong method:", itoa(method)))
    3401              : 
    3402            0 :  iomode = IO_MODE_FORTRAN; if (endswith(path, ".nc")) iomode = IO_MODE_ETSF
    3403              : 
    3404              :  ! Only master reads.
    3405            0 :  if (my_rank == master) then
    3406              : 
    3407            0 :    select case (iomode)
    3408              :    case (IO_MODE_FORTRAN)
    3409            0 :      if (open_file(path, msg, newunit=unt, action="read", form="unformatted", status="old") /= 0) then
    3410            0 :        ABI_ERROR(msg)
    3411              :      end if
    3412              : 
    3413            0 :      close(unt)
    3414              : 
    3415              :    case default
    3416            0 :      ABI_ERROR(sjoin("iomode:", itoa(iomode), "is not coded"))
    3417              :    end select
    3418              :  end if
    3419              : 
    3420              :  ! Broad cast data
    3421              :  if (nproc > 1) then
    3422              :  end if
    3423              : 
    3424            0 : end subroutine lwl_init
    3425              : !!***
    3426              : 
    3427              : !----------------------------------------------------------------------
    3428              : 
    3429              : !!****f* m_screening/lwl_free
    3430              : !! NAME
    3431              : !! lwl_free
    3432              : !!
    3433              : !! FUNCTION
    3434              : !!
    3435              : !! INPUTS
    3436              : !!
    3437              : !! OUTPUT
    3438              : !!
    3439              : !! SOURCE
    3440              : 
    3441            0 : subroutine lwl_free(lwl)
    3442              : 
    3443              : !Arguments ------------------------------------
    3444              : !scalars
    3445              :  type(lwl_t),intent(inout) :: lwl
    3446              : ! *************************************************************************
    3447              : 
    3448            0 :  ABI_SFREE(lwl%head)
    3449            0 :  ABI_SFREE(lwl%lwing)
    3450            0 :  ABI_SFREE(lwl%uwing)
    3451            0 :  ABI_SFREE(lwl%body)
    3452              : 
    3453            0 : end subroutine lwl_free
    3454              : !!***
    3455              : 
    3456            0 : end module m_screening
    3457              : !!***
        

Generated by: LCOV version 2.3-1