LCOV - code coverage report
Current view: top level - src/70_gw - m_ppmodel.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 64.6 % 763 493
Test Date: 2026-11-06 12:58:16 Functions: 66.7 % 21 14
Branches: 44.9 % 1855 833

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_ppmodel
       2                 :             : !! NAME
       3                 :             : !! m_ppmodel
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  Module containing the definition of the ppmodel_t used to deal with the plasmonpole technique.
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 2008-2026 ABINIT group (MG, GMR, VO, LR, RWG, RS)
      10                 :             : !!  This file is distributed under the terms of the
      11                 :             : !!  GNU General Public License, see ~abinit/COPYING
      12                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13                 :             : !!
      14                 :             : !! SOURCE
      15                 :             : 
      16                 :             : #if defined HAVE_CONFIG_H
      17                 :             : #include "config.h"
      18                 :             : #endif
      19                 :             : 
      20                 :             : #include "abi_common.h"
      21                 :             : 
      22                 :             : module m_ppmodel
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use m_errors
      26                 :             :  use m_abicore
      27                 :             :  use m_array
      28                 :             :  use m_linalg_interfaces
      29                 :             :  use m_distribfft
      30                 :             :  use m_yaml
      31                 :             : 
      32                 :             :  use defs_abitypes,    only : MPI_type
      33                 :             :  use m_fstrings,       only : sjoin, itoa, ktoa
      34                 :             :  use m_hide_lapack,    only : xhegv
      35                 :             :  use m_gwdefs,         only : GW_Q0_DEFAULT, czero_gw
      36                 :             :  use m_crystal,        only : crystal_t
      37                 :             :  use m_bz_mesh,        only : kmesh_t
      38                 :             :  use m_gsphere,        only : gsphere_t
      39                 :             :  use m_vcoul,          only : vcoul_t
      40                 :             :  use m_qplusg,         only : cmod_qpg
      41                 :             :  use m_fft_mesh,       only : g2ifft
      42                 :             :  use m_fft,            only : fourdp
      43                 :             :  use m_mpinfo,         only : destroy_mpi_enreg, initmpi_seq
      44                 :             :  use m_pstat,          only : pstat_proc
      45                 :             : 
      46                 :             :  implicit none
      47                 :             : 
      48                 :             :  private
      49                 :             : !!***
      50                 :             : 
      51                 :             :  integer,public,parameter :: PPM_NONE            = 0
      52                 :             :  integer,public,parameter :: PPM_GODBY_NEEDS     = 1
      53                 :             :  integer,public,parameter :: PPM_HYBERTSEN_LOUIE = 2
      54                 :             :  integer,public,parameter :: PPM_LINDEN_HORSH    = 3
      55                 :             :  integer,public,parameter :: PPM_ENGEL_FARID     = 4
      56                 :             : 
      57                 :             :  ! Flags giving the status of the plasmon-pole tables
      58                 :             :  integer,public,parameter :: PPM_NOTAB         = 0
      59                 :             :  integer,public,parameter :: PPM_TAB_ALLOCATED = 1
      60                 :             :  integer,public,parameter :: PPM_TAB_STORED    = 2
      61                 :             : 
      62                 :             : !----------------------------------------------------------------------
      63                 :             : 
      64                 :             : !!****t* m_ppmodel/ppmodel_t
      65                 :             : !! NAME
      66                 :             : !! ppmodel_t
      67                 :             : !!
      68                 :             : !! FUNCTION
      69                 :             : !!  This datatype gathers all the information on the Plasmonpole technique used in the calculations
      70                 :             : !!
      71                 :             : !! SOURCE
      72                 :             : 
      73                 :             :  type,public :: ppmodel_t
      74                 :             : 
      75                 :             :    integer :: dm2_botsq
      76                 :             :    ! =npwc if ppmodel=1,2
      77                 :             :    ! =1    if ppmodel=3,4
      78                 :             : 
      79                 :             :    integer :: dm_eig
      80                 :             :    ! =0    if ppmodel=1,2,4
      81                 :             :    ! =npwc if ppmodel=3
      82                 :             : 
      83                 :             :    integer :: dm2_otq
      84                 :             :    ! =npwc if ppmodel=1,2
      85                 :             :    ! =1    if ppmodel=3,4
      86                 :             : 
      87                 :             :    integer :: invalid_freq
      88                 :             :    ! what to do when PPM frequencies are invalid.
      89                 :             : 
      90                 :             :    integer :: model
      91                 :             :    ! The type of Plasmonpole model.
      92                 :             : 
      93                 :             :    integer :: mqmem
      94                 :             :    ! =nqibz if in-core solution.
      95                 :             :    ! =0 for out-of-core for which the last dimension in the ppm arrays has size 1.
      96                 :             : 
      97                 :             :    integer :: nqibz
      98                 :             :    ! Number of q-points in the IBZ
      99                 :             : 
     100                 :             :    integer :: npwc
     101                 :             :    ! Number of G vectors in $\tilde \epsilon $
     102                 :             : 
     103                 :             :    integer :: userho
     104                 :             :    ! 1 if the ppmodel requires rho(G).
     105                 :             : 
     106                 :             :    integer :: iq_bz = 0
     107                 :             :    ! The index of the q-point in the BZ that is referenced by the internal pointer.
     108                 :             :    ! when we perform a symmetrization from the IBZ to the BZ.
     109                 :             : 
     110                 :             :    real(dp) :: drude_plsmf
     111                 :             :    ! Drude plasma frequency
     112                 :             : 
     113                 :             :    real(dp) :: force_plsmf = zero
     114                 :             :    ! Force plasma frequency to that set by ppmfreq (not used if set zero).
     115                 :             : 
     116                 :             :    ! arrays
     117                 :             :    logical,allocatable :: keep_qibz(:)
     118                 :             :    ! (nqibz)
     119                 :             :    ! .TRUE. if the ppmodel tables for this q in the IBZ are kept in memory.
     120                 :             : 
     121                 :             :    integer,allocatable :: has_qibz(:)
     122                 :             :    ! Flag defining the status of the tables for the different q. See the PPM_TAB flags.
     123                 :             : 
     124                 :             :    complex(gwp),allocatable :: bigomegatwsq_qbz_vals(:,:)
     125                 :             :    ! (Points|Stores) the symmetrized plasmon pole parameters $\tilde\Omega^2_{G Gp}(q_bz)$.
     126                 :             : 
     127                 :             :    complex(gwp),allocatable :: omegatw_qbz_vals(:,:)
     128                 :             :    ! (Points|Stores) the symmetrized plasmon pole parameters $\tilde\omega_{G Gp}(q_bz)$.
     129                 :             : 
     130                 :             :    complex(gwp),allocatable :: eigpot_qbz_vals(:,:)
     131                 :             :    ! (Points|Stores) the eigvectors of the symmetrized inverse dielectric matrix.
     132                 :             : 
     133                 :             :    type(array2_gwpc_t),allocatable :: bigomegatwsq(:)
     134                 :             :    ! (nqibz)%value(npwc,dm2_botsq)
     135                 :             :    ! Plasmon pole parameters $\tilde\Omega^2_{G Gp}(q)$.
     136                 :             : 
     137                 :             :    type(array2_gwpc_t),allocatable :: omegatw(:)
     138                 :             :    ! (nqibz)%value(npwc,dm2_otq)
     139                 :             :    ! Plasmon pole parameters $\tilde\omega_{G Gp}(q)$.
     140                 :             : 
     141                 :             :    type(array2_gwpc_t),allocatable :: eigpot(:)
     142                 :             :    ! (nqibz)%value(dm_eig,dm_eig)
     143                 :             :    ! Eigvectors of the symmetrized inverse dielectric matrix.
     144                 :             : 
     145                 :             : contains
     146                 :             : 
     147                 :             :    procedure :: get_qbz => ppm_get_qbz
     148                 :             :      ! Symmetrize the ppm parameters in the BZ.
     149                 :             : 
     150                 :             :    procedure :: init => ppm_init
     151                 :             :      ! Initialize dimensions and pointers
     152                 :             : 
     153                 :             :    procedure :: free => ppm_free
     154                 :             :      ! Free dynamic memory.
     155                 :             : 
     156                 :             :    procedure :: setup => ppm_setup
     157                 :             :      ! Main Driver
     158                 :             : 
     159                 :             :    procedure :: new_setup => ppm_new_setup
     160                 :             :      ! New Main Driver
     161                 :             : 
     162                 :             :    procedure :: print => ppm_print
     163                 :             :      ! Print info on object
     164                 :             : 
     165                 :             :    procedure :: calc_sigc => ppm_calc_sigc
     166                 :             :      ! Matrix elements of the correlated self-energy with ppmodel.
     167                 :             : 
     168                 :             :    procedure :: calc_dsigc => ppm_calc_dsigc
     169                 :             :      ! Frequency derivative of the above (double-pole term for GWPT at q=Gamma).
     170                 :             : 
     171                 :             :    procedure :: rotate_iqbz => ppm_rotate_iqbz
     172                 :             : 
     173                 :             :    procedure :: malloc_iqibz => ppm_malloc_iqibz
     174                 :             : 
     175                 :             :    procedure :: table_free_iqibz => ppm_table_free_iqibz
     176                 :             : 
     177                 :             :    procedure :: get_eigenvalues => ppm_get_eigenvalues
     178                 :             : 
     179                 :             :    procedure :: getem1 => ppm_getem1
     180                 :             :      ! Reconstruct e^{-1}(w) from ppm.
     181                 :             : 
     182                 :             :    procedure :: getem1_one_ggp => ppm_getem1_one_ggp
     183                 :             :      ! Reconstruct e^{-1}(w) from ppm for one (G,G') pair
     184                 :             : 
     185                 :             :  end type ppmodel_t
     186                 :             : 
     187                 :             :  public :: cqratio
     188                 :             : !!***
     189                 :             : 
     190                 :             : contains
     191                 :             : !!***
     192                 :             : 
     193                 :             : !!****f* m_ppmodel/ppm_get_qbz
     194                 :             : !! NAME
     195                 :             : !!  ppm_get_qbz
     196                 :             : !!
     197                 :             : !! FUNCTION
     198                 :             : !!  Compute plasmon-pole matrix elements for q in the BZ from the symmetrical image in the IBZ
     199                 :             : !!
     200                 :             : !! INPUTS
     201                 :             : !!  Gsph<gsphere_t>=data related to the G-sphere
     202                 :             : !!  Qmesh<kmesh_t>=Info on the q-mesh
     203                 :             : !!  iq_bz=Index of the q-point in the BZ where ppmodel parameters have to be symmetrized
     204                 :             : !!
     205                 :             : !! OUTPUT
     206                 :             : !!  botsq
     207                 :             : !!  otq
     208                 :             : !!  eig (only if ppm%ppmodel==3)
     209                 :             : !!
     210                 :             : !! NOTES
     211                 :             : !!  In the present implementation we are not considering a possible umklapp vector G0.
     212                 :             : !!  In this case,indeed, the equation is different since we have to consider G-G0.
     213                 :             : !!  There is however a check in sigma
     214                 :             : !!
     215                 :             : !!  * Remember the symmetry properties of \tilde\espilon^{-1}
     216                 :             : !!
     217                 :             : !!    If q_bz=Sq_ibz+G0:
     218                 :             : !!
     219                 :             : !!      $\epsilon^{-1}_{SG1-G0,SG2-G0}(q_bz) = e^{+iS(G2-G1).\tau}\epsilon^{-1}_{G1,G2)}(q)
     220                 :             : !!
     221                 :             : !!    If time-reversal symmetry can be used then:
     222                 :             : !!
     223                 :             : !!       $\epsilon^{-1}_{G1,G2}(-q_bz) = e^{+i(G1-G2).\tau}\epsilon^{-1}_{-S^{-1}(G1+Go),-S^{-1}(G2+G0)}^*(q)
     224                 :             : !!
     225                 :             : !! * Note that eig is used only if ppm%model==3
     226                 :             : !!
     227                 :             : !! SOURCE
     228                 :             : 
     229                 :       14848 : subroutine ppm_get_qbz(ppm, Gsph, Qmesh, iq_bz, botsq, otq, eig)
     230                 :             : 
     231                 :             : !Arguments ------------------------------------
     232                 :             : !scalars
     233                 :             :  class(ppmodel_t),target,intent(inout) :: ppm
     234                 :             :  integer,intent(in) :: iq_bz
     235                 :             :  type(gsphere_t),target,intent(in) :: Gsph
     236                 :             :  type(kmesh_t),intent(in) :: Qmesh
     237                 :             :  complex(gwp),allocatable,intent(out) :: botsq(:,:),otq(:,:),eig(:,:)
     238                 :             : 
     239                 :             : !Local variables-------------------------------
     240                 :             : !scalars
     241                 :             :  integer :: ii,jj,iq_ibz,itim_q,isym_q,iq_curr,isg1,isg2
     242                 :             : !arrays
     243                 :       14848 :  integer, contiguous, pointer :: grottb(:)
     244                 :       14848 :  complex(gwp),contiguous, pointer :: phsgt(:),bigomegatwsq(:,:),omegatw(:,:)
     245                 :             : ! *********************************************************************
     246                 :             : 
     247                 :             :  ! Save the index of the q-point for checking purpose.
     248                 :       14848 :  ppm%iq_bz = iq_bz
     249                 :             : 
     250   [ +  -  -  +  :       59392 :  ABI_MALLOC(botsq, (ppm%npwc, ppm%dm2_botsq))
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
     251   [ -  +  +  -  :       59392 :  ABI_MALLOC(otq, (ppm%npwc, ppm%dm2_otq))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     252   [ -  +  +  -  :       59392 :  ABI_MALLOC(eig, (ppm%dm_eig, ppm%dm_eig))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     253                 :             : 
     254                 :             :  ! Here there is a problem with the small q, still cannot use BZ methods
     255                 :       14848 :  iq_ibz = Qmesh%tab(iq_bz); isym_q = Qmesh%tabo(iq_bz); itim_q = (3-Qmesh%tabi(iq_bz))/2
     256                 :             : 
     257   [ +  +  +  -  :       59392 :  ABI_CHECK(all(abs(qmesh%umklp(:, iq_bz)) < tol6), "umklapp in get_qbz are not supported!")
                   -  + ]
     258                 :             : 
     259                 :             :  !call Qmesh%get_bz_item(iq_bz,qbz,iq_ibz,isym_q,itim_q,isirred=q_isirred)
     260         [ +  + ]:       14848 :  iq_curr = iq_ibz; if (ppm%mqmem == 0) iq_curr = 1
     261                 :             : 
     262                 :       14848 :  grottb => Gsph%rottb (1:ppm%npwc, itim_q, isym_q)
     263                 :       14848 :  phsgt  => Gsph%phmSGt(1:ppm%npwc, isym_q)
     264                 :       14848 :  bigomegatwsq => ppm%bigomegatwsq(iq_curr)%vals
     265                 :       14848 :  omegatw      => ppm%omegatw(iq_curr)%vals
     266                 :             : 
     267                 :             :  ! Symmetrize the PPM parameters
     268                 :       14848 :  select case (ppm%model)
     269                 :             :  case (PPM_GODBY_NEEDS, PPM_HYBERTSEN_LOUIE)
     270                 :             :    ! Plasmon pole frequencies otq are invariant under symmetry
     271                 :             : !$omp parallel do private(isg1, isg2)
     272         [ +  + ]:      474726 :    do jj=1,ppm%npwc
     273                 :      460070 :      isg2 = grottb(jj)
     274         [ +  + ]:    21095446 :      do ii=1,ppm%npwc
     275                 :    20620720 :        isg1 = grottb(ii)
     276                 :    20620720 :        botsq(isg1,isg2) = bigomegatwsq(ii,jj)*phsgt(ii)*CONJG(phsgt(jj))
     277                 :    21080790 :        otq  (isg1,isg2) = omegatw(ii,jj)
     278                 :             :      end do
     279                 :             :    end do
     280                 :             : 
     281                 :             :  case (PPM_LINDEN_HORSH)
     282                 :             :    ! For notations see page 22 of Quasiparticle Calculations in solid (Aulbur et al)
     283                 :             :    !  If q_bz = Sq_ibz + G0 then:
     284                 :             :    !
     285                 :             :    ! $\omega^2_{ii}(q_bz) = \omega^2_{ii}(q)$        (otq array)
     286                 :             :    ! $\alpha_{ii}(q_bz)   = \alpha_{ii}(q)$          (botq array
     287                 :             :    ! $\Phi_{SG-G0}(q_bz)  = \Phi_{G}(q) e^{-iSG.t}$  (eigenvectors of e^{-1}, eig array)
     288                 :             :    !
     289         [ +  + ]:        2688 :    do ii=1,ppm%npwc ! DM bands index
     290                 :        2592 :      botsq(ii,1) = bigomegatwsq(ii,1)
     291                 :        2592 :      otq  (ii,1) = omegatw     (ii,1)
     292         [ +  + ]:       72672 :      do jj=1,ppm%npwc
     293                 :       72576 :        eig(grottb(jj),ii) = ppm%eigpot(iq_curr)%vals(jj,ii) * phsgt(jj)
     294                 :             :      end do
     295                 :             :    end do
     296   [ -  +  -  -  :          96 :    if (itim_q==2) eig=CONJG(eig) ! Time-reversal
                   -  - ]
     297                 :             : 
     298                 :             :  case (PPM_ENGEL_FARID)
     299                 :             :    ! For notations see page 23 of Quasiparticle Calculations in solid (Aulbur et al.)
     300                 :             :    ! If q_bz = Sq_ibz + G0 then:
     301                 :             :    !
     302                 :             :    ! $\omega^2_{ii}(q_bz) = \omega^2_{ii}(q)$        (otq array)
     303                 :             :    ! $y_{SG-G0}(q_bz)     = y_{G}(q) e^{-iSG.t}$     (y=Lx)
     304                 :             :    !
     305         [ +  + ]:        2688 :    do ii=1,ppm%npwc ! DM bands index
     306                 :        2592 :      otq(ii,1) = omegatw(ii,1)
     307         [ +  + ]:       72672 :      do jj=1,ppm%npwc
     308                 :       72576 :        botsq(grottb(jj),ii) = bigomegatwsq(jj,ii)*phsgt(jj)
     309                 :             :      end do
     310                 :             :    end do
     311                 :             : 
     312                 :             :  case default
     313   [ +  +  +  - ]:       14848 :    ABI_BUG(sjoin('Wrong ppm%model:',itoa(ppm%model)))
     314                 :             :  end select
     315                 :             : 
     316                 :             :  ! Take into account time-reversal symmetry.
     317         [ +  + ]:       14752 :  if (itim_q == 2) then
     318                 :             : !$omp parallel workshare
     319   [ +  +  +  + ]:      809858 :    botsq=CONJG(botsq)
     320                 :             : !$omp end parallel workshare
     321                 :             :  end if
     322                 :             : 
     323         [ -  + ]:       14848 : end subroutine ppm_get_qbz
     324                 :             : !!***
     325                 :             : 
     326                 :             : !----------------------------------------------------------------------
     327                 :             : 
     328                 :             : !!****f* m_ppmodel/ppm_free
     329                 :             : !! NAME
     330                 :             : !!  ppm_free
     331                 :             : !!
     332                 :             : !! FUNCTION
     333                 :             : !!  Deallocate all associated pointers defined in a variable of type ppmodel_t.
     334                 :             : !!
     335                 :             : !! SOURCE
     336                 :             : 
     337                 :         238 : subroutine ppm_free(ppm)
     338                 :             : 
     339                 :             : !Arguments ------------------------------------
     340                 :             :  class(ppmodel_t),intent(inout) :: ppm
     341                 :             : 
     342                 :             : !Local variables-------------------------------
     343                 :             :  integer :: dim_q,iq_ibz
     344                 :             : ! *********************************************************************
     345                 :             : 
     346         [ -  + ]:         238 :  ABI_SFREE(ppm%bigomegatwsq_qbz_vals)
     347         [ -  + ]:         238 :  ABI_SFREE(ppm%omegatw_qbz_vals)
     348         [ -  + ]:         238 :  ABI_SFREE(ppm%eigpot_qbz_vals)
     349                 :             : 
     350         [ +  + ]:         238 :  dim_q = ppm%nqibz; if (ppm%mqmem==0) dim_q=1
     351                 :             : 
     352         [ +  + ]:         238 :  if (allocated(ppm%bigomegatwsq)) then
     353         [ +  + ]:        1010 :    do iq_ibz=1,dim_q
     354                 :        1010 :      call ppm%bigomegatwsq(iq_ibz)%free()
     355                 :             :    end do
     356   [ +  -  +  +  :        1010 :    ABI_FREE(ppm%bigomegatwsq)
             -  +  -  + ]
     357                 :             :  end if
     358         [ +  + ]:         238 :  if (allocated(ppm%omegatw)) then
     359         [ +  + ]:        1010 :    do iq_ibz=1,dim_q
     360                 :        1010 :      call ppm%omegatw(iq_ibz)%free()
     361                 :             :    end do
     362   [ +  -  +  +  :        1010 :    ABI_FREE(ppm%omegatw)
             -  +  -  + ]
     363                 :             :  end if
     364         [ +  + ]:         238 :  if (allocated(ppm%eigpot)) then
     365         [ +  + ]:        1010 :    do iq_ibz=1,dim_q
     366                 :        1010 :      call ppm%eigpot(iq_ibz)%free()
     367                 :             :    end do
     368   [ +  -  +  +  :        1010 :    ABI_FREE(ppm%eigpot)
             -  +  -  + ]
     369                 :             :  end if
     370                 :             : 
     371                 :             :  ! logical flags must be deallocated here.
     372         [ +  + ]:         238 :  ABI_SFREE(ppm%keep_qibz)
     373         [ +  + ]:         238 :  ABI_SFREE(ppm%has_qibz)
     374                 :             : 
     375                 :         238 : end subroutine ppm_free
     376                 :             : !!***
     377                 :             : 
     378                 :             : !----------------------------------------------------------------------
     379                 :             : 
     380                 :             : !!****f* m_ppmodel/ppm_malloc_iqibz
     381                 :             : !! NAME
     382                 :             : !!  ppm_malloc_iqibz
     383                 :             : !!
     384                 :             : !! FUNCTION
     385                 :             : !!  Allocate the ppmodel tables for the selected q-point in the IBZ.
     386                 :             : !!
     387                 :             : !! INPUT
     388                 :             : !!  iq_ibz=Index of the q-point in the IBZ.
     389                 :             : !!
     390                 :             : !! SOURCE
     391                 :             : 
     392                 :         872 : subroutine ppm_malloc_iqibz(ppm, iq_ibz)
     393                 :             : 
     394                 :             : !Arguments ------------------------------------
     395                 :             :  class(ppmodel_t),intent(inout) :: ppm
     396                 :             :  integer,intent(in) :: iq_ibz
     397                 :             : 
     398                 :             : !Local variables-------------------------------
     399                 :             :  integer :: ierr
     400                 :             : ! *********************************************************************
     401                 :             : 
     402         [ -  + ]:         872 :  ABI_CHECK(allocated(ppm%bigomegatwsq), "bigomegatwsq is not allocated")
     403         [ -  + ]:         872 :  ABI_CHECK(allocated(ppm%omegatw), "omegatwsq is not allocated")
     404         [ -  + ]:         872 :  ABI_CHECK(allocated(ppm%eigpot), "eigpot is not allocated")
     405                 :             : 
     406         [ -  + ]:         872 :  ABI_CHECK_IGEQ(size(ppm%bigomegatwsq), iq_ibz, "bigomegatwsq too small")
     407         [ -  + ]:         872 :  ABI_CHECK_IGEQ(size(ppm%omegatw), iq_ibz, "omegatwsq too small")
     408         [ -  + ]:         872 :  ABI_CHECK_IGEQ(size(ppm%eigpot), iq_ibz, "eigpot too small")
     409                 :             : 
     410   [ -  +  +  -  :        3488 :  ABI_MALLOC_OR_DIE(ppm%bigomegatwsq(iq_ibz)%vals, (ppm%npwc, ppm%dm2_botsq), ierr)
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                -  -  + ]
     411   [ -  +  +  -  :        3488 :  ABI_MALLOC_OR_DIE(ppm%omegatw(iq_ibz)%vals, (ppm%npwc, ppm%dm2_otq), ierr)
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                -  -  + ]
     412   [ -  +  +  -  :        3488 :  ABI_MALLOC_OR_DIE(ppm%eigpot(iq_ibz)%vals, (ppm%dm_eig, ppm%dm_eig), ierr)
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                -  -  + ]
     413                 :             : 
     414                 :         872 :  ppm%has_qibz(iq_ibz) = PPM_TAB_ALLOCATED
     415                 :             : 
     416                 :         872 : end subroutine ppm_malloc_iqibz
     417                 :             : !!***
     418                 :             : 
     419                 :             : !----------------------------------------------------------------------
     420                 :             : 
     421                 :             : !!****f* m_ppmodel/ppm_table_free_iqibz
     422                 :             : !! NAME
     423                 :             : !!  ppm_table_free_iqibz
     424                 :             : !!
     425                 :             : !! FUNCTION
     426                 :             : !!  Free the ppmodel tables for the selected q-point in the IBZ.
     427                 :             : !!
     428                 :             : !! INPUT
     429                 :             : !!  iq_ibz = Index of the q-point in the IBZ.
     430                 :             : !!
     431                 :             : !! SOURCE
     432                 :             : 
     433                 :           0 : subroutine ppm_table_free_iqibz(ppm, iq_ibz)
     434                 :             : 
     435                 :             : !Arguments ------------------------------------
     436                 :             :  class(ppmodel_t),intent(inout) :: ppm
     437                 :             :  integer,intent(in) :: iq_ibz
     438                 :             : ! *********************************************************************
     439                 :             : 
     440         [ #  # ]:           0 :  if (allocated(ppm%bigomegatwsq)) call ppm%bigomegatwsq(iq_ibz)%free()
     441         [ #  # ]:           0 :  if (allocated(ppm%omegatw)) call ppm%omegatw(iq_ibz)%free()
     442         [ #  # ]:           0 :  if (allocated(ppm%eigpot)) call ppm%eigpot(iq_ibz)%free()
     443                 :             : 
     444                 :           0 :  ppm%has_qibz(iq_ibz) = PPM_NOTAB
     445                 :             : 
     446                 :           0 : end subroutine ppm_table_free_iqibz
     447                 :             : !!***
     448                 :             : 
     449                 :             : !----------------------------------------------------------------------
     450                 :             : 
     451                 :             : !!****f* m_ppmodel/ppm_init
     452                 :             : !! NAME
     453                 :             : !!  ppm_init
     454                 :             : !!
     455                 :             : !! FUNCTION
     456                 :             : !!  Initialize dimensions and other important variables related to the ppmodel
     457                 :             : !!
     458                 :             : !! INPUTS
     459                 :             : !! ppmodel=
     460                 :             : !! drude_plsmf=
     461                 :             : !!
     462                 :             : !! SOURCE
     463                 :             : 
     464         [ +  - ]:         138 : subroutine ppm_init(ppm, mqmem, nqibz, npwe, ppmodel, drude_plsmf, invalid_freq)
     465                 :             : 
     466                 :             : !Arguments ------------------------------------
     467                 :             :  class(ppmodel_t),intent(out) :: ppm
     468                 :             :  integer,intent(in) :: mqmem, nqibz, npwe, ppmodel, invalid_freq
     469                 :             :  real(dp),intent(in) :: drude_plsmf
     470                 :             : 
     471                 :             : !Local variables-------------------------------
     472                 :             : !scalars
     473                 :             :  integer :: dim_q,iq_ibz
     474                 :             :  logical :: ltest
     475                 :             :  !character(len=500) :: msg
     476                 :             : ! *********************************************************************
     477                 :             : 
     478                 :         138 :  ppm%nqibz = nqibz; ppm%mqmem = mqmem; ppm%invalid_freq = invalid_freq
     479                 :             :  !call wrtout(std_out, sjoin(' ppm%mqmem:', itoa(ppm%mqmem), 'ppm%nqibz:', itoa(ppm%nqibz)))
     480                 :             :  ltest = (ppm%mqmem == 0 .or. ppm%mqmem == ppm%nqibz)
     481                 :             :  ! ABI_CHECK(ltest,'Wrong value for mqmem')
     482                 :             : 
     483                 :         138 :  ppm%npwc        = npwe
     484                 :         138 :  ppm%model       = ppmodel
     485                 :         138 :  ppm%drude_plsmf = drude_plsmf
     486                 :         138 :  ppm%userho      = 0
     487         [ +  + ]:         138 :  if (any(ppmodel == [PPM_HYBERTSEN_LOUIE, PPM_LINDEN_HORSH, PPM_ENGEL_FARID])) ppm%userho = 1
     488                 :             : 
     489   [ -  +  +  -  :         414 :  ABI_MALLOC(ppm%keep_qibz, (nqibz))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     490   [ +  +  +  +  :        1884 :  ppm%keep_qibz = .FALSE.; if (ppm%mqmem > 0) ppm%keep_qibz = .TRUE.
                   +  + ]
     491                 :             : 
     492   [ -  +  +  -  :         276 :  ABI_MALLOC(ppm%has_qibz, (nqibz))
          -  +  -  +  -  
                      + ]
     493         [ +  + ]:        1029 :  ppm%has_qibz = PPM_NOTAB
     494                 :             : 
     495                 :             :  ! Full q-mesh is stored or out-of-memory solution.
     496         [ +  + ]:         138 :  dim_q = ppm%nqibz; if (ppm%mqmem == 0) dim_q=1
     497                 :             : 
     498   [ -  +  +  -  :        1286 :  ABI_MALLOC(ppm%bigomegatwsq, (dim_q))
          +  -  +  -  -  
          +  -  +  -  +  
                   +  + ]
     499   [ -  +  +  -  :        1148 :  ABI_MALLOC(ppm%omegatw, (dim_q))
          -  +  -  +  -  
                +  +  + ]
     500   [ -  +  +  -  :        1148 :  ABI_MALLOC(ppm%eigpot, (dim_q))
          -  +  -  +  -  
                +  +  + ]
     501                 :             : 
     502                 :         138 :  select case (ppm%model)
     503                 :             :  case (PPM_NONE)
     504                 :           0 :    ABI_WARNING("Called with ppmodel == 0")
     505                 :           0 :    ppm%dm2_botsq = 0
     506                 :           0 :    ppm%dm2_otq   = 0
     507                 :           0 :    ppm%dm_eig    = 0
     508                 :           0 :    RETURN
     509                 :             : 
     510                 :             :  case (PPM_GODBY_NEEDS, PPM_HYBERTSEN_LOUIE)
     511                 :         132 :    ppm%dm2_botsq = ppm%npwc
     512                 :         132 :    ppm%dm2_otq   = ppm%npwc
     513                 :         132 :    ppm%dm_eig    = 1 ! Should be set to 0, but g95 does not like zero-sized arrays
     514                 :             : 
     515                 :             :  case (PPM_LINDEN_HORSH)
     516                 :           3 :    ppm%dm2_botsq = 1
     517                 :           3 :    ppm%dm2_otq   = 1
     518                 :           3 :    ppm%dm_eig    = ppm%npwc
     519                 :             : 
     520                 :             :  case (PPM_ENGEL_FARID)
     521                 :           3 :    ppm%dm2_botsq = ppm%npwc
     522                 :           3 :    ppm%dm2_otq   = 1
     523                 :           3 :    ppm%dm_eig    = 1 ! Should be set to 0, but g95 does not like zero-sized arrays
     524                 :             : 
     525                 :             :  case default
     526   [ -  +  +  +  :         138 :    ABI_BUG(sjoin('Wrong ppm%model:', itoa(ppm%model)))
                      - ]
     527                 :             :  end select
     528                 :             : 
     529                 :             :  ! Allocate tables depending on the value of keep_qibz.
     530         [ +  + ]:        1010 :  do iq_ibz=1,dim_q
     531                 :        1010 :    call ppm%malloc_iqibz(iq_ibz)
     532                 :             :  end do
     533                 :             : 
     534                 :         138 :  call pstat_proc%print(_PSTAT_ARGS_)
     535                 :             : 
     536                 :             : end subroutine ppm_init
     537                 :             : !!***
     538                 :             : 
     539                 :             : !----------------------------------------------------------------------
     540                 :             : 
     541                 :             : !!****f* m_ppmodel/ppm_setup
     542                 :             : !! NAME
     543                 :             : !! ppm_setup
     544                 :             : !!
     545                 :             : !! FUNCTION
     546                 :             : !!  Initialize some values of several arrays of the ppm datastructure
     547                 :             : !!  that are used in case of plasmonpole calculations
     548                 :             : !!  This is a wrapper around different plasmonpole routines.
     549                 :             : !!
     550                 :             : !! INPUTS
     551                 :             : !!  Cryst<crystal_t>=Info on the unit cell and crystal symmetries.
     552                 :             : !!  Qmesh<kmesh_t>=the q-mesh used for the inverse dielectric matrix
     553                 :             : !!  npwe=number of G vectors for the correlation part
     554                 :             : !!  nomega=number of frequencies in $\epsilon^{-1}$
     555                 :             : !!  omega=frequencies in epsm1
     556                 :             : !!  epsm1=the inverse dielctric matrix
     557                 :             : !!  ngfftf(18)=contain all needed information about the 3D fine FFT mesh, see ~abinit/doc/variables/vargs.htm#ngfft
     558                 :             : !!  gprimd(3,3)=dimensional primitive translations for reciprocal space ($\textrm{bohr}^{-1}$)
     559                 :             : !!  nfftf=the number of points in the FFT mesh (for this processor)
     560                 :             : !!  rhor_tot(nfftf)=the total charge in real space
     561                 :             : !!
     562                 :             : !! SIDE EFFECTS
     563                 :             : !!  == if ppmodel 1 or 2 ==
     564                 :             : !!   %omegatw and %bigomegatwsq
     565                 :             : !!  == if ppmodel 3 ==
     566                 :             : !!   %omegatw, %bigomegatwsq and %eigpot
     567                 :             : !!  == if ppmodel 4 ==
     568                 :             : !!   %omegatw and %bigomegatwsq
     569                 :             : !!
     570                 :             : !! NOTES
     571                 :             : !! * FFT parallelism not implemented.
     572                 :             : !! * TODO: rhor_tot should be replaced by rhog_tot
     573                 :             : !!
     574                 :             : !! SOURCE
     575                 :             : 
     576         [ -  + ]:         408 : subroutine ppm_setup(ppm, Cryst, Qmesh, npwe, nomega, omega, epsm1, nfftf, gvec, ngfftf, rhor_tot, &
     577                 :             :                      iqiA) ! Optional
     578                 :             : 
     579                 :             : !Arguments ------------------------------------
     580                 :             : !scalars
     581                 :             :  class(ppmodel_t),intent(inout) :: ppm
     582                 :             :  integer,intent(in) :: nfftf,npwe,nomega
     583                 :             :  integer,intent(in),optional :: iqiA
     584                 :             :  type(kmesh_t),intent(in) :: Qmesh
     585                 :             :  type(crystal_t),intent(in) :: Cryst
     586                 :             : !arrays
     587                 :             :  integer,intent(in) :: gvec(3,npwe),ngfftf(18)
     588                 :             :  real(dp),intent(in) :: rhor_tot(nfftf)
     589                 :             :  complex(dp),intent(in) :: omega(nomega)
     590                 :             :  complex(gwp),intent(in) :: epsm1(:,:,:,:)
     591                 :             : 
     592                 :             : !Local variables-------------------------------
     593                 :             : !scalars
     594                 :             :  integer :: nqiA,iq_ibz
     595                 :             :  real(dp) :: n_at_G_zero
     596                 :             :  logical :: single_q
     597                 :             :  character(len=500) :: msg
     598                 :             : !scalars
     599                 :             :  real(dp) :: qpt(3)
     600                 :             : ! *************************************************************************
     601                 :             : 
     602                 :             :  !@ppmodel_t
     603                 :             :  !
     604                 :             :  ! === if iqiA is present, then consider only one qpoint to save memory ===
     605                 :             :  ! * This means the object has been already initialized
     606                 :         408 :  nqiA = Qmesh%nibz; single_q = .FALSE.
     607         [ +  + ]:         408 :  if (PRESENT(iqiA)) then
     608                 :         290 :    nqiA = 1; single_q = .TRUE.
     609                 :             :  end if
     610                 :             : 
     611                 :             :  ! Allocate plasmonpole parameters
     612                 :             :  ! TODO ppmodel==1 by default, should be set to 0 if AC and CD
     613                 :         408 :  select case (ppm%model)
     614                 :             : 
     615                 :             :  case (PPM_NONE)
     616                 :           0 :    ABI_COMMENT(' Skipping Plasmompole model calculation')
     617                 :             : 
     618                 :             :  case (PPM_GODBY_NEEDS)
     619                 :             :    ! Note: the q-dependency enters only through epsilon^-1.
     620         [ +  + ]:        1464 :    do iq_ibz=1,nqiA
     621                 :             :      call cppm1par(npwe,nomega,omega,ppm%drude_plsmf,&
     622   [ -  +  -  -  :        1464 :                    epsm1(:,:,:,iq_ibz),ppm%omegatw(iq_ibz)%vals,ppm%bigomegatwsq(iq_ibz)%vals)
          -  -  -  -  -  
                -  -  + ]
     623                 :             :    end do
     624                 :             : 
     625                 :             :  case (PPM_HYBERTSEN_LOUIE)
     626         [ +  + ]:          28 :    do iq_ibz=1,nqiA
     627   [ +  +  -  +  :          96 :      qpt = Qmesh%ibz(:,iq_ibz); if (single_q) qpt=Qmesh%ibz(:,iqiA)
                   -  - ]
     628                 :             : 
     629                 :             :      call cppm2par(qpt,npwe,epsm1(:,:,1,iq_ibz),ngfftf,gvec,Cryst%gprimd,rhor_tot,nfftf,Cryst%gmet,&
     630   [ -  +  -  -  :          28 :                    ppm%bigomegatwsq(iq_ibz)%vals,ppm%omegatw(iq_ibz)%vals,ppm%invalid_freq)
          -  -  -  -  -  
                      + ]
     631                 :             :    end do
     632                 :             : 
     633                 :             :    ! Quick-and-dirty change of the plasma frequency. Never executed in standard runs.
     634         [ -  + ]:           4 :    if (ppm%force_plsmf>tol6) then ! Integrate the real-space density
     635         [ #  # ]:           0 :       n_at_G_zero = SUM(rhor_tot(:))/nfftf
     636                 :             :       ! Change the prefactor
     637                 :           0 :       write(msg,'(2(a,es16.8))') 'Forced ppmfreq:',ppm%force_plsmf*Ha_eV,' nelec/ucvol:',n_at_G_zero
     638                 :           0 :       ABI_WARNING(msg)
     639                 :           0 :       ppm%force_plsmf = (ppm%force_plsmf**2)/(four_pi*n_at_G_zero)
     640         [ #  # ]:           0 :       do iq_ibz=1,ppm%nqibz
     641   [ #  #  #  # ]:           0 :         ppm%bigomegatwsq(iq_ibz)%vals = ppm%force_plsmf * ppm%bigomegatwsq(iq_ibz)%vals
     642   [ #  #  #  # ]:           0 :         ppm%omegatw(iq_ibz)%vals      = ppm%force_plsmf * ppm%omegatw(iq_ibz)%vals
     643                 :             :       end do
     644                 :           0 :       write(msg,'(a,es16.8)') 'Plasma frequency forced in HL ppmodel, new prefactor is:',ppm%force_plsmf
     645                 :           0 :       ABI_WARNING(msg)
     646                 :             :    end if
     647                 :             : 
     648                 :             :  case (PPM_LINDEN_HORSH) ! TODO Check better double precision, this routine is in a messy state
     649         [ +  + ]:          21 :    do iq_ibz=1,nqiA
     650   [ +  +  -  +  :          72 :      qpt = Qmesh%ibz(:,iq_ibz); if (single_q) qpt=Qmesh%ibz(:,iqiA)
                   -  - ]
     651                 :             :      call cppm3par(qpt,npwe,epsm1(:,:,1,iq_ibz),ngfftf,gvec,Cryst%gprimd,rhor_tot,nfftf,&
     652   [ -  +  -  -  :          21 :                    ppm%bigomegatwsq(iq_ibz)%vals,ppm%omegatw(iq_ibz)%vals(:,1),ppm%eigpot(iq_ibz)%vals)
          -  -  -  -  -  
                      + ]
     653                 :             :    end do
     654                 :             : 
     655                 :             :  case (PPM_ENGEL_FARID)  ! TODO Check better double precision, this routine is in a messy state
     656         [ +  + ]:          21 :    do iq_ibz=1,nqiA
     657   [ +  +  -  +  :          72 :      qpt = Qmesh%ibz(:,iq_ibz); if (single_q) qpt=Qmesh%ibz(:,iqiA)
                   -  - ]
     658   [ +  +  +  +  :          30 :      if ((ALL(ABS(qpt)<1.0e-3))) qpt = GW_Q0_DEFAULT ! FIXME
                   +  + ]
     659                 :             :      call cppm4par(qpt,npwe,epsm1(:,:,1,iq_ibz),ngfftf,gvec,Cryst%gprimd,rhor_tot,nfftf,&
     660   [ -  +  -  -  :          21 :                    ppm%bigomegatwsq(iq_ibz)%vals,ppm%omegatw(iq_ibz)%vals(:,1))
          -  -  -  -  -  
                      + ]
     661                 :             :    end do
     662                 :             : 
     663                 :             :  case default
     664   [ -  +  +  +  :         408 :    ABI_BUG(sjoin('Wrong ppm%model:',itoa(ppm%model)))
                   +  - ]
     665                 :             :  end select
     666                 :             : 
     667                 :         408 : end subroutine ppm_setup
     668                 :             : !!***
     669                 :             : 
     670                 :             : !----------------------------------------------------------------------
     671                 :             : 
     672                 :             : !!****f* m_ppmodel/ppm_getem1
     673                 :             : !! NAME
     674                 :             : !!  ppm_getem1
     675                 :             : !!
     676                 :             : !! FUNCTION
     677                 :             : !!  Calculate the symmetrized inverse dielectric matrix from the parameters of the plasmon-pole model.
     678                 :             : !!
     679                 :             : !! INPUTS
     680                 :             : !!
     681                 :             : !! OUTPUT
     682                 :             : !!
     683                 :             : !! SOURCE
     684                 :             : 
     685                 :           0 : subroutine ppm_getem1(ppm, mpwc, iqibz, zcut, nomega, omega, Vcp, em1q, &
     686                 :             :                       only_ig1, only_ig2) ! Optional
     687                 :             : 
     688                 :             : !Arguments ------------------------------------
     689                 :             : !scalars
     690                 :             :  class(ppmodel_t),intent(in) :: ppm
     691                 :             :  integer,intent(in) :: mpwc,iqibz,nomega
     692                 :             :  type(vcoul_t),intent(in) :: Vcp
     693                 :             :  real(dp),intent(in) :: zcut
     694                 :             :  integer,optional,intent(in) :: only_ig1,only_ig2
     695                 :             : !arrays
     696                 :             :  complex(dp),intent(in) :: omega(nomega)
     697                 :             :  complex(dp),intent(out) :: em1q(mpwc,mpwc,nomega)
     698                 :             : 
     699                 :             : !Local variables-------------------------------
     700                 :             : !scalars
     701                 :             :  integer :: ig1,ig2,io,idm,ig1_min,ig2_min,ig1_max,ig2_max
     702                 :             :  real(dp) :: den
     703                 :             :  complex(dp) :: qpg1,qpg2,ug1,ug2
     704                 :             :  complex(dp) :: delta,em1ggp,otw,zzpq,yg1,yg2,bot1,bot2,chig1g2
     705                 :             :  !character(len=500) :: msg
     706                 :             : ! *************************************************************************
     707                 :             : 
     708         [ #  # ]:           0 :  ABI_CHECK(ppm%mqmem/=0,'mqmem==0 not implemented')
     709                 :             : 
     710                 :             :  !TODO zcut should be an entry in ppm
     711                 :           0 :  delta=CMPLX(zero,zcut)
     712                 :             : 
     713                 :             :  ! To save memory, a particular combination of
     714                 :             :  ! ig1 and ig2 can be selected
     715                 :           0 :  ig1_min = 1
     716                 :           0 :  ig2_min = 1
     717                 :           0 :  ig1_max = ppm%npwc
     718                 :           0 :  ig2_max = ppm%npwc
     719         [ #  # ]:           0 :  if (present(only_ig1)) then
     720                 :           0 :    ig1_min = only_ig1
     721                 :           0 :    ig1_max = only_ig1
     722                 :             :  end if
     723         [ #  # ]:           0 :  if (present(only_ig2)) then
     724                 :           0 :    ig2_min = only_ig2
     725                 :           0 :    ig2_max = only_ig2
     726                 :             :  end if
     727                 :             : 
     728                 :           0 :  select case (ppm%model)
     729                 :             :  case (PPM_GODBY_NEEDS, PPM_HYBERTSEN_LOUIE)
     730         [ #  # ]:           0 :    do io=1,nomega
     731         [ #  # ]:           0 :      do ig2=ig2_min,ig2_max
     732         [ #  # ]:           0 :        do ig1=ig1_min,ig1_max
     733                 :             :         !den = omega(io)**2-REAL(ppm%omegatw(iqibz)%vals(ig1,ig2)**2)
     734                 :             :         !if (den**2<zcut**2) den = omega(io)**2-REAL( (ppm%omegatw(iqibz)%vals(ig1,ig2)-delta)**2 )
     735                 :           0 :         den = omega(io)**2 - REAL( (ppm%omegatw(iqibz)%vals(ig1,ig2)-delta)**2 )
     736                 :           0 :         em1ggp = ppm%bigomegatwsq(iqibz)%vals(ig1,ig2)/den
     737         [ #  # ]:           0 :         if (ig1==ig2) em1ggp=em1ggp+one
     738                 :           0 :         em1q(ig1,ig2,io)=em1ggp
     739                 :             :         !em1q(ig1,ig2,io)=em1ggp*Vcp%vc_sqrt(ig1,iqibz)*Vcp%vc_sqrt(ig2,iqibz)
     740                 :             :        end do
     741                 :             :      end do
     742                 :             :      !
     743                 :             :    end do !io
     744                 :             : 
     745                 :             :  case (PPM_LINDEN_HORSH)
     746                 :             :    !TODO Check coefficients
     747         [ #  # ]:           0 :    do io=1,nomega
     748         [ #  # ]:           0 :      do ig2=ig2_min,ig2_max
     749         [ #  # ]:           0 :        do ig1=ig1_min,ig1_max
     750                 :             :          !
     751                 :             :          em1ggp=czero
     752         [ #  # ]:           0 :          do idm=1,ppm%npwc
     753                 :             :            !den=omega(io)**2-(ppm%omegatw(iqibz)%vals(ig1,ig2)-delta)**2
     754                 :             :            !em1w(io)=em1w(io)+eigvec(ig1,idm,iqibz)*conjg(eigvec(ig2,idm,iqibz))*bigomegatwsq(ig1,ig2,iqibz)/den
     755                 :           0 :            ug1 = ppm%eigpot(iqibz)%vals(ig1,idm)
     756                 :           0 :            ug2 = ppm%eigpot(iqibz)%vals(ig2,idm)
     757                 :           0 :            otw = ppm%bigomegatwsq(iqibz)%vals(idm,1)*ppm%omegatw(iqibz)%vals(idm,1)
     758                 :           0 :            zzpq=ppm%bigomegatwsq(iqibz)%vals(idm,1)
     759                 :           0 :            den=half*REAL(zzpq*otw*( one/(omega(io)-otw+delta) - one/(omega(io)+otw-delta) ))
     760                 :           0 :            em1ggp=em1ggp+ug1*CONJG(ug2)*den
     761                 :             :            !eigenvalues(idm,io)=one + half*REAL(zzpq*otw*( one/(omega(io)-otw+delta) - one/(omega(io)+otw-delta) ))
     762                 :             :          end do
     763         [ #  # ]:           0 :          if (ig2==ig1) em1ggp=em1ggp+one
     764                 :           0 :          em1q(ig1,ig2,io)=em1ggp
     765                 :             :        end do !ig1
     766                 :             :      end do !ig2
     767                 :             :      !
     768                 :             :    end do !iomega
     769                 :             : 
     770                 :             :  case (PPM_ENGEL_FARID)
     771                 :             :    ! Make e^-1
     772         [ #  # ]:           0 :    do io=1,nomega
     773         [ #  # ]:           0 :      do ig2=ig2_min,ig2_max
     774                 :           0 :        qpg2=one/Vcp%vc_sqrt(ig2,iqibz)
     775         [ #  # ]:           0 :        do ig1=ig1_min,ig1_max
     776                 :           0 :          qpg1=one/Vcp%vc_sqrt(ig1,iqibz)
     777                 :             : 
     778                 :           0 :          chig1g2=czero
     779         [ #  # ]:           0 :          do idm=1,ppm%npwc
     780                 :           0 :            otw =ppm%omegatw(iqibz)%vals(idm,1)
     781                 :           0 :            bot1=ppm%bigomegatwsq(iqibz)%vals(ig1,idm)
     782                 :           0 :            bot2=ppm%bigomegatwsq(iqibz)%vals(ig2,idm)
     783                 :           0 :            yg1=SQRT(otw/four_pi)*qpg1*bot1
     784                 :           0 :            yg2=SQRT(otw/four_pi)*qpg2*bot2
     785                 :           0 :            chig1g2=chig1g2 + yg1*CONJG(yg2)/(omega(io)**2-(otw-delta)**2)
     786                 :             :          end do
     787                 :             : 
     788                 :           0 :          em1ggp=four_pi*chig1g2/(qpg1*qpg2)
     789         [ #  # ]:           0 :          if (ig1==ig2) em1ggp=em1ggp+one
     790                 :           0 :          em1q(ig1,ig2,io)=em1ggp !*Vcp%vc_sqrt(ig1,iqibz)*Vcp%vc_sqrt(ig2,iqibz)
     791                 :             :        end do !ig1
     792                 :             :      end do !ig2
     793                 :             :    end do !iomega
     794                 :             : 
     795                 :             :  case default
     796   [ #  #  #  # ]:           0 :    ABI_BUG(sjoin('Wrong ppm%model:',itoa(ppm%model)))
     797                 :             :  end select
     798                 :             : 
     799                 :           0 : end subroutine ppm_getem1
     800                 :             : !!***
     801                 :             : 
     802                 :             : !----------------------------------------------------------------------
     803                 :             : 
     804                 :             : !!****f* m_ppmodel/ppm_getem1_one_ggp
     805                 :             : !! NAME
     806                 :             : !!  ppm_getem1_one_ggp
     807                 :             : !!
     808                 :             : !! FUNCTION
     809                 :             : !!  Same as ppm_getem1, but does it for a single set of G,G' vectors
     810                 :             : !!
     811                 :             : !! INPUTS
     812                 :             : !!
     813                 :             : !! OUTPUT
     814                 :             : !!
     815                 :             : !! SOURCE
     816                 :             : 
     817                 :           0 : subroutine ppm_getem1_one_ggp(ppm, iqibz, zcut, nomega, omega, Vcp, em1q, ig1, ig2)
     818                 :             : 
     819                 :             : !Arguments ------------------------------------
     820                 :             : !scalars
     821                 :             :  class(ppmodel_t),intent(in) :: ppm
     822                 :             :  integer,intent(in) :: iqibz,nomega
     823                 :             :  type(vcoul_t),intent(in) :: Vcp
     824                 :             :  real(dp),intent(in) :: zcut
     825                 :             :  integer, intent(in) :: ig1,ig2
     826                 :             : !arrays
     827                 :             :  complex(dp),intent(in) :: omega(nomega)
     828                 :             :  complex(dp),intent(out) :: em1q(nomega)
     829                 :             : 
     830                 :             : !Local variables-------------------------------
     831                 :             : !scalars
     832                 :             :  integer :: io,idm !,ig1_min,ig2_min,ig2_max
     833                 :             :  real(dp) :: den
     834                 :             :  complex(dp) :: qpg1,qpg2,ug1,ug2
     835                 :             :  complex(dp) :: delta,em1ggp,otw,zzpq,yg1,yg2,bot1,bot2,chig1g2
     836                 :             :  !character(len=500) :: msg
     837                 :             : ! *************************************************************************
     838                 :             : 
     839         [ #  # ]:           0 :  ABI_CHECK(ppm%mqmem /= 0, 'mqmem==0 not implemented')
     840                 :             : 
     841                 :             :  !TODO zcut should be an entry in ppm
     842                 :           0 :  delta=CMPLX(zero,zcut)
     843                 :             : 
     844                 :           0 :  select case (ppm%model)
     845                 :             : 
     846                 :             :  case (PPM_GODBY_NEEDS, PPM_HYBERTSEN_LOUIE)
     847         [ #  # ]:           0 :    do io=1,nomega
     848                 :             :      !den = omega(io)**2-REAL(ppm%omegatw(iqibz)%vals(ig1,ig2)**2)
     849                 :             :      !if (den**2<zcut**2) den = omega(io)**2-REAL( (ppm%omegatw(iqibz)%value(ig1,ig2)-delta)**2 )
     850                 :           0 :      den = omega(io)**2-REAL( (ppm%omegatw(iqibz)%vals(ig1,ig2)-delta)**2 )
     851                 :           0 :      em1ggp = ppm%bigomegatwsq(iqibz)%vals(ig1,ig2)/den
     852         [ #  # ]:           0 :      if (ig1==ig2) em1ggp=em1ggp+one
     853                 :           0 :      em1q(io)=em1ggp
     854                 :             :      !em1q(io)=em1ggp*Vcp%vc_sqrt(ig1,iqibz)*Vcp%vc_sqrt(ig2,iqibz)
     855                 :             :    end do !io
     856                 :             : 
     857                 :             :  case (PPM_LINDEN_HORSH)
     858                 :             :    !TODO Check coefficients
     859         [ #  # ]:           0 :    do io=1,nomega
     860                 :           0 :      em1ggp=czero
     861         [ #  # ]:           0 :      do idm=1,ppm%npwc
     862                 :             :        !den=omega(io)**2-(ppm%omegatw(iqibz)%vals(ig1,ig2)-delta)**2
     863                 :             :        !em1w(io)=em1w(io)+eigvec(ig1,idm,iqibz)*conjg(eigvec(ig2,idm,iqibz))*bigomegatwsq(ig1,ig2,iqibz)/den
     864                 :           0 :        ug1 =ppm%eigpot(iqibz)%vals(ig1,idm)
     865                 :           0 :        ug2 =ppm%eigpot(iqibz)%vals(ig2,idm)
     866                 :           0 :        otw =ppm%bigomegatwsq(iqibz)%vals(idm,1)*ppm%omegatw(iqibz)%vals(idm,1)
     867                 :           0 :        zzpq=ppm%bigomegatwsq(iqibz)%vals(idm,1)
     868                 :           0 :        den=half*REAL(zzpq*otw*( one/(omega(io)-otw+delta) - one/(omega(io)+otw-delta) ))
     869                 :           0 :        em1ggp=em1ggp+ug1*CONJG(ug2)*den
     870                 :             :        !eigenvalues(idm,io)=one + half*REAL(zzpq*otw*( one/(omega(io)-otw+delta) - one/(omega(io)+otw-delta) ))
     871                 :             :      end do
     872                 :             : 
     873         [ #  # ]:           0 :      if (ig2==ig1) em1ggp=em1ggp+one
     874                 :           0 :      em1q(io)=em1ggp
     875                 :             :    end do !iomega
     876                 :             : 
     877                 :             :  case (PPM_ENGEL_FARID)
     878                 :             :    ! Make e^-1
     879         [ #  # ]:           0 :    do io=1,nomega
     880                 :           0 :      qpg2=one/Vcp%vc_sqrt(ig2,iqibz)
     881                 :           0 :      qpg1=one/Vcp%vc_sqrt(ig1,iqibz)
     882                 :             : 
     883                 :           0 :      chig1g2=czero
     884         [ #  # ]:           0 :      do idm=1,ppm%npwc
     885                 :           0 :        otw =ppm%omegatw(iqibz)%vals(idm,1)
     886                 :           0 :        bot1=ppm%bigomegatwsq(iqibz)%vals(ig1,idm)
     887                 :           0 :        bot2=ppm%bigomegatwsq(iqibz)%vals(ig2,idm)
     888                 :           0 :        yg1=SQRT(otw/four_pi)*qpg1*bot1
     889                 :           0 :        yg2=SQRT(otw/four_pi)*qpg2*bot2
     890                 :           0 :        chig1g2=chig1g2 + yg1*CONJG(yg2)/(omega(io)**2-(otw-delta)**2)
     891                 :             :      end do
     892                 :             : 
     893                 :           0 :      em1ggp=four_pi*chig1g2/(qpg1*qpg2)
     894         [ #  # ]:           0 :      if (ig1==ig2) em1ggp=em1ggp+one
     895                 :           0 :      em1q(io)=em1ggp !*Vcp%vc_sqrt(ig1,iqibz)*Vcp%vc_sqrt(ig2,iqibz)
     896                 :             :    end do ! io
     897                 :             : 
     898                 :             :  case default
     899   [ #  #  #  # ]:           0 :    ABI_BUG(sjoin('Wrong ppm%model:',itoa(ppm%model)))
     900                 :             :  end select
     901                 :             : 
     902                 :           0 : end subroutine ppm_getem1_one_ggp
     903                 :             : !!***
     904                 :             : 
     905                 :             : !----------------------------------------------------------------------
     906                 :             : 
     907                 :             : !!****f* m_ppmodel/ppm_get_eigenvalues
     908                 :             : !! NAME
     909                 :             : !!  ppm_get_eigenvalues
     910                 :             : !!
     911                 :             : !! FUNCTION
     912                 :             : !!  Constructs the inverse dielectri matrixc starting from the plasmon-pole
     913                 :             : !!  parameters and calculates the frequency-dependent eigenvalues for each
     914                 :             : !!  of the nomega frequencies specified in the array omega.
     915                 :             : !!
     916                 :             : !! INPUTS
     917                 :             : !!
     918                 :             : !! OUTPUT
     919                 :             : !!
     920                 :             : !! SOURCE
     921                 :             : 
     922                 :           0 : subroutine ppm_get_eigenvalues(ppm, iqibz, zcut, nomega, omega, Vcp, eigenvalues)
     923                 :             : 
     924                 :             : !Arguments ------------------------------------
     925                 :             : !scalars
     926                 :             :  class(ppmodel_t),intent(in) :: ppm
     927                 :             :  integer,intent(in) :: iqibz,nomega
     928                 :             :  type(vcoul_t),intent(in) :: Vcp
     929                 :             :  real(dp),intent(in) :: zcut
     930                 :             : !arrays
     931                 :             :  complex(dp),intent(in) :: omega(nomega)
     932                 :             :  complex(dp),intent(out) :: eigenvalues(ppm%npwc,nomega)
     933                 :             : 
     934                 :             : !Local variables-------------------------------
     935                 :             : !scalars
     936                 :             :  integer :: info,lwork,negw,ig1,ig2,idx,sdim,iomega,ierr
     937                 :             :  character(len=500) :: msg
     938                 :             : !arrays
     939                 :           0 :  real(dp),allocatable :: ww(:),rwork(:)
     940                 :           0 :  complex(dp),allocatable :: work(:),Adpp(:),eigvec(:,:),wwc(:),vs(:,:),Afull(:,:)
     941                 :           0 :  complex(dp),allocatable :: em1q(:,:,:)
     942                 :           0 :  logical,allocatable :: bwork(:)
     943                 :             :  logical :: sortcplx !BUG in abilint
     944                 :             : ! *************************************************************************
     945                 :             : 
     946         [ #  # ]:           0 :  ABI_CHECK(ppm%mqmem/=0,'mqmem==0 not implemented')
     947                 :             : 
     948   [ #  #  #  #  :           0 :  ABI_MALLOC(em1q, (ppm%npwc,ppm%npwc,nomega))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     949                 :             : 
     950                 :           0 :  call ppm%getem1(ppm%npwc,iqibz,zcut,nomega,omega,Vcp,em1q)
     951                 :             : 
     952         [ #  # ]:           0 :  do iomega=1,nomega
     953         [ #  # ]:           0 :    if (ABS(REAL(omega(iomega)))>0.00001) then
     954                 :             :      ! Eigenvalues for a generic complex matrix.
     955                 :             : 
     956                 :           0 :      lwork=4*2*ppm%npwc
     957   [ #  #  #  #  :           0 :      ABI_MALLOC(wwc,(ppm%npwc))
          #  #  #  #  #  
                #  #  # ]
     958   [ #  #  #  #  :           0 :      ABI_MALLOC(work,(lwork))
          #  #  #  #  #  
                #  #  # ]
     959   [ #  #  #  #  :           0 :      ABI_MALLOC(rwork,(ppm%npwc))
          #  #  #  #  #  
                #  #  # ]
     960   [ #  #  #  #  :           0 :      ABI_MALLOC(bwork,(ppm%npwc))
          #  #  #  #  #  
                #  #  # ]
     961   [ #  #  #  #  :           0 :      ABI_MALLOC(vs,(ppm%npwc,ppm%npwc))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     962   [ #  #  #  #  :           0 :      ABI_MALLOC(Afull,(ppm%npwc,ppm%npwc))
          #  #  #  #  #  
                #  #  # ]
     963   [ #  #  #  #  :           0 :      Afull=em1q(:,:,iomega)
          #  #  #  #  #  
                      # ]
     964                 :             : 
     965                 :             :      !for the time being, no sorting. Maybe here I should sort using the real part?
     966                 :           0 :      call ZGEES('V','N',sortcplx,ppm%npwc,Afull,ppm%npwc,sdim,wwc,vs,ppm%npwc,work,lwork,rwork,bwork,info)
     967         [ #  # ]:           0 :      if (info/=0) then
     968                 :           0 :       write(msg,'(2a,i10)')' ppm_get_eigenvalues: Error in ZGEES, diagonalizing complex matrix, info = ',info
     969                 :           0 :       call wrtout(std_out,msg)
     970                 :             :      end if
     971                 :             : 
     972         [ #  # ]:           0 :      eigenvalues(:,iomega)=wwc(:)
     973                 :             : 
     974         [ #  # ]:           0 :      ABI_FREE(wwc)
     975         [ #  # ]:           0 :      ABI_FREE(work)
     976         [ #  # ]:           0 :      ABI_FREE(rwork)
     977         [ #  # ]:           0 :      ABI_FREE(bwork)
     978         [ #  # ]:           0 :      ABI_FREE(vs)
     979         [ #  # ]:           0 :      ABI_FREE(Afull)
     980                 :             : 
     981                 :             :    else
     982                 :             :      ! === Hermitian Case ===
     983                 :           0 :      lwork=2*ppm%npwc-1
     984   [ #  #  #  #  :           0 :      ABI_MALLOC(ww,(ppm%npwc))
          #  #  #  #  #  
                #  #  # ]
     985   [ #  #  #  #  :           0 :      ABI_MALLOC(work,(lwork))
          #  #  #  #  #  
                #  #  # ]
     986   [ #  #  #  #  :           0 :      ABI_MALLOC(rwork,(3*ppm%npwc-2))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     987   [ #  #  #  #  :           0 :      ABI_MALLOC(eigvec,(ppm%npwc,ppm%npwc))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     988                 :             : 
     989   [ #  #  #  #  :           0 :      ABI_MALLOC_OR_DIE(Adpp,(ppm%npwc*(ppm%npwc+1)/2), ierr)
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     990                 :             :      !write(std_out,*) 'in hermitian'
     991                 :             : 
     992                 :           0 :      idx=0
     993         [ #  # ]:           0 :      do ig2=1,ppm%npwc
     994         [ #  # ]:           0 :        do ig1=1,ig2
     995                 :           0 :          idx=idx+1
     996                 :           0 :          Adpp(idx)=em1q(ig1,ig2,iomega)
     997                 :             :        end do
     998                 :             :      end do
     999                 :             : 
    1000                 :             :      ! Require eigenvectors as well
    1001                 :           0 :      call ZHPEV('V','U',ppm%npwc,Adpp,ww,eigvec,ppm%npwc,work,rwork,info)
    1002                 :             : 
    1003         [ #  # ]:           0 :      ABI_CHECK(info == 0, sjoin('Error diagonalizing matrix, info: ', itoa(info)))
    1004                 :             : 
    1005   [ #  #  #  # ]:           0 :      negw = (COUNT((REAL(ww)<tol6)))
    1006         [ #  # ]:           0 :      if (negw /= 0) then
    1007   [ #  #  #  #  :           0 :        write(msg,'(a,i0,a,i0,a,f8.4)')'Found negative eigenvalues. No. ',negw,' at iqibz= ',iqibz,' minval= ',MINVAL(REAL(ww))
             #  #  #  # ]
    1008                 :           0 :         ABI_WARNING(msg)
    1009                 :             :      end if
    1010                 :             : 
    1011         [ #  # ]:           0 :      eigenvalues(:,iomega)=ww(:)
    1012                 :             : 
    1013         [ #  # ]:           0 :      ABI_FREE(ww)
    1014         [ #  # ]:           0 :      ABI_FREE(work)
    1015         [ #  # ]:           0 :      ABI_FREE(rwork)
    1016         [ #  # ]:           0 :      ABI_FREE(eigvec)
    1017         [ #  # ]:           0 :      ABI_FREE(Adpp)
    1018                 :             :    end if
    1019                 :             :  end do !iomega
    1020                 :             : 
    1021         [ #  # ]:           0 :  ABI_FREE(em1q)
    1022                 :             : 
    1023                 :           0 : end subroutine ppm_get_eigenvalues
    1024                 :             : !!***
    1025                 :             : 
    1026                 :             : !----------------------------------------------------------------------
    1027                 :             : 
    1028                 :             : !!****f* m_ppmodel/cppm1par
    1029                 :             : !! NAME
    1030                 :             : !! cppm1par
    1031                 :             : !!
    1032                 :             : !! FUNCTION
    1033                 :             : !! Calculate the plasmon-pole parameters big-omega-twiddle-squared and omega-twiddle from
    1034                 :             : !! epsilon-twiddle^-1 calculated for nomega (usually 2) frequencies omega=0 and omega=iE0.
    1035                 :             : !!
    1036                 :             : !! INPUTS
    1037                 :             : !!  epsm1(npwc,npwc,nomega)=dielectric matrix at nomega frequencies.
    1038                 :             : !!  npwc=number of plane waves
    1039                 :             : !!  nomega=number of frequencies (usually 2)
    1040                 :             : !!  omega(nomega)=frequencies
    1041                 :             : !!  omegaplasma=input variable or Drude plasma frequency
    1042                 :             : !!
    1043                 :             : !! OUTPUT
    1044                 :             : !!  bigomegatwsq(npwc,npwc)=parameter of the plasmon-pole model (see gwa.pdf file)
    1045                 :             : !!  omegatw(npwc,npwc)=parameter of the plasmon-pole model (see gwa.pdf file)
    1046                 :             : !!
    1047                 :             : !! TODO
    1048                 :             : !!  Calculation can be done in place.
    1049                 :             : !!
    1050                 :             : !! SOURCE
    1051                 :             : 
    1052                 :        1085 : subroutine cppm1par(npwc, nomega, omega, omegaplasma, epsm1, omegatw, bigomegatwsq)
    1053                 :             : 
    1054                 :             : !Arguments ------------------------------------
    1055                 :             : !scalars
    1056                 :             :  integer,intent(in) :: nomega,npwc
    1057                 :             :  real(dp),intent(in) :: omegaplasma
    1058                 :             : !arrays
    1059                 :             :  complex(dp),intent(in) :: omega(nomega)
    1060                 :             :  complex(gwp),intent(in) :: epsm1(npwc,npwc,nomega)
    1061                 :             :  complex(gwp),intent(out) :: omegatw(npwc,npwc), bigomegatwsq(npwc,npwc)
    1062                 :             : 
    1063                 :             : !Local variables-------------------------------
    1064                 :             : !scalars
    1065                 :             :  integer :: ig,igp,io,io0,ioe0
    1066                 :             :  real(dp) :: e0,minomega
    1067                 :             :  character(len=500) :: msg
    1068                 :             :  complex(gwp) :: AA,omegatwsq,diff,ratio,epsm1_io0,epsm1_ioe0
    1069                 :             : ! *************************************************************************
    1070                 :             : 
    1071                 :             :  ! Find omega=0 and omega=imag (closest to omegaplasma) to fit the ppm parameters
    1072                 :        1085 :  minomega=1.0d-3; io0=0
    1073         [ +  + ]:        3406 :  do io=1,nomega
    1074         [ +  + ]:        3406 :    if (ABS(omega(io))<minomega) then
    1075                 :        1085 :      io0=io; minomega=ABS(omega(io))
    1076                 :             :    end if
    1077                 :             :  end do
    1078         [ -  + ]:        1085 :  ABI_CHECK(io0 /= 0, "omega=0 not found")
    1079                 :             : 
    1080                 :        1085 :  minomega=1.0d-3; e0=200.0; ioe0=0
    1081         [ +  + ]:        3406 :  do io=1,nomega
    1082   [ +  +  +  + ]:        3406 :    if (REAL(omega(io))<minomega.and.AIMAG(omega(io))>minomega) then
    1083         [ +  + ]:        1145 :      if (ABS(AIMAG(omega(io))-omegaplasma)<ABS(e0-omegaplasma)) then
    1084                 :        2321 :        ioe0=io; e0=AIMAG(omega(io))
    1085                 :             :      end if
    1086                 :             :    end if
    1087                 :             :  end do
    1088                 :             : 
    1089                 :        1085 :  write(msg,'(a,f9.4,a)')' Imaginary frequency for fit located at: ',e0*Ha_eV,' [eV] '
    1090                 :        1085 :  call wrtout(std_out, msg)
    1091         [ -  + ]:        1085 :  ABI_CHECK(ioe0 /= 0,"Imaginary omega not found")
    1092                 :             : 
    1093                 :             :  ! ================================================================
    1094                 :             :  ! === Calculate plasmon-pole A parameter A=epsilon^-1(0)-delta ===
    1095                 :             :  ! ================================================================
    1096         [ +  + ]:       53890 :  do ig=1,npwc
    1097         [ +  + ]:     4140407 :    do igp=1,npwc
    1098                 :     4086517 :      epsm1_io0  = epsm1(ig,igp,io0)
    1099                 :     4086517 :      epsm1_ioe0 = epsm1(ig,igp,ioe0)
    1100                 :             : 
    1101                 :     4086517 :      AA=epsm1_io0
    1102         [ +  + ]:     4086517 :      if (ig==igp) AA=AA-one
    1103                 :             : 
    1104                 :             :      ! === Calculate plasmon-pole omega-twiddle-square parameter ===
    1105                 :             :      ! XG201009 Strangely, the next formula does not work with gcc43-debug
    1106                 :             :      ! omegatwsq=(AA/(epsm1_io0-epsm1_ioe0)-one)*e0**2
    1107                 :             :      ! This seems to be due to precision issue at the level of division by a complex whose norm squared
    1108                 :             :      ! is below the smallest representable number.
    1109                 :             :      ! After many trials, I have decided to shift the difference by a small number ... well, not so small ...
    1110                 :             :      ! for numerical issues
    1111                 :     4086517 :      diff=epsm1_io0-epsm1_ioe0
    1112                 :     4086517 :      diff=diff+cmplx(tol10,tol10)
    1113                 :     4086517 :      ratio=AA/diff
    1114                 :     4086517 :      omegatwsq=(ratio-cone)*e0**2
    1115                 :             :      !
    1116                 :             :      ! If omega-twiddle-squared is negative,set omega-twiddle-squared to 1.0 (a reasonable way of treating
    1117                 :             :      ! such terms, in which epsilon**-1 was originally increasing along this part of the imaginary axis)
    1118                 :             :      ! (note: originally these terms were ignored in Sigma; this was changed on 6 March 1990.)
    1119                 :             : 
    1120         [ +  + ]:     4086517 :      if (REAL(omegatwsq)<=zero) omegatwsq=one
    1121                 :             :      !
    1122                 :             :      ! Get omega-twiddle. Neglect the imag part (if any) in omega-twiddle-squared
    1123                 :     4086517 :      omegatw(ig,igp)=SQRT(REAL(omegatwsq))
    1124                 :             : 
    1125                 :             :      ! Get big-omega-twiddle-squared=-omega-twiddle-squared AA
    1126                 :     4139322 :      bigomegatwsq(ig,igp)=-AA*omegatw(ig,igp)**2
    1127                 :             : 
    1128                 :             :    end do !igp
    1129                 :             :  end do !ig
    1130                 :             : 
    1131                 :        1085 :  write(msg,'(2a,f15.12,2a,2i5,a)')ch10,&
    1132   [ +  +  +  +  :     4140407 :    ' cppm1par : omega twiddle minval [eV]  = ',MINVAL(ABS(omegatw))*Ha_eV,ch10,&
          +  +  +  -  -  
                +  -  - ]
    1133   [ +  -  +  +  :     4143662 :    '            omega twiddle min location = ',MINLOC(ABS(omegatw)),ch10
             +  +  +  + ]
    1134                 :        1085 :  call wrtout(std_out,msg)
    1135                 :             : 
    1136                 :        1085 : end subroutine cppm1par
    1137                 :             : !!***
    1138                 :             : 
    1139                 :             : !----------------------------------------------------------------------
    1140                 :             : 
    1141                 :             : !!****f* m_ppmodel/cppm2par
    1142                 :             : !! NAME
    1143                 :             : !! cppm2par
    1144                 :             : !!
    1145                 :             : !! FUNCTION
    1146                 :             : !!  Calculate plasmon-pole parameters of the Hybertsen and Louie model (PRB 34, 5390 (1986) [[cite:Hybertsen1986]])
    1147                 :             : !!
    1148                 :             : !! INPUTS
    1149                 :             : !!  qpt(3)=The coordinates of the q-point in the IBZ.
    1150                 :             : !!  epsm1(npwc,npwc)=symmetrized inverse dielectric (static limit is used)
    1151                 :             : !!  gmet(3,3)=metric in reciprocal space
    1152                 :             : !!  ngfftf(18)=contain all needed information about the 3D fine FFT, see ~abinit/doc/variables/vargs.htm#ngfft
    1153                 :             : !!  npwc=number of plane waves in epsm1
    1154                 :             : !!  rhor(nfftf)=charge density on the real space FFT grid
    1155                 :             : !!  nfftf= total number of points in the fine FFT mesh  (for this processor)
    1156                 :             : !!  invalid_freq: what to do when PPM omega is found negative or imaginary
    1157                 :             : !!     0) drop it (default as specified in Hybersen-Louie original GW paper)
    1158                 :             : !!     1) set to 1 hartree
    1159                 :             : !!     2) set to infinity
    1160                 :             : !!
    1161                 :             : !! OUTPUT
    1162                 :             : !!  bigomegatwsq(npwc,npwc)= squared bare plasma frequencies
    1163                 :             : !!   \Omega^2_{G1 G2}(q) = 4\pi \frac {(q+G1).(q+G2)}/{|q+G1|^2} n(G1-G2)
    1164                 :             : !!  omegatw(npwc,npwc)= plasmon frequencies \tilde\omega_{G1 G2}(q) where:
    1165                 :             : !!  \tilde\omega^2_{G1 G2}(q) =
    1166                 :             : !!    \frac {\Omega^2_{G1 G2}(q)} {\delta_{G1 G2}-\tilde\epsilon^{-1}_{G1 G2} (q, \omega=0)}
    1167                 :             : !!
    1168                 :             : !! SOURCE
    1169                 :             : 
    1170                 :          24 : subroutine cppm2par(qpt, npwc, epsm1, ngfftf, gvec, gprimd, rhor, nfftf, gmet, bigomegatwsq, omegatw, invalid_freq)
    1171                 :             : 
    1172                 :             : !Arguments ------------------------------------
    1173                 :             : !scalars
    1174                 :             :  integer,intent(in) :: npwc,nfftf,invalid_freq
    1175                 :             : !arrays
    1176                 :             :  integer,intent(in) :: gvec(3,npwc), ngfftf(18)
    1177                 :             :  real(dp),intent(in) :: qpt(3),gmet(3,3),gprimd(3,3), rhor(nfftf)
    1178                 :             :  complex(gwp),intent(in) :: epsm1(npwc,npwc)
    1179                 :             :  complex(gwp),intent(out) :: bigomegatwsq(npwc,npwc), omegatw(npwc,npwc)
    1180                 :             : 
    1181                 :             : !Local variables-------------------------------
    1182                 :             : !scalars
    1183                 :             :  integer :: ig,igp,nimwp,ngfft1,ngfft2,ngfft3,gmgp_idx,ierr
    1184                 :             :  real(dp) :: lambda,phi,AA
    1185                 :             :  logical,parameter :: use_symmetrized=.TRUE., check_imppf=.FALSE.
    1186                 :             :  character(len=500) :: msg
    1187                 :          24 :  type(MPI_type) :: MPI_enreg_seq
    1188                 :             : !arrays
    1189                 :             :  real(dp) :: qlist(3,1)
    1190                 :          24 :  real(dp),allocatable :: tmp_rhor(:),qratio(:,:),qplusg(:),rhog_dp(:,:)
    1191                 :          24 :  complex(gwp),allocatable :: omegatwsq(:,:)
    1192                 :          24 :  complex(gwp),allocatable :: rhog(:),rhogg(:,:),temp(:,:)  !MG these should be double precision TODO
    1193                 :             : !*************************************************************************
    1194                 :             : 
    1195                 :          24 :  call initmpi_seq(MPI_enreg_seq)
    1196                 :          24 :  call MPI_enreg_seq%distribfft%init_seq('c',ngfftf(2),ngfftf(3),'all')
    1197                 :             : 
    1198                 :             :  ! Calculate qratio(npwec,npvec) = (q+G).(q+Gp)/|q+G|^2 ===
    1199   [ -  +  +  -  :          96 :  ABI_MALLOC_OR_DIE(qratio,(npwc,npwc), ierr)
          -  +  +  -  +  
          -  +  -  +  -  
             -  +  -  + ]
    1200                 :             : 
    1201                 :          24 :  call cqratio(npwc,gvec,qpt,gmet,gprimd,qratio)
    1202                 :             :  !
    1203                 :             :  ! Compute the density in G space rhor(R)--> rhog(G)
    1204   [ -  +  +  -  :          72 :  ABI_MALLOC(rhog_dp,(2,nfftf))
          +  -  +  -  -  
                +  -  + ]
    1205   [ -  +  +  -  :          72 :  ABI_MALLOC(rhog,(nfftf))
          +  -  +  -  -  
                +  -  + ]
    1206                 :          24 :  ngfft1=ngfftf(1); ngfft2=ngfftf(2); ngfft3=ngfftf(3)
    1207                 :             : 
    1208   [ -  +  +  -  :          72 :  ABI_MALLOC(tmp_rhor,(nfftf))
          +  -  +  -  -  
                +  -  + ]
    1209   [ -  +  +  + ]:      183222 :  tmp_rhor = rhor ! To avoid having to use intent(inout).
    1210                 :          24 :  call fourdp(1,rhog_dp,tmp_rhor,-1,MPI_enreg_seq,nfftf,1,ngfftf,0)
    1211         [ -  + ]:          24 :  ABI_FREE(tmp_rhor)
    1212                 :             : 
    1213         [ +  + ]:      183198 :  rhog(1:nfftf)=CMPLX(rhog_dp(1,1:nfftf),rhog_dp(2,1:nfftf))
    1214                 :             : 
    1215                 :             :  ! Calculate the FFT index of each (G-Gp) vector and assign
    1216                 :             :  ! the value of the correspondent density simultaneously
    1217   [ -  +  +  -  :          96 :  ABI_MALLOC_OR_DIE(rhogg,(npwc, npwc), ierr)
          -  +  +  -  +  
          -  +  -  +  -  
             -  +  -  + ]
    1218                 :             : 
    1219                 :          24 :  ierr=0
    1220         [ +  + ]:         708 :  do ig=1,npwc
    1221         [ +  + ]:       20364 :    do igp=1,npwc
    1222         [ +  + ]:       78624 :      gmgp_idx = g2ifft(gvec(:,ig)-gvec(:,igp),ngfftf)
    1223         [ +  - ]:       20340 :      if (gmgp_idx/=0) then
    1224                 :       19656 :        rhogg(ig,igp)=rhog(gmgp_idx)
    1225                 :             :      else
    1226                 :           0 :        ierr=ierr+1
    1227                 :           0 :        rhogg(ig,igp)=czero
    1228                 :             :      end if
    1229                 :             :    end do
    1230                 :             :  end do
    1231                 :             : 
    1232         [ -  + ]:          24 :  if (ierr /= 0) then
    1233                 :             :    write(msg,'(a,i0,1x,3a)')&
    1234                 :           0 :     'Found ',ierr,' G1-G2 vectors falling outside the FFT box. ',ch10,&
    1235                 :           0 :     'Enlarge the FFT mesh to get rid of this problem. '
    1236                 :           0 :    ABI_WARNING(msg)
    1237                 :             :  end if
    1238                 :             : 
    1239   [ +  +  +  + ]:       20364 :  rhogg=four_pi*rhogg
    1240         [ -  + ]:          24 :  ABI_FREE(rhog_dp)
    1241         [ -  + ]:          24 :  ABI_FREE(rhog)
    1242                 :             : 
    1243                 :             :  ! Calculate GPP parameters
    1244                 :             :  ! unsymmetrized epsm1 -> epsm1=|q+Gp|/|q+G|*epsm1
    1245   [ -  +  +  -  :          72 :  ABI_MALLOC(qplusg,(npwc))
          +  -  +  -  -  
                +  -  + ]
    1246   [ -  +  +  -  :          72 :  ABI_MALLOC(temp,(npwc,npwc))
          -  +  +  -  -  
                +  -  + ]
    1247   [ -  +  +  -  :          72 :  ABI_MALLOC_OR_DIE(omegatwsq,(npwc,npwc), ierr)
          -  +  +  -  +  
             -  -  +  -  
                      + ]
    1248                 :             : 
    1249   [ -  +  +  +  :       20388 :  temp = -epsm1(:,:)
                   +  + ]
    1250                 :             :  !
    1251                 :             :  ! RS still not obvious for me whether one shall use the symmetrized inverse DM or the unsymmetrized one
    1252                 :             :  ! the default here is to use the symmetrized one, I must discuss this with XG
    1253                 :             :  !
    1254                 :             :  ! MG it turns out that using the symmetrized inverse DM in the plasmon-pole
    1255                 :             :  ! equations give the same results for the squared plasmon frequencies omegatwsq while the
    1256                 :             :  ! squared bare plasma frequencies bigomegatwsq related to the symmetrized dielectric matrix
    1257                 :             :  ! are obtained multiplying by |q+G1|/|q+G2|.
    1258                 :             :  !
    1259                 :             :  if (.not.use_symmetrized) then
    1260                 :             :    qlist(:,1) = qpt
    1261                 :             :    call cmod_qpg(1,1,qlist,npwc,gvec,gprimd,qplusg) !MG TODO here take care of small q
    1262                 :             :    do ig=1,npwc
    1263                 :             :      do igp=1,npwc
    1264                 :             :        temp(ig,igp)=qplusg(igp)/qplusg(ig)*temp(ig,igp)
    1265                 :             :      end do
    1266                 :             :    end do
    1267                 :             :  end if
    1268                 :             : 
    1269                 :          24 :  nimwp=0
    1270         [ +  + ]:         708 :  do ig=1,npwc
    1271                 :         684 :    temp(ig,ig)=temp(ig,ig)+one
    1272         [ +  + ]:       20364 :    do igp=1,npwc
    1273                 :       19656 :      bigomegatwsq(ig,igp) = rhogg(ig,igp)*qratio(ig,igp)
    1274                 :       19656 :      omegatwsq(ig,igp)=bigomegatwsq(ig,igp)/temp(ig,igp)
    1275                 :             :      !
    1276                 :             :      ! Set to an arbitrary value the omegawsq which become negative or imaginary
    1277                 :             :      ! in principle these correspond to cases where the imaginary part of epsm1 does not have
    1278                 :             :      ! a well defined peak. The imaginary part of epsm1 in these cases oscillates  with a small amplitude
    1279                 :             :      ! since the amplitude A_GGpr=-pi/2*bigomegatwsq/omegatw,
    1280                 :             :      ! it follows that bigomegatwsq shall be set to zero for these cases
    1281   [ +  +  -  + ]:       20340 :      if ( REAL(omegatwsq(ig,igp))<= tol12 .or. AIMAG(omegatwsq(ig,igp))**2*tol12> REAL(omegatwsq(ig,igp))**2) then
    1282                 :       10280 :        nimwp=nimwp+1
    1283                 :             : 
    1284         [ -  + ]:       10280 :        if ( invalid_freq == 1 ) then
    1285                 :             :         ! set omegatwsq to 1 hartree
    1286                 :           0 :          omegatwsq(ig,igp)=cone
    1287                 :           0 :          AA = epsm1(ig,igp)
    1288         [ #  # ]:           0 :          if ( ig == igp ) AA = AA - one
    1289                 :           0 :          omegatw(ig,igp)=SQRT(REAL(omegatwsq(ig,igp)))
    1290                 :           0 :          bigomegatwsq(ig,igp)=-AA*omegatw(ig,igp)**2
    1291         [ +  + ]:       10280 :        elseif ( invalid_freq == 2 ) then
    1292                 :             :          ! set omegatwsq to infinity
    1293                 :        3911 :          omegatwsq(ig,igp)=cone/tol6
    1294                 :        3911 :          AA = epsm1(ig,igp)
    1295         [ -  + ]:        3911 :          if ( ig == igp ) AA = AA - one
    1296                 :        3911 :          omegatw(ig,igp)=SQRT(REAL(omegatwsq(ig,igp)))
    1297                 :        3911 :          bigomegatwsq(ig,igp)=-AA*omegatw(ig,igp)**2
    1298                 :             :        else
    1299                 :             :          ! simply ignore all cases of omegatw with imaginary values
    1300                 :        6369 :          bigomegatwsq(ig,igp)=(0.,0.)
    1301                 :        6369 :          omegatw(ig,igp)=(ten,0.)
    1302                 :             :        end if
    1303                 :             :        if (check_imppf) then
    1304                 :             :          write(msg,'(a,2(i0,1x))')' Imaginary plasmon frequency at : ',ig,igp
    1305                 :             :          call wrtout(std_out,msg)
    1306                 :             :        end if
    1307                 :             :      else
    1308                 :             :        ! this part has been added to deal with systems without inversion symmetry
    1309                 :             :        ! this new implementation gives the same results as the previous one if
    1310                 :             :        ! omegatwsq is a pure real number and has the advantage of being an improved
    1311                 :             :        ! approach for systems without an inversion center.
    1312                 :        9376 :        lambda=ABS(omegatwsq(ig,igp))
    1313                 :        9376 :        phi=ATAN(AIMAG(omegatwsq(ig,igp))/REAL(omegatwsq(ig,igp)))
    1314                 :        9376 :        omegatw(ig,igp)=SQRT(lambda/COS(phi))
    1315                 :        9376 :        bigomegatwsq(ig,igp)=bigomegatwsq(ig,igp)*(1.-(0.,1.)*TAN(phi))
    1316                 :             :        ! Uncomment the following line and comment the previous to restore the old version.
    1317                 :             :        !omegatw(ig,igp)=sqrt(real(omegatwsq(ig,igp)))
    1318                 :             :      end if
    1319                 :             :    end do
    1320                 :             :  end do
    1321                 :             : 
    1322         [ +  - ]:          24 :  write(msg,'(3a,i0,a,i0)')' At q-point : ',trim(ktoa(qpt)), ' # imaginary plasmonpole frequencies: ',nimwp,' / ',npwc**2
    1323                 :          24 :  call wrtout(std_out, msg)
    1324                 :             :  write(msg,'(a,f12.8,a,3(i0,1x))') &
    1325   [ +  +  +  +  :       40752 :   " omega twiddle minval: ", MINVAL(ABS(omegatw))*Ha_eV, "[eV], min location: ",MINLOC(ABS(omegatw))
          +  +  +  -  -  
          +  -  -  +  -  
          +  +  +  +  +  
                      + ]
    1326                 :          24 :  call wrtout(std_out, msg)
    1327                 :             : 
    1328                 :          24 :  call destroy_mpi_enreg(MPI_enreg_seq)
    1329                 :             : 
    1330         [ -  + ]:          24 :  ABI_FREE(omegatwsq)
    1331         [ -  + ]:          24 :  ABI_FREE(rhogg)
    1332         [ -  + ]:          24 :  ABI_FREE(temp)
    1333         [ -  + ]:          24 :  ABI_FREE(qplusg)
    1334         [ -  + ]:          24 :  ABI_FREE(qratio)
    1335                 :             : 
    1336   [ -  +  -  +  :          24 : end subroutine cppm2par
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                +  -  + ]
    1337                 :             : !!***
    1338                 :             : 
    1339                 :             : !----------------------------------------------------------------------
    1340                 :             : 
    1341                 :             : !!****f* m_ppmodel/cppm3par
    1342                 :             : !! NAME
    1343                 :             : !! cppm3par
    1344                 :             : !!
    1345                 :             : !! FUNCTION
    1346                 :             : !! Calculate the plasmon-pole parameters using the von Linden-Horsh model (PRB 37, 8351, 1988) [[cite:vonderLinden1988]]
    1347                 :             : !! (see also Pag 22 of Quasiparticle Calculations in Solids [[cite:Aulbur2001]].
    1348                 :             : !!
    1349                 :             : !! INPUTS
    1350                 :             : !! epsm1(npwc,npwc))= symmetrized inverse dielectric
    1351                 :             : !! ngfftf(18)=contain all needed information about 3D fine FFT, see ~abinit/doc/variables/vargs.htm#ngfft
    1352                 :             : !! npwc=number of plane waves in epsm1
    1353                 :             : !! qratio=(q+G1).(q+G2)/(|q+G1|.|q+G2|)
    1354                 :             : !! rhor(nfftf)=charge density on the real space FFT grid
    1355                 :             : !! nfftf=number of points in the FFT grid (for this processor)
    1356                 :             : !! gvec(3,npwc)= G vectors in reduced coordinates
    1357                 :             : !!
    1358                 :             : !! OUTPUT
    1359                 :             : !!  omegatw(npwc,npwc)= plasmon pole positions
    1360                 :             : !!  bigomegatwsq(npwc,npwc)=(E_{q,ii}^{-1}-1)*omegatw
    1361                 :             : !!   where E^{-1} is the eigenvalue of the inverse dielectric matrix
    1362                 :             : !!  eigtot(npwc,npwc)=the eigvectors of the symmetrized inverse dielectric matrix
    1363                 :             : !!   (first index for G, second index for bands)
    1364                 :             : !!
    1365                 :             : !! SOURCE
    1366                 :             : 
    1367                 :          18 : subroutine cppm3par(qpt,npwc,epsm1,ngfftf,gvec,gprimd,rhor,nfftf,bigomegatwsq,omegatw,eigtot)
    1368                 :             : 
    1369                 :             : !Arguments ------------------------------------
    1370                 :             : !scalars
    1371                 :             :  integer,intent(in) :: nfftf,npwc
    1372                 :             : !arrays
    1373                 :             :  integer,intent(in) :: gvec(3,npwc),ngfftf(18)
    1374                 :             :  real(dp),intent(in) :: qpt(3),gprimd(3,3),rhor(nfftf)
    1375                 :             :  complex(gwp),intent(in) :: epsm1(npwc,npwc)
    1376                 :             :  complex(gwp),intent(out) :: bigomegatwsq(npwc,1),omegatw(npwc) ,eigtot(npwc,npwc)
    1377                 :             : 
    1378                 :             : !Local variables-------------------------------
    1379                 :             : !TODO these should be dp
    1380                 :             : !scalars
    1381                 :             :  integer :: idx,ierr,ig,igp,ii,jj,ngfft1,ngfft2,ngfft3,gmgp_idx
    1382                 :             :  real(dp) :: num,qpg_dot_qpgp
    1383                 :             :  complex(dp) :: conjg_eig
    1384                 :             :  logical :: qiszero
    1385                 :             :  character(len=500) :: msg
    1386                 :          18 :  type(MPI_type) :: MPI_enreg_seq
    1387                 :             : !arrays
    1388                 :             :  real(dp) :: b1(3),b2(3),b3(3),gppq(3),gpq(3),qlist(3,1)
    1389                 :          18 :  real(dp),allocatable :: eigval(:),qplusg(:),rhog_dp(:,:),zhpev2(:),tmp_rhor(:)
    1390                 :          18 :  complex(dp),allocatable :: eigvec(:,:),matr(:),mm(:,:),rhog(:),rhogg(:,:), zhpev1(:),zz(:)
    1391                 :             : !*************************************************************************
    1392                 :             : 
    1393                 :             :  ! Fake MPI_type for the sequential part.
    1394                 :          18 :  call initmpi_seq(MPI_enreg_seq)
    1395                 :          18 :  call MPI_enreg_seq%distribfft%init_seq('c',ngfftf(2),ngfftf(3),'all')
    1396                 :             : 
    1397   [ +  +  +  + ]:          30 :  qiszero = (ALL(ABS(qpt)<1.0e-3))
    1398                 :             : 
    1399   [ +  +  +  +  :         180 :  b1 = two_pi*gprimd(:,1); b2 = two_pi*gprimd(:,2); b3 = two_pi*gprimd(:,3)
                   +  + ]
    1400                 :             : 
    1401                 :          18 :  ngfft1=ngfftf(1); ngfft2=ngfftf(2); ngfft3=ngfftf(3)
    1402                 :             : 
    1403   [ -  +  +  -  :          54 :  ABI_MALLOC(rhog_dp,(2,nfftf))
          +  -  +  -  -  
                +  -  + ]
    1404   [ -  +  +  -  :          54 :  ABI_MALLOC(rhog,(nfftf))
          +  -  +  -  -  
                +  -  + ]
    1405   [ -  +  +  -  :          72 :  ABI_MALLOC_OR_DIE(rhogg,(npwc, npwc), ierr)
          -  +  +  -  +  
          -  +  -  +  -  
             -  +  -  + ]
    1406                 :             :  !
    1407                 :             :  ! === Compute the density in G space rhog(r)--> rho(G) ===
    1408                 :             :  ! FIXME this has to be fixed, rho(G) should be passed instead of doing FFT for each q
    1409                 :             : 
    1410   [ -  +  +  -  :          54 :  ABI_MALLOC(tmp_rhor,(nfftf))
          +  -  +  -  -  
                +  -  + ]
    1411   [ -  +  +  + ]:       65112 :  tmp_rhor=rhor ! To avoid having to use intent(inout).
    1412                 :          18 :  call fourdp(1,rhog_dp,tmp_rhor,-1,MPI_enreg_seq,nfftf,1,ngfftf,0)
    1413         [ -  + ]:          18 :  ABI_FREE(tmp_rhor)
    1414                 :             : 
    1415         [ +  + ]:       65094 :  rhog(1:nfftf)=CMPLX(rhog_dp(1,1:nfftf),rhog_dp(2,1:nfftf))
    1416                 :             :  !
    1417                 :             :  ! Calculate the FFT index of each (G-Gp) vector and assign the value
    1418                 :             :  ! of the correspondent density simultaneously
    1419                 :          18 :  ierr=0
    1420         [ +  + ]:         504 :  do ig=1,npwc
    1421         [ +  + ]:       13626 :    do igp=1,npwc
    1422         [ +  + ]:       52488 :      gmgp_idx = g2ifft(gvec(:,ig)-gvec(:,igp),ngfftf)
    1423         [ +  - ]:       13608 :      if (gmgp_idx/=0) then
    1424                 :       13122 :        rhogg(ig,igp)=rhog(gmgp_idx)
    1425                 :             :      else
    1426                 :           0 :        ierr=ierr+1
    1427                 :           0 :        rhogg(ig,igp)=czero
    1428                 :             :      end if
    1429                 :             :    end do
    1430                 :             :  end do
    1431                 :             : 
    1432         [ -  + ]:          18 :  if (ierr /= 0) then
    1433                 :             :    write(msg,'(a,i0,3a)')&
    1434                 :           0 :    'Found ',ierr,' G1-G2 vectors falling outside the FFT box. ',ch10,&
    1435                 :           0 :    'Enlarge the FFT mesh to get rid of this problem. '
    1436                 :           0 :    ABI_WARNING(msg)
    1437                 :             :  end if
    1438                 :             : 
    1439                 :             :  ! mm(G,Gp) = (q+G) \cdot (q+Gp) n(G-Gp)
    1440   [ -  +  +  -  :          54 :  ABI_MALLOC_OR_DIE(mm, (npwc,npwc), ierr)
          -  +  +  -  +  
             -  -  +  -  
                      + ]
    1441                 :             : 
    1442         [ +  + ]:         504 :  do ig=1,npwc
    1443         [ +  + ]:         486 :    if (qiszero) then
    1444                 :             :      ! To be discussed with Riad, here we should use the small q
    1445                 :             :      ! to be consistent and consider the limit q-->0
    1446         [ +  + ]:         324 :      gpq(:)=gvec(:,ig)
    1447                 :             :    else
    1448         [ +  + ]:        1620 :      gpq(:)=gvec(:,ig)+qpt
    1449                 :             :    end if
    1450         [ +  + ]:       13626 :    do igp=1,npwc
    1451         [ +  + ]:       13122 :      if (qiszero) then
    1452         [ +  + ]:        8748 :        gppq(:)=gvec(:,igp)
    1453                 :             :      else
    1454         [ +  + ]:       43740 :        gppq(:)=gvec(:,igp)+qpt
    1455                 :             :      end if
    1456                 :       13122 :      qpg_dot_qpgp=zero
    1457         [ +  + ]:       52488 :      do ii=1,3
    1458                 :             :        qpg_dot_qpgp=qpg_dot_qpgp+&
    1459                 :             :         ( gpq(1)*b1(ii) +gpq(2)*b2(ii) +gpq(3)*b3(ii))*&
    1460                 :       52488 :         (gppq(1)*b1(ii)+gppq(2)*b2(ii)+gppq(3)*b3(ii))
    1461                 :             :      end do
    1462                 :       13608 :      mm(ig,igp)=rhogg(ig,igp)*qpg_dot_qpgp
    1463                 :             :    end do !igp
    1464                 :             :  end do !ig
    1465                 :             : 
    1466         [ -  + ]:          18 :  ABI_FREE(rhog_dp)
    1467         [ -  + ]:          18 :  ABI_FREE(rhog)
    1468                 :             :  ! === Now we have rhogg,rho0 ===
    1469                 :             :  !
    1470                 :             :  ! Calculate the dielectric matrix eigenvalues and vectors
    1471                 :             :  ! Use only the static epsm1 i.e., only the w=0 part (eps(:,:,1,:))
    1472   [ -  +  +  -  :          54 :  ABI_MALLOC(eigval,(npwc))
          +  -  +  -  -  
                +  -  + ]
    1473   [ -  +  +  -  :          54 :  ABI_MALLOC_OR_DIE(eigvec, (npwc, npwc), ierr)
          -  +  +  -  +  
             -  -  +  -  
                      + ]
    1474                 :             : 
    1475   [ -  +  +  -  :          54 :  ABI_MALLOC(zz,(npwc))
          +  -  +  -  -  
                +  -  + ]
    1476         [ +  + ]:         504 :  zz=czero
    1477                 :             : 
    1478   [ -  +  +  -  :          36 :  ABI_MALLOC(qplusg,(npwc))
             -  +  -  + ]
    1479                 :             : 
    1480                 :             :  ! Store the susceptibility matrix in upper mode before calling zhpev.
    1481   [ +  -  -  +  :          54 :  ABI_MALLOC_OR_DIE(matr,(npwc*(npwc+1)/2), ierr)
          +  -  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1482                 :             : 
    1483                 :             :  idx=1
    1484         [ +  + ]:         504 :  do ii=1,npwc
    1485         [ +  + ]:        7308 :    do jj=1,ii
    1486                 :        7290 :      matr(idx)=epsm1(jj,ii); idx=idx+1
    1487                 :             :    end do
    1488                 :             :  end do
    1489                 :             : 
    1490   [ +  -  -  +  :          54 :  ABI_MALLOC(zhpev2,(3*npwc-2))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
    1491   [ +  -  -  +  :          54 :  ABI_MALLOC(zhpev1,(2*npwc-1))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
    1492                 :             : 
    1493                 :          18 :  call ZHPEV('V','U',npwc,matr,eigval,eigvec,npwc,zhpev1,zhpev2,ierr)
    1494         [ -  + ]:          18 :  ABI_FREE(matr)
    1495         [ -  + ]:          18 :  ABI_FREE(zhpev2)
    1496         [ -  + ]:          18 :  ABI_FREE(zhpev1)
    1497                 :             : 
    1498         [ -  + ]:          18 :  if (ierr < 0) then
    1499                 :             :    write (msg,'(2a,i0,a)')&
    1500                 :           0 :     ' Failed to calculate the eigenvalues and eigenvectors of the dielectric matrix ',ch10,&
    1501                 :           0 :     ierr*(-1),'-th argument in the matrix has an illegal value. '
    1502                 :           0 :    ABI_ERROR(msg)
    1503                 :             :  end if
    1504                 :             : 
    1505         [ -  + ]:          18 :  if (ierr > 0) then
    1506                 :             :    write(msg,'(3a,i0,2a)')&
    1507                 :           0 :     ' Failed to calculate the eigenvalues and eigenvectors of the dielectric matrix ',ch10,&
    1508                 :           0 :     ' the algorithm failed to converge; ierr = ', ierr,ch10,&
    1509                 :           0 :     ' off-diagonal elements of an intermediate tridiagonal form did not converge to zero. '
    1510                 :           0 :    ABI_ERROR(msg)
    1511                 :             :  end if
    1512                 :             : 
    1513                 :             :  ! Calculate the PPM parameters and the eigenpotentials needed for
    1514                 :             :  ! the calculation of the generalized overlap matrix
    1515                 :             :  ! Note: the eigenpotentials has to be calculated on the FFT (G-Gp) index
    1516                 :             :  !
    1517                 :             :  ! Save eigenvectors of \tilde\epsilon^{-1}
    1518                 :             :  ! MG well it is better to save \Theta otherwise
    1519                 :             :  ! we have to calculare \Theta for each band, spin, k-point but oh well
    1520   [ +  +  +  + ]:       13626 :  eigtot=eigvec
    1521                 :             : 
    1522                 :          18 :  qlist(:,1) = qpt
    1523                 :          18 :  call cmod_qpg(1,1,qlist,npwc,gvec,gprimd,qplusg) !MG TODO here take care of small q
    1524                 :             :  !
    1525                 :             :  ! Basic Equation:
    1526                 :             :  !
    1527                 :             :  ! \Theta_{q,ii}(G)=\Psi_{q,ii}(G)/|q+G|
    1528                 :             :  ! where \Psi_{q,ii}(G) is the eigenvector of \tilde\epsilon^{-1}
    1529                 :             : 
    1530                 :             :  ! \tilde\omega_{ii,q}^2= 4\pi (1-eigenval(ii,q)))
    1531                 :             :  ! \sum_{G,Gp} \Theta^*_{q,ii}(G) (q+G)\cdot(q+Gp) n(G-Gp) \Theta_{q,ii}(Gp)
    1532                 :             : 
    1533         [ +  + ]:         504 :  do ii=1,npwc !DM band
    1534                 :             :    ! Calculate \Theta_{q,ii}(G)
    1535                 :             :    ! why the first element is not modified? if the problem is the small value of qplusg(1)
    1536                 :             :    ! we could multiply by sqrt(mod((q+G)(q+G'))) and then add the sing at the end
    1537         [ +  + ]:         486 :    if (qiszero)then
    1538         [ +  + ]:        2187 :      eigvec(2:,ii)=eigvec(2:,ii)/qplusg(2:)
    1539                 :             :    else
    1540         [ +  + ]:       11340 :      eigvec(:,ii)=eigvec(:,ii)/qplusg(:)
    1541                 :             :    end if
    1542         [ +  + ]:       13608 :    do ig=1,npwc
    1543                 :       13122 :      conjg_eig=CONJG(eigvec(ig,ii))
    1544         [ +  + ]:      367902 :      do igp=1,npwc
    1545   [ +  +  +  + ]:      367416 :        if(qiszero .and. ig==1 .and. igp==1)then
    1546                 :          81 :          zz(ii)=zz(ii)+conjg_eig*rhogg(ig,igp)*eigvec(igp,ii)
    1547                 :             :        else
    1548                 :      354213 :          zz(ii)=zz(ii)+conjg_eig*mm(ig,igp)*eigvec(igp,ii)
    1549                 :             :        end if
    1550                 :             :      end do
    1551                 :             :    end do
    1552                 :             : 
    1553                 :         486 :    num=one-eigval(ii)
    1554         [ +  - ]:         486 :    if (num<=zero) then
    1555                 :             :      ! here I think we should set bigomegatwsq=0 and omegatw to an arbitrary value
    1556                 :             :      ! maybe we can output a warning TO BE discussed with Riad
    1557         [ #  # ]:           0 :      if (ABS(num)<1.0d-4) then
    1558                 :             :        num=1.0d-5
    1559                 :             :      else
    1560                 :           0 :        ABI_ERROR("One or more imaginary plasmon pole energies")
    1561                 :             :      end if
    1562                 :             :    end if
    1563                 :             : 
    1564                 :         486 :    omegatw(ii)=SQRT(4*pi*REAL(zz(ii))/num)
    1565                 :             :    ! this should be \alpha = 2\pi omegatw * (1-eigenval)
    1566                 :             :    ! MG check this, in the review I found a factor 2\pi, maybe it is reintroduced later
    1567                 :         504 :    bigomegatwsq(ii,1)=num*omegatw(ii)
    1568                 :             :  end do
    1569                 :             : 
    1570         [ -  + ]:          18 :  ABI_FREE(rhogg)
    1571         [ -  + ]:          18 :  ABI_FREE(mm)
    1572         [ -  + ]:          18 :  ABI_FREE(eigval)
    1573         [ -  + ]:          18 :  ABI_FREE(zz)
    1574         [ -  + ]:          18 :  ABI_FREE(eigvec)
    1575         [ -  + ]:          18 :  ABI_FREE(qplusg)
    1576                 :             : 
    1577                 :          18 :  call destroy_mpi_enreg(MPI_enreg_seq)
    1578                 :             : 
    1579                 :          18 :  write(msg,'(2a,f12.8,2a,3i5)')ch10,&
    1580   [ +  -  -  +  :         522 :   ' cppm3par : omega twiddle minval [eV]  = ',MINVAL(ABS(omegatw))*Ha_eV,ch10,&
             -  -  +  + ]
    1581   [ +  -  -  +  :         540 :   '            omega twiddle min location = ',MINLOC(ABS(omegatw))
          -  -  +  +  +  
                +  +  + ]
    1582                 :          18 :  call wrtout(std_out,msg)
    1583                 :             : 
    1584   [ -  +  -  +  :          18 : end subroutine cppm3par
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                +  -  + ]
    1585                 :             : !!***
    1586                 :             : 
    1587                 :             : !----------------------------------------------------------------------
    1588                 :             : 
    1589                 :             : !!****f* m_ppmodel/cppm4par
    1590                 :             : !! NAME
    1591                 :             : !! cppm4par
    1592                 :             : !!
    1593                 :             : !! FUNCTION
    1594                 :             : !! Calculate the plasmon-pole parameters using Engel-Farid model (PRB47,15931,1993) [[cite:Engel1993]].
    1595                 :             : !! See also Quasiparticle Calculations in Solids [[cite:Aulbur2001]] page. 23.
    1596                 :             : !!
    1597                 :             : !! INPUTS
    1598                 :             : !!  qpt(3)=Reduced coordinates of the q-point.
    1599                 :             : !!  npwc=number of plane waves in epsm1
    1600                 :             : !!  epsm1(npwc,npwc)=symmetrized inverse dielectric matrix.
    1601                 :             : !!  ngfftf(18)=contain all needed information about 3D fine FFT, see ~abinit/doc/variables/vargs.htm#ngfft
    1602                 :             : !!  gvec(3,npwc)=G vectors in reduced coordinated
    1603                 :             : !!  gprimd(3,3)=dimensional primitive translations for reciprocal space ($\textrm{bohr}^{-1}$)
    1604                 :             : !!  rhor(nfftf)=charge density on the real space FFT grid
    1605                 :             : !!  nfftf=Number of FFT points.
    1606                 :             : !!
    1607                 :             : !! OUTPUT
    1608                 :             : !!  bigomegatwsq(npwc,npwc)=plasmon-pole strength.
    1609                 :             : !!  omegatw(npwc)=plasmon-pole frequencies.
    1610                 :             : !!
    1611                 :             : !! SOURCE
    1612                 :             : 
    1613                 :          18 : subroutine cppm4par(qpt, npwc, epsm1, ngfftf, gvec, gprimd, rhor, nfftf, bigomegatwsq, omegatw)
    1614                 :             : 
    1615                 :             : !Arguments ------------------------------------
    1616                 :             : !scalars
    1617                 :             :  integer,intent(in) :: nfftf,npwc
    1618                 :             : !arrays
    1619                 :             :  integer,intent(in) :: gvec(3,npwc),ngfftf(18)
    1620                 :             :  real(dp),intent(in) :: gprimd(3,3),qpt(3), rhor(nfftf)
    1621                 :             :  complex(gwp),intent(in) :: epsm1(npwc,npwc)
    1622                 :             :  complex(gwp),intent(out) :: bigomegatwsq(npwc,npwc),omegatw(npwc)
    1623                 :             : 
    1624                 :             : !Local variables-------------------------------
    1625                 :             : !scalars
    1626                 :             :  integer :: ierr,ig,igp,ii,ngfft1,ngfft2,ngfft3,gmgp_idx
    1627                 :             :  real(dp) :: qpg_dot_qpgp
    1628                 :             :  character(len=500) :: msg
    1629                 :             :  character(len=80) :: bar
    1630                 :          18 :  type(MPI_type) :: MPI_enreg_seq
    1631                 :             : !arrays
    1632                 :             :  real(dp) :: b1(3),b2(3),b3(3),gppq(3),gpq(3),qlist(3,1)
    1633                 :          18 :  real(dp),allocatable :: eigval(:),qplusg(:),rhog_dp(:,:),tmp_rhor(:)
    1634                 :          18 :  complex(dp),allocatable :: chi(:,:), mm(:,:),mtemp(:,:),rhog(:), tmp1(:),zz2(:,:)
    1635                 :             : !*************************************************************************
    1636                 :             : 
    1637                 :             :  ! Calculate density in G space rhog(G)
    1638                 :             :  ! FIXME this has to be fixed, rho(G) should be passed instead of doing FFT for each q
    1639                 :          18 :  call initmpi_seq(MPI_enreg_seq)
    1640                 :          18 :  call MPI_enreg_seq%distribfft%init_seq('c',ngfftf(2),ngfftf(3),'all')
    1641                 :             : 
    1642   [ -  +  +  -  :          54 :  ABI_MALLOC(rhog_dp, (2,nfftf))
          +  -  +  -  -  
                +  -  + ]
    1643                 :             : 
    1644                 :             :  ! Conduct FFT tho(r)-->rhog(G)
    1645   [ -  +  +  -  :          54 :  ABI_MALLOC(tmp_rhor,(nfftf))
          +  -  +  -  -  
                +  -  + ]
    1646   [ -  +  +  + ]:       65112 :  tmp_rhor = rhor ! To avoid having to use intent(inout).
    1647                 :          18 :  call fourdp(1,rhog_dp,tmp_rhor,-1,MPI_enreg_seq,nfftf,1,ngfftf,0)
    1648                 :             : 
    1649         [ -  + ]:          18 :  ABI_FREE(tmp_rhor)
    1650                 :          18 :  call destroy_mpi_enreg(MPI_enreg_seq)
    1651                 :             : 
    1652   [ -  +  +  -  :          54 :  ABI_MALLOC(rhog, (nfftf))
          +  -  +  -  -  
                +  -  + ]
    1653         [ +  + ]:       65094 :  rhog(1:nfftf)=CMPLX(rhog_dp(1,1:nfftf),rhog_dp(2,1:nfftf))
    1654         [ -  + ]:          18 :  ABI_FREE(rhog_dp)
    1655                 :             : 
    1656                 :             :  ! Calculate the FFT index of each (G-Gp) vector and assign the value
    1657                 :             :  ! of the correspondent density simultaneously
    1658                 :          18 :  ngfft1=ngfftf(1)
    1659                 :          18 :  ngfft2=ngfftf(2)
    1660                 :          18 :  ngfft3=ngfftf(3)
    1661                 :             : 
    1662   [ -  +  +  -  :          72 :  ABI_MALLOC_OR_DIE(mm, (npwc,npwc), ierr)
          -  +  +  -  +  
          -  +  -  +  -  
             -  +  -  + ]
    1663                 :             : 
    1664                 :          18 :  ierr = 0
    1665         [ +  + ]:         504 :  do ig=1,npwc
    1666         [ +  + ]:       13626 :    do igp=1,npwc
    1667         [ +  + ]:       52488 :      gmgp_idx = g2ifft(gvec(:,ig)-gvec(:,igp),ngfftf)
    1668         [ +  - ]:       13608 :      if (gmgp_idx /= 0) then
    1669                 :       13122 :        mm(ig,igp) = rhog(gmgp_idx)
    1670                 :             :      else
    1671                 :           0 :        ierr = ierr + 1
    1672                 :           0 :        mm(ig,igp) = czero
    1673                 :             :      end if
    1674                 :             :    end do
    1675                 :             :  end do
    1676                 :             : 
    1677         [ -  + ]:          18 :  if (ierr /= 0) then
    1678                 :             :    write(msg,'(a,i0,3a)')&
    1679                 :           0 :     'Found ',ierr,' G1-G2 vectors falling outside the FFT box. ',ch10,&
    1680                 :           0 :     'Enlarge the FFT mesh to get rid of this problem. '
    1681                 :           0 :    ABI_WARNING(msg)
    1682                 :             :  end if
    1683                 :             : 
    1684         [ -  + ]:          18 :  ABI_FREE(rhog)
    1685                 :             : 
    1686                 :             :  ! Now we have rhogg, calculate the M matrix (q+G1).(q+G2) n(G1-G2)
    1687   [ +  +  +  +  :         180 :  b1=two_pi*gprimd(:,1); b2=two_pi*gprimd(:,2); b3=two_pi*gprimd(:,3)
                   +  + ]
    1688         [ +  + ]:         504 :  do ig=1,npwc
    1689         [ +  + ]:        1944 :    gpq(:)=gvec(:,ig)+qpt
    1690         [ +  + ]:       13626 :    do igp=1,npwc
    1691         [ +  + ]:       52488 :      gppq(:)=gvec(:,igp)+qpt
    1692                 :             :      qpg_dot_qpgp=zero
    1693         [ +  + ]:       52488 :      do ii=1,3
    1694                 :             :        qpg_dot_qpgp = qpg_dot_qpgp + &
    1695                 :             :          ( gpq(1)*b1(ii) +gpq(2)*b2(ii) +gpq(3)*b3(ii))*&
    1696                 :       52488 :          (gppq(1)*b1(ii)+gppq(2)*b2(ii)+gppq(3)*b3(ii))
    1697                 :             :      end do
    1698                 :       13608 :      mm(ig,igp) = mm(ig,igp)*qpg_dot_qpgp
    1699                 :             :    end do ! igp
    1700                 :             :  end do ! ig
    1701                 :             : 
    1702                 :             :  ! Extract the reducible polarizability chi: e^{-1} = 1 + v chi
    1703                 :             :  ! \tilde\epsilon^{-1}_{G1 G2} = \delta_{G1 G2} + 4\pi \frac{\chi_{G1 G2}}{|q+G1| |q+G2|}
    1704                 :             :  !MG TODO too much memory in chi, we can do all this stuff inside a loop
    1705   [ -  +  +  -  :          54 :  ABI_MALLOC_OR_DIE(chi, (npwc,npwc), ierr)
          -  +  +  -  +  
             -  -  +  -  
                      + ]
    1706   [ -  +  +  -  :          54 :  ABI_MALLOC(qplusg, (npwc))
          +  -  +  -  -  
                +  -  + ]
    1707                 :             : 
    1708   [ +  +  +  + ]:       13626 :  chi(:,:)=epsm1(:,:)
    1709                 :          18 :  qlist(:,1) = qpt
    1710                 :          18 :  call cmod_qpg(1,1,qlist,npwc,gvec,gprimd,qplusg) !MG TODO here take care of small q
    1711                 :             : 
    1712         [ +  + ]:         504 :  do ig=1,npwc
    1713                 :         504 :    chi(ig,ig)=chi(ig,ig) - one
    1714                 :             :  end do
    1715                 :             : 
    1716         [ +  + ]:         504 :  do ig=1,npwc
    1717         [ +  + ]:       13626 :    do igp=1,npwc
    1718                 :       13608 :      chi(ig,igp) = chi(ig,igp) * qplusg(ig) * qplusg(igp) / four_pi
    1719                 :             :    end do
    1720                 :             :  end do
    1721                 :             : 
    1722                 :             :  ! Solve chi(w=)*X = Lambda M*X where Lambda=-1/em(q)**2
    1723   [ -  +  +  -  :          36 :  ABI_MALLOC(eigval, (npwc))
             -  +  -  + ]
    1724   [ -  +  +  -  :          54 :  ABI_MALLOC_OR_DIE(mtemp, (npwc,npwc), ierr)
          -  +  +  -  +  
             -  -  +  -  
                      + ]
    1725                 :             : 
    1726                 :             :  ! Copy mm into working array as xhegv changes input matrices
    1727   [ +  +  +  + ]:       13626 :  mtemp(:,:) = mm(:,:)
    1728                 :             : 
    1729                 :          18 :  call xhegv(1,"Vectors","Upper",npwc,chi,mtemp,eigval)
    1730         [ -  + ]:          18 :  ABI_FREE(mtemp)
    1731                 :             : 
    1732                 :             :  ! Now chi contains the eigenvectors.
    1733                 :             :  ! Eigenvectors are normalized as: X_i^* M X_j = \delta_{ij}
    1734                 :             : 
    1735                 :             :  ! Calculate the plasmon pole parameters
    1736                 :             :  ! good check: the lowest plasmon energy on gamma should be
    1737                 :             :  ! close to experimental plasma energy within an error of 10%
    1738                 :             :  ! this error can be reduced further if one includes the non local
    1739                 :             :  ! commutators in the calculation of the polarizability at q==0
    1740                 :             : 
    1741   [ -  +  +  -  :          54 :  ABI_MALLOC(tmp1,(npwc))
          +  -  +  -  -  
                +  -  + ]
    1742   [ -  +  +  -  :          54 :  ABI_MALLOC_OR_DIE(zz2, (npwc, npwc), ierr)
          -  +  +  -  +  
             -  -  +  -  
                      + ]
    1743   [ +  +  +  + ]:       13626 :  zz2(:,:)= zero
    1744                 :             : 
    1745                 :             :  ! Caller is responsible for handing small q case
    1746                 :          18 :  qlist(:,1) = qpt
    1747                 :          18 :  call cmod_qpg(1,1,qlist,npwc,gvec,gprimd,qplusg)
    1748                 :             : 
    1749         [ +  + ]:         504 :  do ii=1,npwc
    1750                 :             :    ! keeping in mind that the above matrix is negative definite
    1751                 :             :    ! we might have a small problem with the eigvals corresponding to large G vectors
    1752                 :             :    ! i.e. DM band index, where the eigevalues become very small with
    1753                 :             :    ! possibility of being small positive numbers (due to numerical problems)
    1754                 :             :    ! thus as a caution one can use the following condition
    1755                 :             :    ! this will not affect the result since such a huge plasmon energy give almost zero
    1756                 :             :    ! contribution to the self-energy correlation energy.
    1757                 :             : 
    1758         [ -  + ]:         486 :    if (eigval(ii)>=zero) then
    1759                 :             :      !write(msg,'(a,i0,a,es16.6)')' Imaginary plasmon pole eigenenergy, eigenvector number ',ii,' with eigval',eigval(ii),ch10
    1760                 :             :      !ABI_ERROR(msg)
    1761                 :           0 :      eigval(ii) = -1.0d-4
    1762                 :             :    end if
    1763                 :             : 
    1764                 :             :    ! Save plasmon energies omega_p(q)
    1765                 :         486 :    omegatw(ii) = SQRT(-one/eigval(ii))
    1766                 :             : 
    1767                 :             :    ! Calculate and save scaled plasmon-pole eigenvectors
    1768                 :             :    ! defined as \sqrt{4\pi} \frac{Mx}{\sqrt{\tilde\omega} |q+G|}
    1769         [ +  + ]:       13608 :    tmp1(:)=chi(:,ii)
    1770                 :             : 
    1771         [ +  + ]:       13626 :    do ig=1,npwc
    1772         [ +  + ]:      367416 :      do igp=1,npwc
    1773                 :      367416 :        zz2(ig,ii)=zz2(ig,ii)+mm(ig,igp)*tmp1(igp) ! z --> y
    1774                 :             :      end do
    1775                 :       13608 :      bigomegatwsq(ig,ii)= SQRT(four_pi) * zz2(ig,ii) / SQRT(omegatw(ii)) / qplusg(ig)
    1776                 :             :    end do
    1777                 :             : 
    1778                 :             :  end do ! ii
    1779                 :             : 
    1780         [ -  + ]:          18 :  ABI_FREE(tmp1)
    1781         [ -  + ]:          18 :  ABI_FREE(eigval)
    1782         [ -  + ]:          18 :  ABI_FREE(zz2)
    1783         [ -  + ]:          18 :  ABI_FREE(qplusg)
    1784         [ -  + ]:          18 :  ABI_FREE(chi)
    1785         [ -  + ]:          18 :  ABI_FREE(mm)
    1786                 :             : 
    1787                 :          18 :  bar = repeat('-', 80)
    1788                 :          18 :  write(msg,'(3a)')bar,ch10,' plasmon energies in eV vs q vector shown for the lowest 10 bands'
    1789                 :          18 :  call wrtout(std_out,msg)
    1790   [ +  -  +  + ]:         198 :  write(msg,'(2x,5x,10f7.3)')(REAL(omegatw(ig))*Ha_eV, ig=1,min(10, npwc))
    1791                 :          18 :  call wrtout(std_out,msg)
    1792                 :          18 :  write(msg,'(a)')bar
    1793                 :          18 :  call wrtout(std_out,msg)
    1794                 :             : 
    1795                 :          18 :  write(msg,'(2a,f12.8,2a,3i5)')ch10,&
    1796   [ +  -  -  +  :         522 :   ' cppm4par: omega twiddle minval [eV]  = ',MINVAL(ABS(omegatw))*Ha_eV,ch10,&
             -  -  +  + ]
    1797   [ +  -  -  +  :         540 :   '           omega twiddle min location = ',MINLOC(ABS(omegatw))
          -  -  +  +  -  
                +  +  + ]
    1798                 :          18 :  call wrtout(std_out,msg)
    1799                 :             : 
    1800   [ -  +  -  +  :          18 : end subroutine cppm4par
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                +  -  + ]
    1801                 :             : !!***
    1802                 :             : 
    1803                 :             : !----------------------------------------------------------------------
    1804                 :             : 
    1805                 :             : !!****f* m_ppmodel/cqratio
    1806                 :             : !! NAME
    1807                 :             : !! cqratio
    1808                 :             : !!
    1809                 :             : !! FUNCTION
    1810                 :             : !!  Calculate qratio(G,Gp,q)= (q+G)\cdot(q+Gp) / |q+G|^2 needed for Hybertsen-Louie and Plasmonpole model
    1811                 :             : !!
    1812                 :             : !! INPUTS
    1813                 :             : !!  npwc=number of planewaves considered (used for the correlation part)
    1814                 :             : !!  gvec(3,npwc)=reduced coordinates of the plane waves
    1815                 :             : !!  q(3)=coordinates of q points
    1816                 :             : !!  gmet(3,3)=metric in reciprocal space
    1817                 :             : !!  gprimd(3,3)=reciprocal lattice vectors
    1818                 :             : !!
    1819                 :             : !! OUTPUT
    1820                 :             : !!  qratio(npwc,npwc)=(q+G).(q+Gp)
    1821                 :             : !!
    1822                 :             : !! SOURCE
    1823                 :             : 
    1824                 :          24 : subroutine cqratio(npwc, gvec, q, gmet, gprimd, qratio)
    1825                 :             : 
    1826                 :             : !Arguments ------------------------------------
    1827                 :             : !scalars
    1828                 :             :  integer,intent(in) :: npwc
    1829                 :             : !arrays
    1830                 :             :  integer,intent(in) :: gvec(3,npwc)
    1831                 :             :  real(dp),intent(in) :: gmet(3,3),gprimd(3,3),q(3)
    1832                 :             :  real(dp),intent(out) :: qratio(npwc,npwc)
    1833                 :             : 
    1834                 :             : !Local variables ------------------------------
    1835                 :             : !scalars
    1836                 :             :  integer :: ig,igp,ii
    1837                 :             :  real(dp),parameter :: tol = 0.001_dp
    1838                 :             :  real(dp) :: qpg_dot_qpgp
    1839                 :             : !arrays
    1840                 :          24 :  real(dp) :: b1(3),b2(3),b3(3),gppq(3),gpq(3),norm(npwc)
    1841                 :             : !************************************************************************
    1842                 :             : 
    1843   [ +  +  +  +  :         240 :  b1=two_pi*gprimd(:,1); b2=two_pi*gprimd(:,2); b3=two_pi*gprimd(:,3)
                   +  + ]
    1844                 :             : 
    1845   [ +  +  +  +  :       21048 :  norm(:)=zero; qratio=zero
                   +  + ]
    1846                 :             : 
    1847                 :             :  !FIXME this loops have to be rewritten!!!!
    1848         [ +  + ]:         708 :  do ig=1,npwc
    1849         [ +  + ]:        2736 :    gpq(:)=gvec(:,ig)+q
    1850   [ +  +  +  +  :       10968 :    norm(ig)=two_pi*SQRT(DOT_PRODUCT(gpq,MATMUL(gmet,gpq)))
                   +  + ]
    1851                 :             :    !norm(ig)=normv(gpq,gmet,'g')
    1852                 :             :  end do
    1853                 :             : 
    1854         [ +  + ]:         708 :  do ig=1,npwc
    1855         [ +  + ]:        2736 :    gpq(:)=gvec(:,ig)+q
    1856         [ +  + ]:       20364 :    do igp=1,npwc
    1857         [ +  + ]:       78624 :      gppq(:)=gvec(:,igp)+q
    1858                 :             :      qpg_dot_qpgp=zero
    1859                 :             :      !qpg_dot_qpgp=vdotw(gpq,gppq,gmet,'g')
    1860         [ +  + ]:       78624 :      do ii=1,3
    1861                 :             :        qpg_dot_qpgp=qpg_dot_qpgp+&
    1862                 :             :         ( gpq(1)*b1(ii) +  gpq(2)*b2(ii) + gpq(3)*b3(ii))*&
    1863                 :       78624 :         (gppq(1)*b1(ii) + gppq(2)*b2(ii) +gppq(3)*b3(ii))
    1864                 :             :      end do
    1865                 :             : 
    1866                 :             :      ! Now calculate qratio = (q+G).(q+Gp)/|q+G|^2
    1867                 :             :      ! when |q+G|^2 and (q+G).(q+Gp) are both zero set (q+G).(q+Gp)/|q+G|^2 = 1
    1868                 :             :      ! when |q+G|^2 is zero and |q+Gp| is not zero set (q+G).(q+Gp)/|q+G|^2 = 0
    1869         [ +  + ]:       20340 :      if (norm(ig) < tol) then
    1870         [ +  + ]:         114 :        if (norm(igp) < tol) then     ! Case q=0 and G=Gp=0
    1871                 :           4 :          qratio(ig,igp) = one
    1872                 :             :        else                          ! Case q=0 and G=0 and Gp !=0
    1873                 :         110 :          qratio(ig,igp) = zero
    1874                 :             :        end if
    1875         [ +  + ]:       19542 :      else if (norm(igp) < tol) then  ! Case q=0 and G= !0 and Gp=0
    1876                 :         110 :        qratio(ig,igp)=zero
    1877                 :             :      else
    1878                 :       19432 :        qratio(ig,igp)=qpg_dot_qpgp / norm(ig)**2
    1879                 :             :      end if
    1880                 :             : 
    1881                 :             :    end do
    1882                 :             :  end do
    1883                 :             : 
    1884                 :          24 : end subroutine cqratio
    1885                 :             : !!***
    1886                 :             : 
    1887                 :             : !----------------------------------------------------------------------
    1888                 :             : 
    1889                 :             : !!****f* m_ppmodel/ppm_calc_sigc
    1890                 :             : !!
    1891                 :             : !! NAME
    1892                 :             : !! ppm_calc_sigc
    1893                 :             : !!
    1894                 :             : !! FUNCTION
    1895                 :             : !!  Calculate the contribution to self-energy operator for a single band s in the band sum
    1896                 :             : !!  using a plasmon-pole model.
    1897                 :             : !!
    1898                 :             : !! INPUTS
    1899                 :             : !!  nspinor=Number of spinor components.
    1900                 :             : !!  npwc=Number of G vectors in the plasmon pole (correlation part)
    1901                 :             : !!  nomega=Number of frequencies.
    1902                 :             : !!  rhotwgp(npwx)=oscillator matrix elements divided by |q+G| i.e. $\frac{\langle b1 k-q s | e^{-i(q+G)r | b2 k s \rangle}{|q+G|}$.
    1903                 :             : !!  botsq(npwc,dm2_botsq)=Plasmon pole parameters for this q-point.
    1904                 :             : !!  otq(npwc,dm2_otq)=Plasmon pole parameters for this q-point.
    1905                 :             : !!  omegame0i(nomega)=($\omega$ - $\epsilon_i)$
    1906                 :             : !!  zcut=Small imaginary part to avoid the divergence. (see related input variable)
    1907                 :             : !!  theta_mu_minus_e0i= $\theta(\mu-\epsilon_{k-q,b1,s}), defines if the state is occupied or not.
    1908                 :             : !!  eig(dm_eig,dm_eig)=The eigvectors of the symmetrized inverse dielectric matrix for this q point
    1909                 :             : !!    (first index for G, second index for bands).
    1910                 :             : !!  npwx=number of G vectors in rhotwgp.
    1911                 :             : !!
    1912                 :             : !! OUTPUT
    1913                 :             : !!  ket(npwc,nomega):
    1914                 :             : !!
    1915                 :             : !!  === model==1,2 ====
    1916                 :             : !!
    1917                 :             : !!    ket(G,omega) += Sum_G2                 Omega(G,G2) * rhotw(G2)
    1918                 :             : !!                            ---------------------------------------------------
    1919                 :             : !!                             2 omegatw(G,G2) (omega - E_i + omegatw(G,G2)(2f-1))
    1920                 :             : !!
    1921                 :             : !!  sigcme(nomega) (to be described), only relevant if ppm3 or ppm4
    1922                 :             : !!
    1923                 :             : !! NOTES
    1924                 :             : !!  The i/two_pi factor in the convolution between G and W is included in this routine.
    1925                 :             : !!
    1926                 :             : !! TODO:
    1927                 :             : !!  Use BLAS for better efficiency
    1928                 :             : !!
    1929                 :             : !! SOURCE
    1930                 :             : 
    1931                 :     1558650 : subroutine ppm_calc_sigc(ppm, nspinor, npwc, nomega, rhotwgp, botsq, otq, &
    1932                 :     1558650 :                          omegame0i, zcut, theta_mu_minus_e0i, eig, npwx, ket, sigcme)
    1933                 :             : 
    1934                 :             : !Arguments ------------------------------------
    1935                 :             : !scalars
    1936                 :             :  class(ppmodel_t),intent(in) :: ppm
    1937                 :             :  integer,intent(in) :: nomega, npwc, npwx, nspinor
    1938                 :             :  real(dp),intent(in) :: theta_mu_minus_e0i, zcut
    1939                 :             : !arrays
    1940                 :             :  real(dp),intent(in) :: omegame0i(nomega)
    1941                 :             :  complex(gwp),intent(in) :: botsq(npwc, ppm%dm2_botsq), eig(ppm%dm_eig, ppm%dm_eig), otq(npwc, ppm%dm2_otq)
    1942                 :             :  complex(gwp),intent(in) :: rhotwgp(npwx, nspinor)
    1943                 :             :  complex(gwp),intent(inout) :: ket(npwc, nspinor, nomega)
    1944                 :             :  complex(gwp),intent(out) :: sigcme(nomega)
    1945                 :             : 
    1946                 :             : !Local variables-------------------------------
    1947                 :             : !scalars
    1948                 :             :  integer :: ig,igp,ii,iw,ispinor
    1949                 :             :  real(dp),parameter :: tol_occ = tol3, tol_omega = tol6
    1950                 :             :  real(dp) :: den, den2, ff, inv_den, omegame0i_io, otw, twofm1, twofm1_zcut, twofm1_zcut2, zcut2
    1951                 :             :  complex(gwp) :: ct, num, numf, rhotwgdp_igp
    1952                 :             :  logical :: fully_occupied, totally_empty
    1953                 :             :  !character(len=500) :: msg
    1954                 :             : !arrays
    1955                 :     1558650 :  complex(gwp),allocatable :: rhotwgdpcc(:)
    1956                 :             : !*************************************************************************
    1957                 :             : 
    1958                 :     1558650 :  zcut2 = zcut ** 2
    1959                 :             : 
    1960                 :     3113460 :  select case (ppm%model)
    1961                 :             : 
    1962                 :             :  case (PPM_GODBY_NEEDS, PPM_HYBERTSEN_LOUIE)
    1963                 :     1554810 :    fully_occupied = (abs(theta_mu_minus_e0i-one) < tol_occ)
    1964                 :     1554810 :    totally_empty  = (abs(theta_mu_minus_e0i    ) < tol_occ)
    1965                 :             : 
    1966         [ +  + ]:     3116340 :    do ispinor=1,nspinor
    1967                 :             : 
    1968         [ +  + ]:     1561530 :      if (.not. totally_empty) then
    1969                 :             :        ! \Bomega^2_{G1G2}/\omegat_{G1G2} M_{G1,G2}. \theta(\mu-e_s) / (\omega+\omegat_{G1G2}-e_s-i\delta)
    1970                 :     4436630 :        twofm1_zcut = zcut
    1971                 :     4436630 :        twofm1_zcut2 = zcut2
    1972                 :             : !$omp parallel do private(omegame0i_io, rhotwgdp_igp, otw, num, den, den2)
    1973         [ +  + ]:     4436630 :        do iw=1,nomega
    1974                 :     3915487 :          omegame0i_io = omegame0i(iw)
    1975                 :             :          !if (iw > 1 .and. abs(omegame0i(iw) - omegame0i(iw-1)) < tol_omega) then
    1976                 :             :          !  ket(:,:,iw) = ket(:,:,iw-1); cycle
    1977                 :             :          !end if
    1978                 :             : 
    1979         [ +  + ]:    96965859 :          do igp=1,npwc
    1980                 :    92529229 :            rhotwgdp_igp = rhotwgp(igp, ispinor)
    1981         [ +  + ]:  4833905347 :            do ig=1,npwc
    1982                 :  4737460631 :              otw = DBLE(otq(ig,igp)) !in principle otw -> otw - ieta
    1983                 :  4737460631 :              num = botsq(ig,igp) * rhotwgdp_igp
    1984                 :  4737460631 :              den = omegame0i_io + otw
    1985                 :  4737460631 :              den2 = den ** 2
    1986         [ +  + ]:  4829989860 :              if (den2 > zcut2) then
    1987                 :  4734382654 :                ket(ig,ispinor, iw) = ket(ig,ispinor,iw) + num/(den*otw) * theta_mu_minus_e0i
    1988                 :             :              else
    1989                 :             :                ket(ig,ispinor,iw) = ket(ig,ispinor,iw) + &
    1990                 :     3077977 :                  num * CMPLX(den,twofm1_zcut) / ((den2 + twofm1_zcut2) * otw) * theta_mu_minus_e0i
    1991                 :             :              end if
    1992                 :             :            end do ! ig
    1993                 :             :          end do ! igp
    1994                 :             :        end do ! iw
    1995                 :             :      end if ! not totally empty
    1996                 :             : 
    1997         [ +  + ]:     3116340 :      if (.not. fully_occupied) then
    1998                 :             :        ! \Bomega^2_{G1G2}/\omegat_{G1G2} M_{G1,G2}. \theta(e_s-\mu) / (\omega-\omegat_{G1G2}-e_s+i\delta)
    1999                 :     1041183 :        twofm1_zcut = -zcut
    2000                 :     1041183 :        twofm1_zcut2 = twofm1_zcut**2
    2001                 :             : !$omp parallel do private(omegame0i_io, rhotwgdp_igp, otw, num, den, den2)
    2002         [ +  + ]:    18225046 :        do iw=1,nomega
    2003                 :    17183863 :          omegame0i_io = omegame0i(iw)
    2004                 :             :          !if (iw > 1 .and. abs(omegame0i(iw) - omegame0i(iw-1)) < tol_omega) then
    2005                 :             :          !  ket(:,:,iw) = ket(:,:,iw-1); cycle
    2006                 :             :          !end if
    2007                 :             : 
    2008         [ +  + ]:   464817479 :          do igp=1,npwc
    2009                 :   446592433 :            rhotwgdp_igp = rhotwgp(igp, ispinor)
    2010         [ +  + ]: 31046850919 :            do ig=1,npwc
    2011                 : 30583074623 :              otw = DBLE(otq(ig,igp)) !in principle otw -> otw + ieta
    2012                 : 30583074623 :              num = botsq(ig,igp) * rhotwgdp_igp
    2013                 : 30583074623 :              den = omegame0i_io - otw
    2014                 : 30583074623 :              den2 = den ** 2
    2015         [ +  + ]: 31029667056 :              if (den2 > zcut2) then
    2016                 : 30582157413 :                ket(ig,ispinor,iw) = ket(ig,ispinor, iw) + num / (den*otw) * (one-theta_mu_minus_e0i)
    2017                 :             :              else
    2018                 :             :                ket(ig,ispinor, iw) = ket(ig,ispinor,iw) + &
    2019                 :      917210 :                  num * CMPLX(den,twofm1_zcut) / ((den2 + twofm1_zcut2) * otw) * (one-theta_mu_minus_e0i)
    2020                 :             :              end if
    2021                 :             :            end do ! ig
    2022                 :             :          end do ! igp
    2023                 :             :        end do ! iw
    2024                 :             :      end if ! not fully occupied
    2025                 :             : 
    2026                 :             :    end do ! ispinor
    2027                 :             : 
    2028   [ +  +  +  +  :   582613416 :    ket=ket*half
                   +  + ]
    2029                 :             : 
    2030                 :             :  case (PPM_LINDEN_HORSH, PPM_ENGEL_FARID)
    2031         [ -  + ]:        3840 :    ABI_CHECK(nspinor == 1, "nspinor/=1 not allowed")
    2032                 :             : 
    2033                 :             :    ! rho-twiddle(G) is formed, introduce rhotwgdpcc, for speed reason
    2034   [ -  +  +  -  :       11520 :    ABI_MALLOC(rhotwgdpcc, (npwx))
          +  -  +  -  -  
                +  -  + ]
    2035                 :             : 
    2036                 :        3840 :    ff = theta_mu_minus_e0i      ! occupation number f (include poles if ...)
    2037                 :        3840 :    twofm1 = two*ff-one          ! 2f-1
    2038                 :        3840 :    twofm1_zcut = twofm1*zcut
    2039         [ +  + ]:      107520 :    rhotwgdpcc(:) = CONJG(rhotwgp(:, 1))
    2040                 :             : 
    2041         [ +  + ]:       33280 :    do iw=1,nomega
    2042                 :       29440 :      omegame0i_io = omegame0i(iw)
    2043                 :       29440 :      ct = czero_gw
    2044         [ +  + ]:      824320 :      do ii=1,npwc ! Loop over the DM bands
    2045                 :      794880 :        num = czero_gw
    2046                 :             : 
    2047                 :      794880 :        select case (ppm%model)
    2048                 :             :        case (PPM_LINDEN_HORSH)
    2049                 :             :          ! Calculate \beta (eq. 106 pag 47)
    2050         [ +  + ]:    11128320 :          do ig=1,npwc
    2051                 :    11128320 :            num = num + rhotwgdpcc(ig)*eig(ig,ii)
    2052                 :             :          end do
    2053                 :      397440 :          numf=num*CONJG(num) !MG this means that we cannot do SCGW
    2054                 :      397440 :          numf=numf*botsq(ii,1)
    2055                 :             : 
    2056                 :             :        case (PPM_ENGEL_FARID)
    2057         [ +  + ]:    11128320 :          do ig=1,npwc
    2058                 :    11128320 :            num = num + rhotwgdpcc(ig)*botsq(ig,ii)
    2059                 :             :          end do
    2060                 :      397440 :          numf = num*CONJG(num) !MG this means that we cannot do SCGW
    2061                 :             : 
    2062                 :             :        case default
    2063      [ +  +  - ]:      794880 :          ABI_ERROR("Wrong ppm%model")
    2064                 :             :        end select
    2065                 :             : 
    2066                 :      794880 :        otw=DBLE(otq(ii,1)) ! in principle otw -> otw - ieta
    2067                 :      794880 :        den=omegame0i_io+otw*twofm1
    2068                 :             : 
    2069         [ +  - ]:      824320 :        if (den**2 > zcut**2) then
    2070                 :      794880 :          inv_den=one/den
    2071                 :      794880 :          ct=ct+numf*inv_den
    2072                 :             :        else
    2073                 :           0 :          inv_den = one/((den**2+twofm1_zcut**2))
    2074                 :           0 :          ct = ct + numf*CMPLX(den,twofm1_zcut)*inv_den
    2075                 :             :        end if
    2076                 :             : 
    2077                 :             :      end do ! ii DM bands
    2078                 :       33280 :      sigcme(iw) = ct*half
    2079                 :             : 
    2080                 :             :      !if (ppm%model == PPM_ENGEL_FARID) then
    2081                 :             :      !ct = dot_product(ket(:, iw), ket(:, iw))
    2082                 :             :      !if (abs(sigcme(iw) - ct) > tol12) then
    2083                 :             :      !  ABI_ERROR("foo bar")
    2084                 :             :      !end if
    2085                 :             :      !end if
    2086                 :             :    end do ! iw
    2087                 :             : 
    2088         [ -  + ]:        3840 :    ABI_FREE(rhotwgdpcc)
    2089                 :             : 
    2090                 :             :  case default
    2091      [ +  +  - ]:     1558650 :    ABI_BUG(sjoin('Wrong ppm%model:',itoa(ppm%model)))
    2092                 :             :  end select
    2093                 :             : 
    2094                 :     1558650 : end subroutine ppm_calc_sigc
    2095                 :             : !!***
    2096                 :             : 
    2097                 :             : !----------------------------------------------------------------------
    2098                 :             : 
    2099                 :             : !!****f* m_ppmodel/ppm_calc_dsigc
    2100                 :             : !! NAME
    2101                 :             : !! ppm_calc_dsigc
    2102                 :             : !!
    2103                 :             : !! FUNCTION
    2104                 :             : !!  Compute the frequency derivative of the plasmon-pole convolution performed in ppm_calc_sigc,
    2105                 :             : !!  i.e. the same contraction but with the simple pole 1/(omega - E_i +- omegatw) replaced by
    2106                 :             : !!  its omega-derivative -1/(omega - E_i +- omegatw)**2.
    2107                 :             : !!
    2108                 :             : !!  This kernel is needed for the additional GWPT term at q=Gamma arising from the first-order
    2109                 :             : !!  derivative of the KS eigenvalue in Delta G0 (double pole, see Appendix A of the GWPT paper):
    2110                 :             : !!
    2111                 :             : !!      Delta_{kappa,alpha,Gamma} G0_{nk}(e) = - (d eps_nk / d tau_{kappa,alpha}) * dG0_{nk}(e)/de
    2112                 :             : !!
    2113                 :             : !!  The caller (gwpt_run) uses the output ket(G,omega) as
    2114                 :             : !!
    2115                 :             : !!      g^Sigma_{mn}(omega) += - Sum_G <m,k| e^{i(p+G)r} |chi_{n'k-p}> vc_sqrt(p+G) * ket(G,omega)
    2116                 :             : !!
    2117                 :             : !!
    2118                 :             : !! INPUTS
    2119                 :             : !!  Same conventions as ppm_calc_sigc (GN and HL plasmon-pole models only).
    2120                 :             : !!
    2121                 :             : !! OUTPUT
    2122                 :             : !!  ket(npwc,nspinor,nomega): incremented with
    2123                 :             : !!
    2124                 :             : !!    ket(G,omega) += - Sum_G2  Omega(G,G2) * rhotw(G2) * [2f-1 pole structure]
    2125                 :             : !!                              --------------------------------------------------
    2126                 :             : !!                              2 omegatw(G,G2) (omega - E_i + omegatw(G,G2)(2f-1))**2
    2127                 :             : !!
    2128                 :             : !! NOTES
    2129                 :             : !!  The i/two_pi factor in the convolution between G and W is included, as in ppm_calc_sigc.
    2130                 :             : !!  The zcut regularization is applied to the complex simple pole before squaring so that
    2131                 :             : !!  the derivative kernel is consistent with the regularized parent kernel.
    2132                 :             : !!
    2133                 :             : !! SOURCE
    2134                 :             : 
    2135                 :           0 : subroutine ppm_calc_dsigc(ppm, nspinor, npwc, nomega, rhotwgp, botsq, otq, &
    2136                 :           0 :                           omegame0i, zcut, theta_mu_minus_e0i, npwx, ket)
    2137                 :             : 
    2138                 :             : !Arguments ------------------------------------
    2139                 :             : !scalars
    2140                 :             :  class(ppmodel_t),intent(in) :: ppm
    2141                 :             :  integer,intent(in) :: nomega, npwc, npwx, nspinor
    2142                 :             :  real(dp),intent(in) :: theta_mu_minus_e0i, zcut
    2143                 :             : !arrays
    2144                 :             :  real(dp),intent(in) :: omegame0i(nomega)
    2145                 :             :  complex(gwp),intent(in) :: botsq(npwc, ppm%dm2_botsq), otq(npwc, ppm%dm2_otq)
    2146                 :             :  complex(gwp),intent(in) :: rhotwgp(npwx, nspinor)
    2147                 :             :  complex(gwp),intent(inout) :: ket(npwc, nspinor, nomega)
    2148                 :             : 
    2149                 :             : !Local variables-------------------------------
    2150                 :             : !scalars
    2151                 :             :  integer :: ig,igp,iw,ispinor
    2152                 :             :  real(dp),parameter :: tol_occ = tol3
    2153                 :             :  real(dp) :: den, den2, omegame0i_io, otw, twofm1_zcut, twofm1_zcut2, zcut2
    2154                 :             :  complex(gwp) :: num, inv_cden, rhotwgdp_igp
    2155                 :             :  logical :: fully_occupied, totally_empty
    2156                 :             : !*************************************************************************
    2157                 :             : 
    2158                 :           0 :  zcut2 = zcut ** 2
    2159                 :             : 
    2160                 :           0 :  select case (ppm%model)
    2161                 :             : 
    2162                 :             :  case (PPM_GODBY_NEEDS, PPM_HYBERTSEN_LOUIE)
    2163                 :           0 :    fully_occupied = (abs(theta_mu_minus_e0i-one) < tol_occ)
    2164                 :           0 :    totally_empty  = (abs(theta_mu_minus_e0i    ) < tol_occ)
    2165                 :             : 
    2166         [ #  # ]:           0 :    do ispinor=1,nspinor
    2167                 :             : 
    2168         [ #  # ]:           0 :      if (.not. totally_empty) then
    2169                 :             :        ! d/domega of \Bomega^2_{G1G2}/\omegat_{G1G2} M_{G1,G2} \theta(\mu-e_s) / (\omega+\omegat_{G1G2}-e_s-i\delta)
    2170                 :           0 :        twofm1_zcut = zcut
    2171                 :           0 :        twofm1_zcut2 = zcut2
    2172                 :             : !$omp parallel do private(omegame0i_io, rhotwgdp_igp, otw, num, den, den2, inv_cden)
    2173         [ #  # ]:           0 :        do iw=1,nomega
    2174                 :           0 :          omegame0i_io = omegame0i(iw)
    2175         [ #  # ]:           0 :          do igp=1,npwc
    2176                 :           0 :            rhotwgdp_igp = rhotwgp(igp, ispinor)
    2177         [ #  # ]:           0 :            do ig=1,npwc
    2178                 :           0 :              otw = DBLE(otq(ig,igp)) !in principle otw -> otw - ieta
    2179                 :           0 :              num = botsq(ig,igp) * rhotwgdp_igp
    2180                 :           0 :              den = omegame0i_io + otw
    2181                 :           0 :              den2 = den ** 2
    2182         [ #  # ]:           0 :              if (den2 > zcut2) then
    2183                 :           0 :                ket(ig,ispinor,iw) = ket(ig,ispinor,iw) - num/(den2*otw) * theta_mu_minus_e0i
    2184                 :             :              else
    2185                 :           0 :                inv_cden = CMPLX(den,twofm1_zcut) / (den2 + twofm1_zcut2)
    2186                 :             :                ket(ig,ispinor,iw) = ket(ig,ispinor,iw) - &
    2187                 :           0 :                  num * inv_cden**2 / otw * theta_mu_minus_e0i
    2188                 :             :              end if
    2189                 :             :            end do ! ig
    2190                 :             :          end do ! igp
    2191                 :             :        end do ! iw
    2192                 :             :      end if ! not totally empty
    2193                 :             : 
    2194         [ #  # ]:           0 :      if (.not. fully_occupied) then
    2195                 :             :        ! d/domega of \Bomega^2_{G1G2}/\omegat_{G1G2} M_{G1,G2} \theta(e_s-\mu) / (\omega-\omegat_{G1G2}-e_s+i\delta)
    2196                 :           0 :        twofm1_zcut = -zcut
    2197                 :           0 :        twofm1_zcut2 = twofm1_zcut**2
    2198                 :             : !$omp parallel do private(omegame0i_io, rhotwgdp_igp, otw, num, den, den2, inv_cden)
    2199         [ #  # ]:           0 :        do iw=1,nomega
    2200                 :           0 :          omegame0i_io = omegame0i(iw)
    2201         [ #  # ]:           0 :          do igp=1,npwc
    2202                 :           0 :            rhotwgdp_igp = rhotwgp(igp, ispinor)
    2203         [ #  # ]:           0 :            do ig=1,npwc
    2204                 :           0 :              otw = DBLE(otq(ig,igp)) !in principle otw -> otw + ieta
    2205                 :           0 :              num = botsq(ig,igp) * rhotwgdp_igp
    2206                 :           0 :              den = omegame0i_io - otw
    2207                 :           0 :              den2 = den ** 2
    2208         [ #  # ]:           0 :              if (den2 > zcut2) then
    2209                 :           0 :                ket(ig,ispinor,iw) = ket(ig,ispinor,iw) - num/(den2*otw) * (one-theta_mu_minus_e0i)
    2210                 :             :              else
    2211                 :           0 :                inv_cden = CMPLX(den,twofm1_zcut) / (den2 + twofm1_zcut2)
    2212                 :             :                ket(ig,ispinor,iw) = ket(ig,ispinor,iw) - &
    2213                 :           0 :                  num * inv_cden**2 / otw * (one-theta_mu_minus_e0i)
    2214                 :             :              end if
    2215                 :             :            end do ! ig
    2216                 :             :          end do ! igp
    2217                 :             :        end do ! iw
    2218                 :             :      end if ! not fully occupied
    2219                 :             : 
    2220                 :             :    end do ! ispinor
    2221                 :             : 
    2222   [ #  #  #  #  :           0 :    ket = ket * half
                   #  # ]
    2223                 :             : 
    2224                 :             :  case default
    2225         [ #  # ]:           0 :    ABI_ERROR(sjoin('ppm_calc_dsigc not implemented for ppm%model:', itoa(ppm%model)))
    2226                 :             :  end select
    2227                 :             : 
    2228                 :           0 : end subroutine ppm_calc_dsigc
    2229                 :             : !!***
    2230                 :             : 
    2231                 :             : !----------------------------------------------------------------------
    2232                 :             : 
    2233                 :             : !!****f* m_ppmodel/ppm_rotate_iqbz
    2234                 :             : !! NAME
    2235                 :             : !!  ppm_rotate_iqbz
    2236                 :             : !!
    2237                 :             : !! FUNCTION
    2238                 :             : !!  Symmetrize the plasmonpole parameters in the full BZ.
    2239                 :             : !!
    2240                 :             : !! INPUTS
    2241                 :             : !!  iq_bz=Index of the q-point in the BZ where the ppmodel parameters are wanted.
    2242                 :             : !!  Gsph<gsphere_t>=data related to the G-sphere.
    2243                 :             : !!  Cryst<crystal_t>=Info on the unit cell and crystal symmetries.
    2244                 :             : !!  Qmesh<kmesh_t>=the q-mesh used for the inverse dielectric matrix
    2245                 :             : !!  iq_ibz=Index of the q-point in the BZ.
    2246                 :             : !!  npwe=number of G vectors for the correlation part
    2247                 :             : !!  nomega=number of frequencies in $\epsilon^{-1}$
    2248                 :             : !!  omega=frequencies in epsm1_ggw
    2249                 :             : !!  epsm1_ggw(npwe,npwe,nomega)=the inverse dielctric matrix
    2250                 :             : !!  ngfftf(18)=contain all needed information about the 3D fine FFT mesh, see ~abinit/doc/variables/vargs.htm#ngfft
    2251                 :             : !!  gprimd(3,3)=dimensional primitive translations for reciprocal space ($\textrm{bohr}^{-1}$)
    2252                 :             : !!  nfftf=the number of points in the FFT mesh (for this processor)
    2253                 :             : !!  rhor_tot(nfftf)=the total charge in real space
    2254                 :             : !!
    2255                 :             : !! SIDE EFFECTS
    2256                 :             : !!  ppm<ppmodel_t>=data type containing information on the plasmonpole technique.
    2257                 :             : !!  Internal tables are modified so that they (point|store) the plasmon-pole parameters
    2258                 :             : !!  for the specified q-point in the BZ.
    2259                 :             : !!
    2260                 :             : !! SOURCE
    2261                 :             : 
    2262                 :           0 : subroutine ppm_rotate_iqbz(ppm, iq_bz, Cryst, Qmesh, Gsph, npwe, nomega, omega, epsm1_ggw, &
    2263                 :           0 :                            nfftf, ngfftf, rhor_tot)
    2264                 :             : 
    2265                 :             : !Arguments ------------------------------------
    2266                 :             : !scalars
    2267                 :             :  class(ppmodel_t),target,intent(inout) :: ppm
    2268                 :             :  integer,intent(in) :: nfftf,npwe,nomega,iq_bz
    2269                 :             :  type(crystal_t),intent(in) :: Cryst
    2270                 :             :  type(gsphere_t),intent(in) :: Gsph
    2271                 :             :  type(kmesh_t),intent(in) :: Qmesh
    2272                 :             : !arrays
    2273                 :             :  integer,intent(in) :: ngfftf(18)
    2274                 :             :  real(dp),intent(in) :: rhor_tot(nfftf)
    2275                 :             :  complex(dp),intent(in) :: omega(nomega)
    2276                 :             :  complex(gwp),intent(in) :: epsm1_ggw(npwe,npwe,nomega)
    2277                 :             : 
    2278                 :             : !Local variables-------------------------------
    2279                 :             : !scalars
    2280                 :             :  integer :: iq_ibz,itim_q,isym_q,iq_curr
    2281                 :             :  logical :: q_isirred
    2282                 :             :  !character(len=500) :: msg
    2283                 :             : !arrays
    2284                 :             :  real(dp) :: qbz(3)
    2285                 :             : ! *********************************************************************
    2286                 :             : 
    2287                 :             :  ! Save the index of the q-point in the BZ for checking purpose.
    2288                 :           0 :  ppm%iq_bz = iq_bz
    2289                 :             : 
    2290                 :           0 :  call qmesh%get_bz_item(iq_bz, qbz, iq_ibz, isym_q, itim_q, isirred=q_isirred)
    2291                 :           0 :  iq_curr = iq_ibz; if (ppm%mqmem == 0) iq_curr = 1
    2292                 :             : 
    2293                 :             :  ! =======================================================
    2294                 :             :  ! ==== Branching for in-core or out-of-core solution ====
    2295                 :             :  ! =======================================================
    2296                 :             : 
    2297                 :             :  ! Allocate the tables for this q_ibz
    2298                 :             :  !print *, "ppm%has_qibz(iq_ibz)", ppm%has_qibz(iq_ibz), "q_isirred:", q_isirred
    2299         [ #  # ]:           0 :  if (ppm%has_qibz(iq_ibz) == PPM_NOTAB) call ppm%malloc_iqibz(iq_ibz)
    2300                 :             : 
    2301         [ #  # ]:           0 :  if (ppm%has_qibz(iq_ibz) == PPM_TAB_ALLOCATED) then
    2302                 :             :    ! Calculate the ppmodel tables for this q_ibz
    2303                 :           0 :    call ppm%new_setup(iq_ibz, Cryst, Qmesh, npwe, nomega, omega, epsm1_ggw, nfftf, Gsph%gvec, ngfftf, rhor_tot)
    2304                 :             :  end if
    2305                 :             : 
    2306                 :             :   ! Allocate memory if not done yet.
    2307                 :             : #ifdef FC_LLVM
    2308                 :             :   !FIXME I don't understand why LLVM fails here...
    2309                 :             :   !I put preproc so others know extra spaces are on purpose
    2310                 :             :   ABI_REMALLOC(ppm%bigomegatwsq_qbz_vals, (ppm%npwc, ppm%dm2_botsq) )
    2311                 :             :   ABI_REMALLOC(ppm%omegatw_qbz_vals, (ppm%npwc, ppm%dm2_otq) )
    2312                 :             :   ABI_REMALLOC(ppm%eigpot_qbz_vals, (ppm%dm_eig, ppm%dm_eig) )
    2313                 :             : #else
    2314   [ #  #  #  #  :           0 :   ABI_REMALLOC(ppm%bigomegatwsq_qbz_vals, (ppm%npwc, ppm%dm2_botsq))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    2315   [ #  #  #  #  :           0 :   ABI_REMALLOC(ppm%omegatw_qbz_vals, (ppm%npwc, ppm%dm2_otq))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    2316   [ #  #  #  #  :           0 :   ABI_REMALLOC(ppm%eigpot_qbz_vals, (ppm%dm_eig, ppm%dm_eig))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    2317                 :             : #endif
    2318                 :             : 
    2319         [ #  # ]:           0 :  if (q_isirred) then
    2320                 :             :    ! Symmetrization is not needed. Copy the data in memory and change the status.
    2321   [ #  #  #  #  :           0 :    ppm%bigomegatwsq_qbz_vals = ppm%bigomegatwsq(iq_ibz)%vals
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    2322   [ #  #  #  #  :           0 :    ppm%omegatw_qbz_vals = ppm%omegatw(iq_ibz)%vals
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    2323   [ #  #  #  #  :           0 :    ppm%eigpot_qbz_vals = ppm%eigpot(iq_ibz)%vals
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    2324                 :             : 
    2325                 :             :  else
    2326                 :             :    ! q-point in the BZ. Calculate new table for this q-point in the BZ. Beware: Dimensions should not change.
    2327   [ #  #  #  #  :           0 :    call ppm%get_qbz(Gsph, Qmesh, iq_bz, ppm%bigomegatwsq_qbz_vals, ppm%omegatw_qbz_vals, ppm%eigpot_qbz_vals)
                   #  # ]
    2328                 :             : 
    2329                 :             :    ! Release the table in the IBZ if required.
    2330         [ #  # ]:           0 :    if (.not. ppm%keep_qibz(iq_ibz)) call ppm%table_free_iqibz(iq_ibz)
    2331                 :             :  end if
    2332                 :             : 
    2333                 :           0 : end subroutine ppm_rotate_iqbz
    2334                 :             : !!***
    2335                 :             : 
    2336                 :             : !----------------------------------------------------------------------
    2337                 :             : 
    2338                 :             : !!****f* m_ppmodel/ppm_new_setup
    2339                 :             : !! NAME
    2340                 :             : !! ppm_new_setup
    2341                 :             : !!
    2342                 :             : !! FUNCTION
    2343                 :             : !!  Initialize some values of several arrays of the ppm datastructure
    2344                 :             : !!  that are used in case of plasmonpole calculations
    2345                 :             : !!  Just a wrapper around different plasmonpole routines.
    2346                 :             : !!
    2347                 :             : !! INPUTS
    2348                 :             : !!  iq_ibz=Index of the q-point in the BZ.
    2349                 :             : !!  Cryst<crystal_t>=Info on the unit cell and crystal symmetries.
    2350                 :             : !!  Qmesh<kmesh_t>=the q-mesh used for the inverse dielectric matrix
    2351                 :             : !!  npwe=number of G vectors for the correlation part
    2352                 :             : !!  nomega=number of frequencies in $\epsilon^{-1}$
    2353                 :             : !!  omega=frequencies in epsm1_ggw
    2354                 :             : !!  epsm1_ggw(npwe,npwe,nomega)=the inverse dielctric matrix
    2355                 :             : !!  nfftf=the number of points in the FFT mesh (for this processor)
    2356                 :             : !!  ngfftf(18)=contain all needed information about the 3D fine FFT mesh, see ~abinit/doc/variables/vargs.htm#ngfft
    2357                 :             : !!  rhor(nfftf)=the total charge in real space.
    2358                 :             : !!
    2359                 :             : !! SIDE EFFECTS
    2360                 :             : !!  == if ppmodel 1 or 2 ==
    2361                 :             : !!   %omegatw and %bigomegatwsq
    2362                 :             : !!  == if ppmodel 3 ==
    2363                 :             : !!   %omegatw, %bigomegatwsq and %eigpot
    2364                 :             : !!  == if ppmodel 4 ==
    2365                 :             : !!   %omegatw and %bigomegatwsq
    2366                 :             : !!
    2367                 :             : !! NOTES
    2368                 :             : !! * FFT parallelism not implemented.
    2369                 :             : !! * TODO: rhor_tot should be replaced by rhog_tot to avoid nq_ibz FFTs.
    2370                 :             : !!
    2371                 :             : !! SOURCE
    2372                 :             : 
    2373                 :          19 : subroutine ppm_new_setup(ppm, iq_ibz, Cryst, Qmesh, npwe, nomega, omega, epsm1_ggw, nfftf, gvec, ngfftf, rhor_tot)
    2374                 :             : 
    2375                 :             : !Arguments ------------------------------------
    2376                 :             : !scalars
    2377                 :             :  class(ppmodel_t),intent(inout) :: ppm
    2378                 :             :  integer,intent(in) :: nfftf,npwe,nomega,iq_ibz
    2379                 :             :  type(kmesh_t),intent(in) :: Qmesh
    2380                 :             :  type(crystal_t),intent(in) :: Cryst
    2381                 :             : !arrays
    2382                 :             :  integer,intent(in) :: gvec(3,npwe),ngfftf(18)
    2383                 :             :  real(dp),intent(in) :: rhor_tot(nfftf)
    2384                 :             :  complex(dp),intent(in) :: omega(nomega)
    2385                 :             :  complex(gwp),intent(in) :: epsm1_ggw(npwe,npwe,nomega)
    2386                 :             : 
    2387                 :             : !Local variables-------------------------------
    2388                 :             : !scalars
    2389                 :             :  real(dp) :: n_at_G_zero
    2390                 :             :  character(len=500) :: msg
    2391                 :             : !scalars
    2392                 :             :  real(dp) :: qpt(3)
    2393                 :             : ! *************************************************************************
    2394                 :             : 
    2395         [ -  + ]:          19 :  if (ppm%has_qibz(iq_ibz) /= PPM_TAB_ALLOCATED) then
    2396                 :           0 :    ABI_ERROR(sjoin("ppmodel tables for iq_ibz:", itoa(iq_ibz), "are not allocated! has_qibz=", itoa(ppm%has_qibz(iq_ibz))))
    2397                 :             :  end if
    2398                 :             : 
    2399         [ +  + ]:          76 :  qpt = Qmesh%ibz(:,iq_ibz)
    2400                 :          19 :  ppm%has_qibz(iq_ibz) = PPM_TAB_STORED
    2401                 :             : 
    2402                 :             :  ! Calculate plasmonpole parameters
    2403                 :          19 :  select case (ppm%model)
    2404                 :             : 
    2405                 :             :  case (PPM_NONE)
    2406                 :           0 :    ABI_COMMENT('Skipping plasmonpole model calculation')
    2407                 :             : 
    2408                 :             :  case (PPM_GODBY_NEEDS)
    2409                 :             :    ! Note: the q-dependence enters only through epsilon^-1.
    2410                 :          19 :    call cppm1par(npwe, nomega, omega, ppm%drude_plsmf, epsm1_ggw, ppm%omegatw(iq_ibz)%vals, ppm%bigomegatwsq(iq_ibz)%vals)
    2411                 :             : 
    2412                 :             :  case (PPM_HYBERTSEN_LOUIE)
    2413                 :             :    call cppm2par(qpt, npwe, epsm1_ggw(:,:,1), ngfftf, gvec, Cryst%gprimd, rhor_tot, nfftf, Cryst%gmet, &
    2414                 :           0 :                  ppm%bigomegatwsq(iq_ibz)%vals, ppm%omegatw(iq_ibz)%vals, ppm%invalid_freq)
    2415                 :             : 
    2416                 :             :    ! Quick-and-dirty change of the plasmon frequency. Never executed in standard runs.
    2417         [ #  # ]:           0 :    if (ppm%force_plsmf > tol6) then
    2418                 :             :       ! Integrate the real-space density
    2419         [ #  # ]:           0 :       n_at_G_zero = SUM(rhor_tot(:))/nfftf
    2420                 :             :       ! Change the prefactor
    2421                 :           0 :       write(msg,'(2(a,es16.8))') 'Forced ppmfreq: ',ppm%force_plsmf*Ha_eV,' nelect/ucvol: ',n_at_G_zero
    2422                 :           0 :       ABI_WARNING(msg)
    2423                 :             : 
    2424                 :           0 :       ppm%force_plsmf = (ppm%force_plsmf**2)/(four_pi*n_at_G_zero)
    2425   [ #  #  #  # ]:           0 :       ppm%bigomegatwsq(iq_ibz)%vals = ppm%force_plsmf * ppm%bigomegatwsq(iq_ibz)%vals
    2426   [ #  #  #  # ]:           0 :       ppm%omegatw(iq_ibz)%vals      = ppm%force_plsmf * ppm%omegatw(iq_ibz)%vals
    2427                 :           0 :       write(msg,'(a,es16.8)') 'Plasma frequency forced in HL ppmodel, new prefactor is: ',ppm%force_plsmf
    2428                 :           0 :       ABI_WARNING(msg)
    2429                 :             :    end if
    2430                 :             : 
    2431                 :             :  case (PPM_LINDEN_HORSH)
    2432                 :             :    call cppm3par(qpt, npwe,epsm1_ggw(:,:,1), ngfftf,gvec, Cryst%gprimd, rhor_tot, nfftf, &
    2433                 :           0 :                  ppm%bigomegatwsq(iq_ibz)%vals, ppm%omegatw(iq_ibz)%vals(:,1), ppm%eigpot(iq_ibz)%vals)
    2434                 :             : 
    2435                 :             :  case (PPM_ENGEL_FARID)
    2436   [ #  #  #  #  :           0 :    if ((ALL(ABS(qpt)<1.0e-3))) qpt = GW_Q0_DEFAULT ! FIXME
                   #  # ]
    2437                 :             : 
    2438                 :             :    call cppm4par(qpt, npwe,epsm1_ggw(:,:,1), ngfftf, gvec, Cryst%gprimd, rhor_tot, nfftf, &
    2439                 :           0 :                  ppm%bigomegatwsq(iq_ibz)%vals, ppm%omegatw(iq_ibz)%vals(:,1))
    2440                 :             : 
    2441                 :             :  case default
    2442   [ -  +  -  -  :          19 :    ABI_BUG(sjoin('Wrong ppm%model:', itoa(ppm%model)))
                   -  - ]
    2443                 :             :  end select
    2444                 :             : 
    2445                 :          19 : end subroutine ppm_new_setup
    2446                 :             : !!***
    2447                 :             : 
    2448                 :             : !!****f* m_ppmodel/ppm_print
    2449                 :             : !! NAME
    2450                 :             : !! ppm_print
    2451                 :             : !!
    2452                 :             : !! FUNCTION
    2453                 :             : !!  Print info on object
    2454                 :             : !!
    2455                 :             : !! SOURCE
    2456                 :             : 
    2457                 :           6 : subroutine ppm_print(ppm, units, header)
    2458                 :             : 
    2459                 :             : !Arguments ------------------------------------
    2460                 :             :  class(ppmodel_t),intent(in) :: ppm
    2461                 :             :  integer,intent(in) :: units(:)
    2462                 :             :  character(len=*),optional,intent(in) :: header
    2463                 :             : 
    2464                 :             : !Local variables-------------------------------
    2465                 :             :  character(len=500) :: msg
    2466                 :             :  type(yamldoc_t) :: ydoc
    2467                 :             : !*************************************************************************
    2468                 :             : 
    2469   [ #  #  #  # ]:           0 :  msg = ' ==== Info on the ppm_t object ==== '; if (present(header)) msg=' ==== '//trim(adjustl(header))//' ==== '
    2470                 :           3 :  call wrtout(units, msg)
    2471                 :             : 
    2472                 :           3 :  ydoc = yamldoc_open('Plasmonpole_params') !, width=11, real_fmt='(3f8.3)')
    2473                 :             :  !call ydoc%add_string("gwr_task", )
    2474                 :           3 :  call ydoc%add_int("dm2_botsq", ppm%dm2_botsq)
    2475                 :           3 :  call ydoc%add_int("dm_eig", ppm%dm_eig)
    2476                 :           3 :  call ydoc%add_int("dm2_otq", ppm%dm2_otq)
    2477                 :           3 :  call ydoc%add_int("invalid_freq", ppm%invalid_freq)
    2478                 :           3 :  call ydoc%add_int("model", ppm%model)
    2479                 :           3 :  call ydoc%add_int("mqmem", ppm%mqmem)
    2480                 :           3 :  call ydoc%add_int("nqibz", ppm%nqibz)
    2481                 :           3 :  call ydoc%add_int("npwc", ppm%npwc)
    2482                 :           3 :  call ydoc%add_int("userho", ppm%userho)
    2483                 :           3 :  call ydoc%add_int("iq_bz", ppm%iq_bz)
    2484                 :           3 :  call ydoc%add_real("drude_plsmf", ppm%drude_plsmf)
    2485                 :           3 :  call ydoc%add_real("force_plsmf", ppm%force_plsmf)
    2486                 :             :  !call ydoc%add_int1d("keep_qibz", ppm%keep_qibz)
    2487                 :             :  !call ydoc%add_int1d("has_qibz", ppm%has_qibz)
    2488                 :             : 
    2489                 :           3 :  call ydoc%write_units_and_free(units)
    2490                 :             : 
    2491   [ -  +  -  + ]:           3 : end subroutine ppm_print
    2492                 :             : !!***
    2493                 :             : 
    2494                 :             : !----------------------------------------------------------------------
    2495                 :             : 
    2496   [ -  +  -  -  :         414 : end module m_ppmodel
          +  +  -  +  +  
          -  -  +  -  +  
          +  -  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          +  -  +  -  -  
          -  -  -  +  -  
          +  -  -  -  -  
                   -  + ]
    2497                 :             : !!***
        

Generated by: LCOV version 2.3-1