LCOV - code coverage report
Current view: top level - src/49_gw_toolbox_oop - m_spectra.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 97.0 % 67 65
Test Date: 2026-09-20 18:56:22 Functions: 71.4 % 7 5

            Line data    Source code
       1              : !!****m* ABINIT/m_spectra
       2              : !! NAME
       3              : !! m_spectra
       4              : !!
       5              : !! FUNCTION
       6              : !! This module contains the definition of the specta_type data type
       7              : !! used to store results related to optical spectra with or without
       8              : !! nonlocal field effects as well as the electron energy loss function
       9              : !! for a given q. These quantities are obtained from the dielectric
      10              : !! matrix as calculated in the GW part of ABINIT (screening.F90)
      11              : !!
      12              : !! COPYRIGHT
      13              : !! Copyright (C) 2008-2026 ABINIT group (MG)
      14              : !! This file is distributed under the terms of the
      15              : !! GNU General Public License, see ~abinit/COPYING
      16              : !! or http://www.gnu.org/copyleft/gpl.txt .
      17              : !!
      18              : !! SOURCE
      19              : 
      20              : #if defined HAVE_CONFIG_H
      21              : #include "config.h"
      22              : #endif
      23              : 
      24              : #include "abi_common.h"
      25              : 
      26              : MODULE m_spectra
      27              : 
      28              :  use defs_basis
      29              :  use m_errors
      30              :  use m_abicore
      31              : 
      32              :  use m_io_tools,      only : open_file
      33              :  use m_fstrings,      only : strcat
      34              : 
      35              :  implicit none
      36              : 
      37              :  private
      38              : !!***
      39              : 
      40              : !!****t* m_spectra/spectra_t
      41              : !! NAME
      42              : !! spectra_t
      43              : !!
      44              : !! FUNCTION
      45              : !!  Object used to store optical spectra with or without non-local field effects.
      46              : !!
      47              : !! SOURCE
      48              : 
      49              :  type,public :: spectra_t
      50              : 
      51              :  !scalars
      52              :   integer :: nomega
      53              :   ! number of frequencies
      54              : 
      55              :   integer :: nqpts
      56              :   ! number of q-points
      57              : 
      58              :  !arrays
      59              :   real(dp),allocatable :: omega(:)
      60              :   ! omega(nomega)
      61              :   ! Real frequency mesh for optical spectra.
      62              : 
      63              :   real(dp),allocatable :: qpts(:,:)
      64              :   ! qpts(3,nqpoints)
      65              :   ! The list of q-points used for the spectra
      66              : 
      67              :   real(dp),allocatable :: eelf(:,:)
      68              :   ! eelf(nomega,nqpoints)
      69              :   ! contains the Electron Energy Loss Function i.e. -\Im{ e^{-1}_{G1=0,G2=0}(q-->0,nomega)}
      70              : 
      71              :   complex(dp),allocatable :: emacro_lf(:,:)
      72              :   ! emacro_lf(nomega,nqpoints)
      73              :   ! contains 1/e^{-1}_{G1=0,G2=0}(q-->0,nomega) (with Local field effects)
      74              : 
      75              :   complex(dp),allocatable :: emacro_nlf(:,:)
      76              :   ! emacro_nlf(nomega,nqpoints)
      77              :   ! contains e_{G1=0,G2=0}(q-->0,nomega) (without Local field effects)
      78              : 
      79              :  contains
      80              : 
      81              :    procedure :: free => spectra_free
      82              :    ! Free memory.
      83              : 
      84              :    procedure :: write => spectra_write
      85              :    ! Write results on file.
      86              : 
      87              :    procedure :: repr => spectra_repr
      88              :    ! Return info on Macroscopic diel. constant in form of a string.
      89              : 
      90              :  end type spectra_t
      91              : !!***
      92              : 
      93              :  public :: spectra_init       ! Creation method.
      94              : 
      95              :  integer,public,parameter :: W_EM_LF  = 1
      96              :  integer,public,parameter :: W_EM_NLF = 2
      97              :  integer,public,parameter :: W_EELF   = 4
      98              : 
      99              : CONTAINS  !========================================================================================
     100              : !!***
     101              : 
     102              : !!****f* m_spectra/spectra_init
     103              : !! NAME
     104              : !!  spectra_init
     105              : !!
     106              : !! FUNCTION
     107              : !!  Initialize the object.
     108              : !!
     109              : !! INPUTS
     110              : !!
     111              : !! OUTPUT
     112              : !!
     113              : !! SOURCE
     114              : 
     115          950 : subroutine spectra_init(Spectra,nomega,omega,nqpts,qpts)
     116              : 
     117              : !Arguments ------------------------------------
     118              : !scalars
     119              :  integer,intent(in) :: nomega,nqpts
     120              : !arrays
     121              :  real(dp),intent(in) :: omega(nomega),qpts(3,nqpts)
     122              :  type(spectra_t),intent(out) :: Spectra
     123              : 
     124              : ! *********************************************************************
     125              : 
     126          950 :  Spectra%nomega = nomega
     127          950 :  Spectra%nqpts  = nqpts
     128              : 
     129         2850 :  ABI_MALLOC(Spectra%qpts,(3,nqpts))
     130         5700 :  Spectra%qpts = qpts
     131              : 
     132         2850 :  ABI_MALLOC(Spectra%omega,(nomega))
     133         4633 :  Spectra%omega = omega
     134              : 
     135         7483 :  ABI_CALLOC(Spectra%emacro_lf,(nomega,nqpts))
     136         6533 :  ABI_CALLOC(Spectra%emacro_nlf,(nomega,nqpts))
     137         7483 :  ABI_CALLOC(Spectra%eelf,(nomega,nqpts))
     138              : 
     139          950 : end subroutine spectra_init
     140              : !!***
     141              : 
     142              : !----------------------------------------------------------------------
     143              : 
     144              : !!****f* m_spectra/spectra_free
     145              : !! NAME
     146              : !!  spectra_free
     147              : !!
     148              : !! FUNCTION
     149              : !!  Deallocate all associated pointers defined in the structure.
     150              : !!
     151              : !! INPUTS
     152              : !!
     153              : !! OUTPUT
     154              : !!
     155              : !! SOURCE
     156              : 
     157          950 : subroutine spectra_free(Spectra)
     158              : 
     159              : !Arguments ------------------------------------
     160              :  class(spectra_t),intent(inout) :: spectra
     161              : 
     162              : ! *********************************************************************
     163              : 
     164          950 :  ABI_SFREE(Spectra%omega)
     165          950 :  ABI_SFREE(Spectra%qpts)
     166          950 :  ABI_SFREE(Spectra%emacro_lf)
     167          950 :  ABI_SFREE(Spectra%emacro_nlf)
     168          950 :  ABI_SFREE(Spectra%eelf)
     169              : 
     170          950 : end subroutine spectra_free
     171              : !!***
     172              : 
     173              : !----------------------------------------------------------------------
     174              : 
     175              : !!****f* m_spectra/spectra_write
     176              : !! NAME
     177              : !!  spectra_write
     178              : !!
     179              : !! FUNCTION
     180              : !!  Write the optical spectra stored in the object on an external formatted file.
     181              : !!
     182              : !! INPUTS
     183              : !!  Spectra=The Object containing the spectra
     184              : !!  write_bits=Positive integer defining the quantities to be written (bit representation is used)
     185              : !!  fname=Name of the file to be written.
     186              : !!
     187              : !! OUTPUT
     188              : !!
     189              : !! SOURCE
     190              : 
     191           66 : subroutine spectra_write(Spectra,write_bits,fname)
     192              : 
     193              : !Arguments ------------------------------------
     194              : !scalars
     195              :  class(spectra_t),intent(in) :: Spectra
     196              :  integer,intent(in) :: write_bits
     197              :  character(len=*),intent(in) :: fname
     198              : 
     199              : !Local variables-------------------------------
     200              : !scalars
     201              :  integer :: unt,io,iqpt
     202              :  real(dp) :: mino,maxo
     203              :  character(len=100) :: fmt
     204              :  character(len=500) :: msg
     205              : 
     206              : ! *********************************************************************
     207              : 
     208           66 :  if (write_bits<0) RETURN
     209              : 
     210              :  mino = MINVAL(Spectra%omega)
     211              :  maxo = MAXVAL(Spectra%omega)
     212              : 
     213           66 :  if (open_file(fname,msg,newunit=unt) /= 0) then
     214            0 :    ABI_ERROR(msg)
     215              :  end if
     216              : 
     217              :  !write(unt,'(a,i5,2(a,f9.1),a)')'# nomega : ',Spectra%nomega,' from ',mino*Ha_eV,' up to ',maxo*Ha_eV,' [eV] '
     218              : 
     219           66 :  if ( IAND(write_bits,W_EM_NLF ) == W_EM_NLF ) then
     220           22 :    write(unt,'(a)')'#'
     221           22 :    write(unt,'(a)')'# Macroscopic Dielectric Function without local fields'
     222           22 :    call dump_qlist()
     223           22 :    write(unt,'(a)')'# Omega [eV]    Re epsilon_M       IM eps_M '
     224           22 :    write(fmt,'(a,i3,a)') '(1x,f7.3,7x,',Spectra%nqpts,'(2(e12.4),2x))'
     225          278 :    do io=1,Spectra%nomega
     226          534 :      write(unt,fmt) Spectra%omega(io)*Ha_eV, ( Spectra%emacro_nlf(io,iqpt), iqpt=1,Spectra%nqpts )
     227              :    end do
     228              :  end if
     229              :  !
     230           66 :  if ( IAND(write_bits, W_EM_LF ) == W_EM_LF ) then
     231           22 :    write(unt,'(a)')'#'
     232           22 :    write(unt,'(a)')'# Macroscopic Dielectric Function with local fields included'
     233           22 :    call dump_qlist()
     234           22 :    write(unt,'(a)')'# Omega [eV]    Re epsilon_M       Im eps_M '
     235           22 :    write(fmt,'(a,i3,a)') '(1x,f7.3,7x,',Spectra%nqpts,'(2(e12.4),2x))'
     236          278 :    do io=1,Spectra%nomega
     237          534 :      write(unt,fmt) Spectra%omega(io)*Ha_eV, ( Spectra%emacro_lf(io,iqpt), iqpt=1,Spectra%nqpts )
     238              :    end do
     239              :  end if
     240              :  !
     241           66 :  if ( IAND(write_bits,W_EELF) == W_EELF) then
     242           22 :    write(unt,'(a)')'#'
     243           22 :    write(unt,'(a)')'# Electron Energy Loss Function -Im(1/epsilon_M)'
     244           22 :    call dump_qlist()
     245           22 :    write(unt,'(a)')'# Omega [eV]    -Im(1/epsilon_M)'
     246           22 :    write(fmt,'(a,i3,a)') '(1x,f7.3,7x,',Spectra%nqpts,'(e12.4,2x))'
     247          278 :    do io=1,Spectra%nomega
     248          534 :      write(unt,fmt) Spectra%omega(io)*Ha_eV, ( Spectra%eelf(io,iqpt), iqpt=1,Spectra%nqpts ) ! -AIMAG(chi0(1,1,io))
     249              :    end do
     250              :  end if
     251              : 
     252           66 :  close(unt)
     253              : 
     254              : CONTAINS
     255              : !!***
     256              : 
     257              : !!****f* m_spectra/dump_Qlist
     258              : !! NAME
     259              : !!  dump_Qlist
     260              : !!
     261              : !! FUNCTION
     262              : !!  Helper function used to write the list of q-points used for the long-wavelength limit.
     263              : !!
     264              : !! INPUTS
     265              : !!  Spectra=The Object containing the spectra
     266              : !!
     267              : !! OUTPUT
     268              : !!  Only writing.
     269              : !!
     270              : !! SOURCE
     271              : 
     272           66 :  subroutine dump_Qlist()
     273              : 
     274              :   integer :: iqpt
     275           66 :   write(unt,'(a,i3)')'# Q-point list, No. ',Spectra%nqpts
     276          132 :   do iqpt=1,Spectra%nqpts
     277          132 :     write(unt,'(a,i3,a,3f9.6,a)')'# ',iqpt,')  [',Spectra%qpts(:,iqpt),'] r.l.u. '
     278              :   end do
     279           66 :  end subroutine dump_Qlist
     280              : 
     281              : end subroutine spectra_write
     282              : !!***
     283              : 
     284              : !----------------------------------------------------------------------
     285              : 
     286              : !!****f* m_spectra/spectra_repr
     287              : !! NAME
     288              : !!  spectra_repr
     289              : !!
     290              : !! FUNCTION
     291              : !!  Returns a string reporting info on the calculated dielectric constant.
     292              : !!
     293              : !! INPUTS
     294              : !!  Spectra=The Object containing the spectra
     295              : !!
     296              : !! OUTPUT
     297              : !!
     298              : !! SOURCE
     299              : 
     300          123 : subroutine spectra_repr(Spectra,str)
     301              : 
     302              : !Arguments ------------------------------------
     303              : !scalars
     304              :  class(spectra_t),intent(in) :: Spectra
     305              :  character(len=*),intent(out) :: str
     306              : 
     307              : !Local variables-------------------------------
     308              : !scalars
     309              :  integer :: iqpt
     310              :  real(dp) :: epsilon0,epsilon0_nlf
     311              :  character(len=15), parameter :: format_f84   = '(1x,a,  f8.4,a)'
     312              :  character(len=15), parameter :: format_es135 = '(1x,a,es13.5,a)'
     313              :  character(len=15) :: format_diel
     314              :  character(len=500) :: msg
     315              : 
     316              : ! *********************************************************************
     317              : 
     318              :  !istatic = -1
     319              :  !do io = Spectra%nomega
     320              :  ! if (ABS(REAL(Spectra%omega(io)))<1.e-3.and.ABS(AIMAG(Spectra%omega(io)))<1.e-3) then
     321              :  !  istatic = io
     322              :  !  EXIT
     323              :  ! end if
     324              :  !end do
     325              : 
     326          123 :  str = ""
     327          246 :  do iqpt=1,Spectra%nqpts
     328          123 :    epsilon0    = REAL(Spectra%emacro_lf (1,iqpt))
     329          123 :    epsilon0_nlf= REAL(Spectra%emacro_nlf(1,iqpt))
     330          123 :    write(msg,'(a,3f9.6,a)')' For q-point: ',Spectra%qpts(:,iqpt),ch10
     331          123 :    format_diel=format_f84
     332          123 :    if(abs(epsilon0)>1000.0d0 .or. abs(epsilon0_nlf)>1000.0d0) format_diel=format_es135
     333          123 :    str = strcat(str,msg)
     334          123 :    write(msg,format_diel)' dielectric constant = ',epsilon0,ch10
     335          123 :    str = strcat(str,msg)
     336          123 :    write(msg,format_diel)' dielectric constant without local fields = ',epsilon0_nlf,ch10
     337          246 :    str = strcat(str,msg)
     338              :  end do
     339              : 
     340          123 : end subroutine spectra_repr
     341              : 
     342              : !----------------------------------------------------------------------
     343              : 
     344            0 : END MODULE m_spectra
     345              : !!***
        

Generated by: LCOV version 2.3-1