TABLE OF CONTENTS
ABINIT/kramerskronig [ Functions ]
NAME
kramerskronig
FUNCTION
check or apply the Kramers Kronig relation: Re \epsilon(\omega) = 1 + \frac{2}{\pi} \int_0^\infty d\omega' frac{\omega'}{\omega'^2 - \omega^2} Im \epsilon(\omega')
COPYRIGHT
Copyright (C) 2007-2017 ABINIT group (Valerio Olevano, Lucia Reining, Francesco Sottile, MG) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt .
INPUTS
nomega=number of real frequencies omega(nomega)= real frequencies eps(nomega)= function on the frequency grid (both real and imaginary part) real part can be used to check whether the K-K relation is satisfied or not method=method used to perform the integration 0= naive integration 1=simpson rule only_check= if /=0 the real part of eps is checked against the imaginary part, a final report in written but the array eps is not modified if ==0 the real part of eps is overwritten using the results obtained using the Kramers-Kronig relation
OUTPUT
Inspired to check_kramerskronig of the DP code
PARENTS
linear_optics_paw
CHILDREN
simpson_int,wrtout
SOURCE
42 #if defined HAVE_CONFIG_H 43 #include "config.h" 44 #endif 45 46 #include "abi_common.h" 47 48 subroutine kramerskronig(nomega,omega,eps,method,only_check) 49 50 use defs_basis 51 use m_errors 52 53 use m_numeric_tools, only : simpson_int 54 55 !This section has been created automatically by the script Abilint (TD). 56 !Do not modify the following lines by hand. 57 #undef ABI_FUNC 58 #define ABI_FUNC 'kramerskronig' 59 use interfaces_14_hidewrite 60 !End of the abilint section 61 62 implicit none 63 64 !Arguments ------------------------------------ 65 !scalars 66 integer,intent(in) :: method,nomega,only_check 67 !arrays 68 real(dp),intent(in) :: omega(nomega) 69 complex,intent(inout) :: eps(nomega) 70 71 !Local variables------------------------------- 72 !scalars 73 integer,save :: enough=0 74 integer :: ii,ip 75 real(dp) :: acc,domega,eav,kkdif,kkrms,ww,wwp 76 character(len=500) :: msg 77 !arrays 78 real(dp) :: e1kk(nomega),intkk(nomega),kk(nomega) 79 80 ! ************************************************************************* 81 82 !Check whether the frequency grid is linear or not 83 domega = (omega(nomega) - omega(1)) / (nomega-1) 84 do ii=2,nomega 85 if (ABS(domega-(omega(ii)-omega(ii-1))) > 0.001) then 86 if (only_check/=1) then 87 msg="check cannot be performed since the frequency step is not constant" 88 MSG_WARNING(msg) 89 RETURN 90 else 91 msg=' Cannot perform integration since frequency step is not constant' 92 MSG_ERROR(msg) 93 end if 94 end if 95 end do 96 97 !Check whether omega(1) is small or not 98 if (omega(1) > 0.1/Ha_eV) then 99 if (only_check/=1) then 100 msg=' Check cannot be performed since first frequency on the grid > 0.1 eV' 101 MSG_WARNING(msg) 102 RETURN 103 else 104 msg=' Cannot perform integration since first frequency on the grid > 0.1 eV' 105 MSG_ERROR(msg) 106 end if 107 end if 108 109 !If eps(nomega) is not 0 warn 110 if (AIMAG(eps(nomega)) > 0.1 .and. enough<50) then 111 enough=enough+1 112 write(msg,'(a,f8.4,3a,f8.2,2a)')& 113 & 'Im epsilon for omega = ',omega(nomega)*Ha_eV,' eV',ch10,& 114 & 'is not yet zero, epsilon_2 = ',AIMAG(eps(nomega)),ch10,& 115 & 'Kramers Kronig could give wrong results' 116 MSG_WARNING(msg) 117 if (enough==50) then 118 write(msg,'(3a)')' sufficient number of WARNINGS-',ch10,' stop writing ' 119 call wrtout(std_out,msg,'COLL') 120 end if 121 end if 122 123 124 !Perform Kramers-Kronig using naive integration 125 select case (method) 126 case (0) 127 128 do ii=1,nomega 129 ww = omega(ii) 130 acc = 0.0_dp 131 do ip=1,nomega 132 if (ip == ii) CYCLE 133 wwp = omega(ip) 134 acc = acc + wwp/(wwp**2-ww**2) *AIMAG(eps(ip)) 135 end do 136 e1kk(ii) = one + two/pi*domega* acc 137 end do 138 139 ! Perform Kramers-Kronig using Simpson integration 140 ! Simpson O(1/N^4), from NumRec in C p 134 NumRec in Fortran p 128 141 case (1) 142 143 kk=zero 144 145 do ii=1,nomega 146 ww=omega(ii) 147 do ip=1,nomega 148 if (ip == ii) CYCLE 149 wwp = omega(ip) 150 kk(ip) = wwp/(wwp**2-ww**2) *AIMAG(eps(ip)) 151 end do 152 call simpson_int(nomega,domega,kk,intkk) 153 e1kk(ii) = one + two/pi * intkk(nomega) 154 end do 155 156 case default 157 write(msg,'(a,i0)')' Wrong value for method ',method 158 MSG_BUG(msg) 159 end select 160 161 !at this point real part is in e1kk, need to put it into eps 162 do ii=1,nomega 163 eps(ii)=CMPLX(e1kk(ii),AIMAG(eps(ii))) 164 end do 165 166 !Verify Kramers-Kronig 167 eav = zero 168 kkdif = zero 169 kkrms = zero 170 171 do ii=1,nomega 172 kkdif = kkdif + ABS(REAL(eps(ii)) - e1kk(ii)) 173 kkrms = kkrms + (REAL(eps(ii)) - e1kk(ii))*(REAL(eps(ii)) - e1kk(ii)) 174 eav = eav + ABS(REAL(eps(ii))) 175 end do 176 177 eav = eav/nomega 178 kkdif = (kkdif/nomega) / eav 179 kkrms = (kkrms/nomega) / (eav*eav) 180 181 kk = ABS(REAL(eps(1)) - e1kk(1)) / REAL(eps(1)) 182 183 !Write data 184 write(msg,'(a,f7.2,a)')' Kramers-Kronig transform is verified within ',MAXVAL(kk)*100,"%" 185 call wrtout(std_out,msg,'COLL') 186 187 end subroutine kramerskronig