TABLE OF CONTENTS
- ABINIT/m_conducti
- m_conducti/conducti_nc
- m_conducti/conducti_paw
- m_conducti/conducti_paw_core
- m_conducti/msig
ABINIT/m_conducti [ Modules ]
NAME
m_conducti
FUNCTION
This program computes the elements of the optical frequency dependent conductivity tensor and the conductivity along the three principal axes from the Kubo-Greenwood formula.
COPYRIGHT
Copyright (C) 2002-2024 ABINIT group (VRecoules, PGhosh, SMazevet, SM, SVinko, NBrouwer) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt .
SOURCE
18 #if defined HAVE_CONFIG_H 19 #include "config.h" 20 #endif 21 22 #include "abi_common.h" 23 24 module m_conducti 25 26 use defs_basis 27 use m_errors 28 use m_abicore 29 use m_xmpi 30 use m_wfk 31 use m_hdr 32 use m_nctk 33 #ifdef HAVE_NETCDF 34 use netcdf 35 #endif 36 37 use defs_abitypes, only : MPI_type 38 use m_io_tools, only : open_file, close_unit, get_unit 39 use m_fstrings, only : sjoin 40 use m_symtk, only : matr3inv 41 use m_hide_lapack, only : jacobi 42 use m_occ, only : getnel 43 use m_geometry, only : metric 44 use m_splines, only : intrpl,splint,spline 45 use m_mpinfo, only : distrb2,init_mpi_enreg,destroy_mpi_enreg,proc_distrb_cycle,initmpi_band 46 47 implicit none 48 49 private
m_conducti/conducti_nc [ Functions ]
[ Top ] [ m_conducti ] [ Functions ]
NAME
conducti_nc
FUNCTION
This program computes the elements of the optical frequency dependent conductivity tensor and the conductivity along the three principal axes from the Kubo-Greenwood formula.
INPUTS
(main routine)
OUTPUT
(main routine)
NOTES
bantot doccde(mband*nkpt_rbz*nsppol)=derivative of occ_rbz wrt the energy. dom=frequency range eigen0(mband*nkpt_rbz*nsppol)=GS eigenvalues at k (hartree). eigen11(2*mband*mband*nkpt_rbz*nsppol)=first-order eigenvalues (hartree) in reciprocal direction 100 eigen12(2*mband*mband*nkpt_rbz*nsppol)=first-order eigenvalues (hartree) in reciprocal direction 010 eigen13(2*mband*mband*nkpt_rbz*nsppol)=first-order eigenvalues (hartree) in reciprocal direction 001 ecut=kinetic energy planewave cutoff (hartree). entropy= entropy associated with the smearing (adimensional) fermie= fermi energy (Hartree) gmet(3,3)=reciprocal space metric ($\textrm{bohr}^{2}$). gmet_inv(3,3)=inverse of reciprocal space metric ($\textrm{bohr}^{2}$). gprimd(3,3)=dimensional primitive translations for reciprocal space(bohr^-1). kin11= Onsager kinetic coeficient=optical conductivity kin12= Onsager kinetic coeficient kin21= Onsager kinetic coeficient kin22= Onsager kinetic coeficient Kth=thermal conductivity mom=number of frequency for conductivity computation mband=maximum number of bands. natom = number of atoms in the unit cell. nband(nkpt*nsppol)=number of bands at each RF k point for each spin. nelect=number of electrons per unit cell nkpt=number of k points in the IBZ for this perturbation ngfft(3)=integer fft box dimensions. nspinor=number of spinorial components of the wavefunctions. nsppol=1 for unpolarized, 2 for spin-polarized. ntypat = number of atom types. occ(mband*nkpt*nsppol)=occupation number for each band and k. occopt==option for occupancies rmet(3,3)=real space metric ($\textrm{bohr}^{2}$). rprimd(3,3)=real space primitive translations. of primitive translations. Sth=thermopower tsmear=smearing width (or temperature) in Hartree ucvol=unit cell volume in ($\textrm{bohr}^{3}$). wind=frequency windows for computations of sigma wtk(nkpt)=weight assigned to each k point. znucl(natom)=atomic number of atoms np_sum=noziere-pines sumrule cond_kg(mom)=kubo-greenwood conductivity
SOURCE
1769 subroutine conducti_nc(filnam,filnam_out) 1770 1771 !Arguments ----------------------------------- 1772 !scalars 1773 character(len=fnlen) :: filnam,filnam_out 1774 1775 !Local variables------------------------------- 1776 !scalars 1777 integer,parameter :: formeig0=0,formeig1=1 1778 integer :: bantot,bd2tot_index,bdtot0_index,bdtot_index 1779 integer :: headform,iband,ii,jj,ikpt,iunt 1780 integer :: index_1,iom,isppol,jband,l1,l2,mband,mom,natom,nband1 1781 integer :: nrot,iomode 1782 integer :: nband_k,nkpt,nlign,nrest,nspinor,nsppol,ntypat 1783 integer :: occopt,comm 1784 integer :: tens_unt,lij_unt,sig_unt,kth_unt,ocond_unt 1785 real(dp) :: deltae,dosdeltae,diff_occ,dom,ecut,entropy,fermie,maxocc 1786 real(dp) :: nelect,np_sum,np_sum_k1,np_sum_k2,omin,oml,socc,socc_k,sig 1787 real(dp) :: tphysel,tsmear,ucvol,wind,Tatm 1788 character(len=fnlen) :: filnam0,filnam1,filnam2,filnam3 1789 character(len=500) :: msg 1790 type(hdr_type) :: hdr 1791 type(wfk_t) :: gswfk,ddk1,ddk2,ddk3 1792 !arrays 1793 integer,allocatable :: nband(:) 1794 real(dp) :: gmet(3,3),gmet_inv(3,3),gprimd(3,3),gprimd_inv(3,3),rmet(3,3),rprimd(3,3) 1795 real(dp),allocatable :: cond_kg(:,:,:),cond_kg_cart(:,:,:),cond_nd(:,:,:),dhdk2_r(:,:,:,:),dhdk2_g(:,:) 1796 real(dp),allocatable :: doccde(:),doccde_k(:),cond_kg_xx(:),cond_kg_yy(:),cond_kg_zz(:),trace(:) 1797 real(dp),allocatable :: eig0_k(:),eig0tmp(:),eig1_k(:,:),eigen0(:),eigen11(:) 1798 real(dp),allocatable :: eigen12(:),eigtmp(:) 1799 real(dp),allocatable :: eigen13(:),occ(:),occ_k(:),wtk(:),cond_tot(:),oml1(:) 1800 real(dp),allocatable :: kin11(:),kin12(:),kin21(:),kin22(:) 1801 real(dp),allocatable :: kin11_k(:),kin12_k(:),kin21_k(:),kin22_k(:),Kth(:),Stp(:) 1802 real(dp) :: cond_kg_w(3,3),z(3,3) 1803 real(dp) :: eig_cond(3) 1804 1805 ! ********************************************************************************* 1806 1807 !Read data file 1808 if (open_file(filnam,msg,newunit=iunt,form='formatted',status="old")/=0) then 1809 ABI_ERROR(msg) 1810 end if 1811 1812 rewind(iunt) 1813 read(iunt,*) 1814 read(iunt,'(a)')filnam1 ! first ddk file 1815 read(iunt,'(a)')filnam2 ! second ddk file 1816 read(iunt,'(a)')filnam3 ! third ddk file 1817 read(iunt,'(a)')filnam0 ! ground-state data 1818 1819 !Open the GS Wavefunction file and the 3 DDK files. 1820 ! TODO: one should perform basic consistency tests for the GS WFK and the DDK files, e.g. 1821 ! k-points and their order, spins, number of bands could differ in the four files. 1822 ! Note indeed that we are assuming the same numer of bands in all the files. 1823 comm = xmpi_comm_self 1824 call nctk_fort_or_ncfile(filnam0, iomode, msg) 1825 if (len_trim(msg) /= 0) ABI_ERROR(msg) 1826 call wfk_open_read(gswfk,filnam0, formeig0, iomode, get_unit(), comm) 1827 1828 call nctk_fort_or_ncfile(filnam1, iomode, msg) 1829 if (len_trim(msg) /= 0) ABI_ERROR(msg) 1830 call wfk_open_read(ddk1,filnam1, formeig1, iomode, get_unit(), comm, hdr_out=hdr) 1831 1832 call nctk_fort_or_ncfile(filnam2, iomode, msg) 1833 if (len_trim(msg) /= 0) ABI_ERROR(msg) 1834 call wfk_open_read(ddk2,filnam2, formeig1, iomode, get_unit(), comm) 1835 1836 call nctk_fort_or_ncfile(filnam3, iomode, msg) 1837 if (len_trim(msg) /= 0) ABI_ERROR(msg) 1838 call wfk_open_read(ddk3,filnam3, formeig1, iomode, get_unit(), comm) 1839 1840 if (ddk1%compare(ddk2) /= 0) then 1841 ABI_ERROR("ddk1 and ddk2 are not consistent. see above messages") 1842 end if 1843 if (ddk1%compare(ddk3) /= 0) then 1844 ABI_ERROR("ddk1 and ddk3 are not consistent. see above messages") 1845 end if 1846 1847 !Extract params from the header of the first ddk file (might have been the GS file ?) 1848 1849 !Extract info from the header 1850 headform=hdr%headform 1851 bantot=hdr%bantot 1852 ecut=hdr%ecut_eff 1853 natom=hdr%natom 1854 nkpt=hdr%nkpt 1855 nspinor=hdr%nspinor 1856 nsppol=hdr%nsppol 1857 ntypat=hdr%ntypat 1858 occopt=hdr%occopt 1859 rprimd(:,:)=hdr%rprimd(:,:) 1860 ABI_MALLOC(nband,(nkpt*nsppol)) 1861 ABI_MALLOC(occ,(bantot)) 1862 fermie=hdr%fermie 1863 occ(1:bantot)=hdr%occ(1:bantot) 1864 nband(1:nkpt*nsppol)=hdr%nband(1:nkpt*nsppol) 1865 1866 !Get mband, as the maximum value of nband(nkpt) 1867 mband=maxval(nband(:)) 1868 1869 write(std_out,*) 1870 write(std_out,'(a,3f10.5,a)' )' rprimd(bohr) =',rprimd(1:3,1) 1871 write(std_out,'(a,3f10.5,a)' )' ',rprimd(1:3,2) 1872 write(std_out,'(a,3f10.5,a)' )' ',rprimd(1:3,3) 1873 write(std_out,'(a,i8)') ' natom =',natom 1874 write(std_out,'(a,2i8)') ' nkpt,mband =',nkpt,mband 1875 write(std_out,'(a, f10.5,a)' ) ' ecut =',ecut,' Ha' 1876 write(std_out,'(a,f10.5,a,f10.5,a)' )' fermie =',fermie,' Ha',fermie*Ha_eV,' eV' 1877 1878 !Prepare the reading of ddk Wff files 1879 ABI_MALLOC(eigtmp,(2*mband*mband)) 1880 ABI_MALLOC(eig0tmp,(mband)) 1881 1882 !Read the eigenvalues of ground-state and ddk files 1883 ABI_MALLOC(eigen0,(mband*nkpt*nsppol)) 1884 ABI_MALLOC(eigen11,(2*mband*mband*nkpt*nsppol)) 1885 ABI_MALLOC(eigen12,(2*mband*mband*nkpt*nsppol)) 1886 ABI_MALLOC(eigen13,(2*mband*mband*nkpt*nsppol)) 1887 bdtot0_index=0 ; bdtot_index=0 1888 do isppol=1,nsppol 1889 do ikpt=1,nkpt 1890 nband1=nband(ikpt+(isppol-1)*nkpt) 1891 call gswfk%read_eigk(ikpt,isppol,xmpio_single,eig0tmp) 1892 eigen0(1+bdtot0_index:nband1+bdtot0_index)=eig0tmp(1:nband1) 1893 1894 call ddk1%read_eigk(ikpt,isppol,xmpio_single,eigtmp) 1895 eigen11(1+bdtot_index:2*nband1**2+bdtot_index)=eigtmp(1:2*nband1**2) 1896 1897 call ddk2%read_eigk(ikpt,isppol,xmpio_single,eigtmp) 1898 eigen12(1+bdtot_index:2*nband1**2+bdtot_index)=eigtmp(1:2*nband1**2) 1899 1900 call ddk3%read_eigk(ikpt,isppol,xmpio_single,eigtmp) 1901 eigen13(1+bdtot_index:2*nband1**2+bdtot_index)=eigtmp(1:2*nband1**2) 1902 1903 bdtot0_index=bdtot0_index+nband1 1904 bdtot_index=bdtot_index+2*nband1**2 1905 end do 1906 end do 1907 1908 !Close files 1909 call gswfk%close() 1910 call ddk1%close() 1911 call ddk2%close() 1912 call ddk3%close() 1913 1914 ABI_FREE(eigtmp) 1915 ABI_FREE(eig0tmp) 1916 1917 !--------------------------------------------------------------------------------- 1918 !Gmet inversion 1919 call metric(gmet,gprimd,-1,rmet,rprimd,ucvol) 1920 call matr3inv(gmet,gmet_inv) 1921 call matr3inv(gprimd,gprimd_inv) 1922 1923 !--------------------------------------------------------------------------------- 1924 !Derivative of occupation wrt the energy. 1925 1926 ABI_MALLOC(doccde,(mband*nkpt*nsppol)) 1927 ABI_MALLOC(wtk,(nkpt)) 1928 1929 read(iunt,*)tsmear 1930 Tatm=tsmear*Ha_K 1931 write(std_out,'(a,f12.5,a,f12.5,a)') ' Temp =',tsmear,' Ha ',Tatm,' Kelvin' 1932 ! 1933 nlign=nkpt/6 1934 nrest=nkpt-6*nlign 1935 index_1=0 1936 do ii=1,nlign 1937 read(iunt,*)wtk(1+index_1:6+index_1) 1938 index_1=index_1+6 1939 end do 1940 if (nrest/=0) then 1941 read(iunt,*)wtk(6*nlign+1:nkpt) 1942 end if 1943 ! 1944 if (occopt==1) then 1945 write(std_out,'(a,i4)') ' occopt =',occopt 1946 doccde=zero 1947 else 1948 tphysel=zero 1949 maxocc=two/(nsppol*nspinor) 1950 dosdeltae=zero 1951 ! CP: using 1 and nband(0) as dummy value, because function 1952 ! not implemented for occopt==9; adding fermih=fermie in the list of arguments as well 1953 call getnel(doccde,dosdeltae,eigen0,entropy,fermie,fermie,maxocc,mband,nband,& 1954 & nelect,nkpt,nsppol,occ,occopt,1,tphysel,tsmear,11,wtk,1,nband(1)) 1955 end if 1956 1957 !--------------------------------------------------------------------------------- 1958 !Size of the frequency range 1959 1960 read(iunt,*)dom,wind 1961 close(iunt) 1962 mom=int(wind/dom) 1963 ABI_MALLOC(oml1,(mom)) 1964 do iom=1,mom 1965 oml1(iom)=tol10*1000._dp+dble(iom)*dom 1966 end do 1967 1968 ABI_MALLOC(cond_nd,(mom,3,3)) 1969 ABI_MALLOC(cond_kg,(mom,3,3)) 1970 ABI_MALLOC(cond_kg_cart,(mom,3,3)) 1971 ABI_MALLOC(cond_kg_xx,(mom)) 1972 ABI_MALLOC(cond_kg_yy,(mom)) 1973 ABI_MALLOC(trace,(mom)) 1974 ABI_MALLOC(cond_kg_zz,(mom)) 1975 ABI_MALLOC(cond_tot,(mom)) 1976 ABI_MALLOC(kin11,(mom)) 1977 ABI_MALLOC(kin12,(mom)) 1978 ABI_MALLOC(kin21,(mom)) 1979 ABI_MALLOC(kin22,(mom)) 1980 ABI_MALLOC(kin11_k,(mom)) 1981 ABI_MALLOC(kin12_k,(mom)) 1982 ABI_MALLOC(kin21_k,(mom)) 1983 ABI_MALLOC(kin22_k,(mom)) 1984 ABI_MALLOC(Kth,(mom)) 1985 ABI_MALLOC(Stp,(mom)) 1986 write(std_out,'(a,i8,2f10.5,a)')' mom,wind,dom =',mom,wind,dom,' Ha' 1987 1988 !--------------------------------------------------------------------------------- 1989 1990 kin11 = zero 1991 kin12 = zero 1992 kin21 = zero 1993 kin22 = zero 1994 np_sum = zero 1995 socc = zero 1996 cond_kg = zero 1997 1998 !LOOP OVER SPINS 1999 do isppol=1,nsppol 2000 ! 2001 bdtot_index = 0 2002 bd2tot_index = 0 2003 2004 deltae = zero 2005 ! 2006 ! BIG FAT k POINT LOOP 2007 ! 2008 do ikpt=1,nkpt 2009 2010 nband_k=nband(ikpt+(isppol-1)*nkpt) 2011 2012 ABI_MALLOC(eig0_k,(nband_k)) 2013 ABI_MALLOC(eig1_k,(2*nband_k**2,3)) 2014 ABI_MALLOC(occ_k,(nband_k)) 2015 ABI_MALLOC(doccde_k,(nband_k)) 2016 ABI_MALLOC(dhdk2_r,(3,3,nband_k,nband_k)) 2017 ABI_MALLOC(dhdk2_g,(nband_k,nband_k)) 2018 2019 cond_nd = zero 2020 kin11_k = zero 2021 kin12_k = zero 2022 kin21_k = zero 2023 kin22_k = zero 2024 np_sum_k1 = zero 2025 np_sum_k2 = zero 2026 socc_k = zero 2027 dhdk2_r = zero 2028 dhdk2_g = zero 2029 2030 ! eigenvalue for k-point 2031 eig0_k(:)=eigen0(1+bdtot_index:nband_k+bdtot_index) 2032 ! first derivative eigenvalues for k-point 2033 eig1_k(:,1)=eigen11(1+bd2tot_index:2*nband_k**2+bd2tot_index) 2034 eig1_k(:,2)=eigen12(1+bd2tot_index:2*nband_k**2+bd2tot_index) 2035 eig1_k(:,3)=eigen13(1+bd2tot_index:2*nband_k**2+bd2tot_index) 2036 ! occupation numbers for k-point 2037 occ_k(:)=occ(1+bdtot_index:nband_k+bdtot_index) 2038 ! derivative of occupation number for k-point 2039 doccde_k(:)=doccde(1+bdtot_index:nband_k+bdtot_index) 2040 2041 ! LOOP OVER BAND 2042 do iband=1,nband_k 2043 do jband=1,nband_k 2044 ! 2045 ! TODO : replace with BLAS calls 2046 do l1=1,3 2047 do l2=1,3 2048 do ii=1,3 2049 do jj=1,3 2050 dhdk2_r(l1,l2,iband,jband)=dhdk2_r(l1,l2,iband,jband)+(rprimd(l1,ii)& 2051 & *eig1_k(2*iband-1+(jband-1)*2*nband_k,ii)*& 2052 & rprimd(l2,jj)*eig1_k(2*iband-1+(jband-1)*2*nband_k,jj)& 2053 & +rprimd(l1,ii)*eig1_k(2*iband +(jband-1)*2*nband_k,ii)*& 2054 & rprimd(l2,jj)*eig1_k(2*iband+(jband-1)*2*nband_k,jj)) 2055 end do 2056 end do 2057 end do 2058 end do 2059 2060 do l1=1,3 2061 do l2=1,3 2062 dhdk2_r(l1,l2,iband,jband)=dhdk2_r(l1,l2,iband,jband)/two_pi/two_pi 2063 end do 2064 end do 2065 2066 ! TODO: replace with BLAS calls 2067 do l1=1,3 2068 do l2=1,3 2069 dhdk2_g(iband,jband)=dhdk2_g(iband,jband)+gmet_inv(l1,l2)*( & 2070 & eig1_k(2*iband-1+(jband-1)*2*nband_k,l1)*& 2071 & eig1_k(2*iband-1+(jband-1)*2*nband_k,l2) & 2072 & +eig1_k(2*iband +(jband-1)*2*nband_k,l1)*& 2073 & eig1_k(2*iband +(jband-1)*2*nband_k,l2)) 2074 end do 2075 end do 2076 dhdk2_g(iband,jband)=dhdk2_g(iband,jband)/two_pi/two_pi 2077 2078 diff_occ = occ_k(iband)-occ_k(jband) 2079 ! if (dabs(diff_occ)>=tol8) then 2080 2081 ! Conductivity for each omega 2082 omin = zero 2083 do iom=1,mom 2084 oml=oml1(iom) 2085 if (jband>iband) then 2086 sig= dhdk2_g(iband,jband)& 2087 & *(diff_occ)/oml*(dexp(-((eig0_k(jband)-eig0_k(iband)-oml)/dom)**2)& 2088 & -dexp(-((eig0_k(iband)-eig0_k(jband)-oml)/dom)**2)) 2089 kin11_k(iom)=kin11_k(iom)+sig 2090 kin12_k(iom)=kin12_k(iom)-sig*(eig0_k(jband)-fermie) 2091 kin21_k(iom)=kin21_k(iom)-sig*(eig0_k(iband)-fermie) 2092 kin22_k(iom)=kin22_k(iom) + & 2093 & sig*(eig0_k(iband)-fermie)*(eig0_k(jband)-fermie) 2094 end if 2095 do l1=1,3 2096 do l2=1,3 2097 cond_nd(iom,l1,l2)=cond_nd(iom,l1,l2) +dhdk2_r(l1,l2,iband,jband)& 2098 & *(diff_occ)/oml*dexp(-((eig0_k(jband)-eig0_k(iband)-oml)/dom)**2) 2099 end do 2100 end do 2101 2102 end do 2103 2104 ! Sumrule start 2105 if (dabs(eig0_k(iband)-eig0_k(jband))>=tol10) then 2106 np_sum_k1=np_sum_k1 -dhdk2_g(iband,jband)& 2107 & *(diff_occ)/(eig0_k(iband)-eig0_k(jband)) 2108 else 2109 np_sum_k2=np_sum_k2 - doccde_k(iband)*dhdk2_g(iband,jband) 2110 end if 2111 2112 2113 ! end loop over band 2114 end do 2115 socc_k=socc_k+occ_k(iband) 2116 end do 2117 2118 do iom=1,mom 2119 kin11(iom)=kin11(iom)+wtk(ikpt)*kin11_k(iom) 2120 kin12(iom)=kin12(iom)+wtk(ikpt)*kin12_k(iom) 2121 kin21(iom)=kin21(iom)+wtk(ikpt)*kin21_k(iom) 2122 kin22(iom)=kin22(iom)+wtk(ikpt)*kin22_k(iom) 2123 do l1=1,3 2124 do l2=1,3 2125 cond_kg(iom,l1,l2)=cond_kg(iom,l1,l2)+wtk(ikpt)*cond_nd(iom,l1,l2) 2126 end do 2127 end do 2128 end do 2129 2130 np_sum=np_sum + wtk(ikpt)*(np_sum_k1+np_sum_k2) 2131 socc=socc+wtk(ikpt)*socc_k 2132 2133 ! Validity limit 2134 deltae=deltae+(eig0_k(nband_k)-fermie) 2135 2136 bd2tot_index=bd2tot_index+2*nband_k**2 2137 bdtot_index=bdtot_index+nband_k 2138 ABI_FREE(eig0_k) 2139 ABI_FREE(eig1_k) 2140 ABI_FREE(occ_k) 2141 ABI_FREE(doccde_k) 2142 ABI_FREE(dhdk2_r) 2143 ABI_FREE(dhdk2_g) 2144 ! End loop over k 2145 end do 2146 2147 write(std_out,'(a,3f10.5)')' sumrule =',np_sum/socc/three,socc 2148 write(std_out,'(a,f10.5,a,f10.5,a)')& 2149 & ' Emax-Efermi =',deltae/dble(nkpt),' Ha',deltae/dble(nkpt)*Ha_eV,' eV' 2150 2151 !End loop over spins 2152 end do 2153 2154 cond_kg=cond_kg*two_pi*third/(dom*ucvol)*half/dsqrt(pi) 2155 2156 2157 !Check that new output file does NOT exist 2158 !Keep this line : prevent silly (compiler ?) bug on HP 8000 2159 write(std_out,*)' conducti : call isfile ' 2160 ! 2161 if (open_file(trim(filnam_out)//'_tens',msg,newunit=tens_unt,form='formatted',action="write")/=0) then 2162 ABI_ERROR(msg) 2163 end if 2164 if (open_file(trim(filnam_out)//'_Lij',msg,newunit=lij_unt,form='formatted',action="write")/=0) then 2165 ABI_ERROR(msg) 2166 end if 2167 write(lij_unt,'(a)')' # omega(ua) L12 L21 L22 L22' 2168 2169 if (open_file(trim(filnam_out)//'_sig',msg,newunit=sig_unt,form='formatted',action="write")/=0) then 2170 ABI_ERROR(msg) 2171 end if 2172 write(sig_unt,'(a)')' # omega(ua) hbar*omega(eV) cond(ua) cond(ohm.cm)-1' 2173 2174 if (open_file(trim(filnam_out)//'_Kth',msg,newunit=kth_unt,form='formatted',action="write")/=0) then 2175 ABI_ERROR(msg) 2176 end if 2177 write(kth_unt,'(a)')& 2178 & ' #omega(ua) hbar*omega(eV) thermal cond(ua) Kth(W/m/K) thermopower(ua) Stp(microohm/K)' 2179 2180 if (open_file(trim(filnam_out)//'.out',msg,newunit=ocond_unt,form='formatted',action="write")/=0) then 2181 ABI_ERROR(msg) 2182 end if 2183 write(ocond_unt,'(a)' )' Conducti output file:' 2184 write(ocond_unt,'(a)' )' Contains all results produced by conducti utility' 2185 write(ocond_unt,'(a)' )' ' 2186 write(ocond_unt,'(a)')' # omega(ua) cond(ua) thermal cond(ua) thermopower(ua)' 2187 2188 !Keep this line : prevent silly (compiler ?) bug on HP 8000 2189 write(std_out,*)' conducti : after call isfile ' 2190 2191 !Compute thermal conductivity and thermopower 2192 do iom=1,mom 2193 oml=oml1(iom) 2194 kin11(iom)=kin11(iom)*two_pi*third/(dom*ucvol)*half/dsqrt(pi) 2195 kin21(iom)=kin21(iom)*two_pi*third/(dom*ucvol)*half/dsqrt(pi) 2196 kin12(iom)=kin12(iom)*two_pi*third/(dom*ucvol)*half/dsqrt(pi) 2197 kin22(iom)=kin22(iom)*two_pi*third/(dom*ucvol)*half/dsqrt(pi) 2198 if (dabs(kin11(iom))<10.0d-20) kin11(iom)=zero 2199 Kth(iom)=kin22(iom) 2200 Stp(iom)=zero 2201 if(kin11(iom)/=zero) then 2202 Kth(iom)=Kth(iom)-(kin12(iom)*kin21(iom)/kin11(iom)) 2203 Stp(iom)=kin12(iom)/(kin11(iom)*Tatm) 2204 end if 2205 if (dabs(Kth(iom))<10.0d-20) Kth(iom)=zero 2206 if (dabs(Stp(iom))<10.0d-20) Stp(iom)=zero 2207 if (dabs(kin12(iom))<10.0d-20) kin12(iom)=zero 2208 if (dabs(kin21(iom))<10.0d-20) kin21(iom)=zero 2209 if (dabs(kin22(iom))<10.0d-20) kin22(iom)=zero 2210 2211 write(lij_unt,'(f12.5,4es22.12)')oml,kin12(iom),kin21(iom),kin22(iom),kin22(iom)/Tatm*3.4057d9 2212 write(sig_unt,'(2f12.5,2es22.12)') oml,oml*Ha_eV,kin11(iom),kin11(iom)*Ohmcm 2213 write(kth_unt,'(2f12.5,4es22.12)') oml,oml*Ha_eV,Kth(iom),Kth(iom)*3.4057d9/Tatm,Stp(iom),Stp(iom)*3.6753d-2 2214 write(ocond_unt,'(1f12.5,3es22.12)') oml,kin11(iom),Kth(iom),Stp(iom) 2215 end do 2216 2217 write(tens_unt,'(a)' )' Conductivity file ' 2218 write(tens_unt,'(a)' )' ----------------- ' 2219 write(tens_unt,'(a)' )' Contain first the full conductivity tensor, for the desired set of energies,' 2220 write(tens_unt,'(a)' )' then, the three principal values, for the desired set of energies' 2221 write(tens_unt,'(a)' )' (note that eigenvalues are not directly associated with xx,yy,zz)' 2222 write(tens_unt,'(a)' )' ' 2223 2224 write(ocond_unt,'(a)' )' ' 2225 write(ocond_unt,'(a)' )' full conductivity tensor, for the desired set of energies' 2226 write(ocond_unt,'(a)' )' then, the three principal values, for the desired set of energies:' 2227 2228 do iom=1,mom 2229 oml=oml1(iom)*Ha_eV 2230 write(tens_unt, '(a,es16.6,a)' ) ' energy (in eV) =',oml,', conductivity tensor (in Ohm.cm-1) follows :' 2231 write(ocond_unt, '(a,es16.6,a)' ) ' energy (in eV) =',oml,', conductivity tensor (in Ohm.cm-1) follows :' 2232 do l1=1,3 2233 write(tens_unt,"(3f25.15)") (cond_kg(iom,l1,l2)*Ohmcm,l2=1,3) 2234 write(ocond_unt,"(3f25.15)") (cond_kg(iom,l1,l2)*Ohmcm,l2=1,3) 2235 end do 2236 end do 2237 2238 !Diagonalizing the conductivity matrix for sigma_xx,sigma_yy,sigma_zz 2239 cond_kg_xx=0d0 2240 cond_kg_yy=0d0 2241 cond_kg_zz=0d0 2242 !trace=0d0 ! Used for checking with the original version of the code 2243 do iom=1,mom 2244 oml=oml1(iom)*Ha_eV 2245 cond_kg_w=0d0 2246 do l1=1,3 2247 do l2=1,3 2248 cond_kg_w(l1,l2)=cond_kg(iom,l1,l2) 2249 end do 2250 end do 2251 call jacobi(cond_kg_w,3,3,eig_cond,z,nrot) 2252 2253 ! When the value is too small, set it to zero before printing 2254 if(abs(eig_cond(1))<tol10)eig_cond(1)=zero 2255 if(abs(eig_cond(2))<tol10)eig_cond(2)=zero 2256 if(abs(eig_cond(3))<tol10)eig_cond(3)=zero 2257 2258 cond_kg_xx(iom)=eig_cond(1) 2259 cond_kg_yy(iom)=eig_cond(2) 2260 cond_kg_zz(iom)=eig_cond(3) 2261 ! trace(iom)=cond_kg_xx(iom)+cond_kg_yy(iom)+cond_kg_zz(iom) 2262 end do 2263 2264 !DEBUG Keep this line : prevent silly (compiler ?) bug on HP 8000 2265 !write(std_out,*)' conducti : after open ' 2266 !ENDDEBUG 2267 2268 write(tens_unt,'(a,a)')ch10,' Now, print principal values of the conductivity tensor.' 2269 write(tens_unt,'(a)')' ' 2270 write(tens_unt,'(a)')' #omega(ua) cond_1(ua) cond_2(ua) cond_3(ua) cond_tot(ua)' 2271 2272 write(ocond_unt,'(a)')' ' 2273 write(ocond_unt,'(a,a)')ch10,' Now, print principal values of the conductivity tensor.' 2274 write(ocond_unt,'(a)')' ' 2275 write(ocond_unt,'(a)')' #omega(ua) cond_1(ua) cond_2(ua) cond_3(ua) cond_tot(ua)' 2276 2277 2278 do iom=1,mom 2279 cond_tot(iom)=cond_kg_xx(iom)+cond_kg_yy(iom)+cond_kg_zz(iom) 2280 write(tens_unt,'(f12.5,4es22.12)')oml1(iom),cond_kg_xx(iom),cond_kg_yy(iom),cond_kg_zz(iom),cond_tot(iom) 2281 write(ocond_unt,'(f12.5,4es22.12)')oml1(iom),cond_kg_xx(iom),cond_kg_yy(iom),cond_kg_zz(iom),cond_tot(iom) 2282 end do 2283 2284 write(tens_unt,*) 2285 write(tens_unt,'(a)')' #hbar*omega(eV) cond_1(ohm.cm)-1 cond_2(ohm.cm)-1 cond_3(ohm.cm)-1 cond_t(ohm.cm)-1' 2286 write(ocond_unt,*) 2287 write(ocond_unt,'(a)')' #hbar*omega(eV) cond_1(ohm.cm)-1 cond_2(ohm.cm)-1 cond_3(ohm.cm)-1 cond_t(ohm.cm)-1' 2288 2289 do iom=1,mom 2290 oml=oml1(iom)*Ha_eV 2291 cond_tot(iom)=cond_tot(iom)*Ohmcm 2292 cond_kg_xx(iom)=cond_kg_xx(iom)*Ohmcm 2293 cond_kg_yy(iom)=cond_kg_yy(iom)*Ohmcm 2294 cond_kg_zz(iom)=cond_kg_zz(iom)*Ohmcm 2295 write(tens_unt,'(f12.5,4es22.12)')oml,cond_kg_xx(iom),cond_kg_yy(iom),cond_kg_zz(iom),cond_tot(iom) 2296 write(ocond_unt,'(f12.5,4es22.12)')oml,cond_kg_xx(iom),cond_kg_yy(iom),cond_kg_zz(iom),cond_tot(iom) 2297 end do 2298 2299 !Calculate the imaginary part of the conductivity (principal value) 2300 !+derived optical properties. 2301 call msig(kin11,mom,oml1,filnam_out) 2302 2303 close(tens_unt) 2304 close(lij_unt) 2305 close(sig_unt) 2306 close(kth_unt) 2307 close(ocond_unt) 2308 2309 ABI_FREE(nband) 2310 ABI_FREE(oml1) 2311 ABI_FREE(occ) 2312 ABI_FREE(eigen11) 2313 ABI_FREE(eigen12) 2314 ABI_FREE(eigen13) 2315 ABI_FREE(eigen0) 2316 ABI_FREE(doccde) 2317 ABI_FREE(wtk) 2318 ABI_FREE(cond_nd) 2319 ABI_FREE(cond_kg) 2320 ABI_FREE(cond_kg_cart) 2321 ABI_FREE(cond_kg_xx) 2322 ABI_FREE(cond_kg_yy) 2323 ABI_FREE(trace) 2324 ABI_FREE(cond_kg_zz) 2325 ABI_FREE(cond_tot) 2326 ABI_FREE(kin11) 2327 ABI_FREE(kin22) 2328 ABI_FREE(kin12) 2329 ABI_FREE(kin21) 2330 ABI_FREE(kin11_k) 2331 ABI_FREE(kin22_k) 2332 ABI_FREE(kin12_k) 2333 ABI_FREE(kin21_k) 2334 ABI_FREE(Stp) 2335 ABI_FREE(Kth) 2336 call hdr%free() 2337 2338 end subroutine conducti_nc
m_conducti/conducti_paw [ Functions ]
[ Top ] [ m_conducti ] [ Functions ]
NAME
conducti_paw
FUNCTION
This program computes the elements of the optical frequency dependent conductivity tensor and the conductivity along the three principal axes from the Kubo-Greenwood formula for PAW formalism
INPUTS
filnam=generic name for input data filnam_out=generic name for output data [varocc]=if true, read arbitrary occupations from a file
OUTPUT
Only printing
NOTES
bantot doccde(mband*nkpt_rbz*nsppol)=derivative of occ_rbz wrt the energy. dom=frequency range eigen0(mband*nkpt_rbz*nsppol)=GS eigenvalues at k (hartree). eigen11(2,nkpt,mband,mband,nsppol)=first-order eigenvalues (hartree) in direction x eigen12(2,nkpt,mband,mband,nsppol)=first-order eigenvalues (hartree) in direction y eigen13(2,nkpt,mband,mband,nsppol)=first-order eigenvalues (hartree) in direction z ecut=kinetic energy planewave cutoff (hartree). fermie= fermi energy (Hartree) gmet(3,3)=reciprocal space metric ($\textrm{bohr}^{2}$). gprimd(3,3)=dimensional primitive translations for reciprocal space(bohr^-1). kin11= Onsager kinetic coeficient=optical conductivity kin12= Onsager kinetic coeficient kin21= Onsager kinetic coeficient kin22= Onsager kinetic coeficient Kth=thermal conductivity mom=number of frequency for conductivity computation mband=maximum number of bands. natom = number of atoms in the unit cell. nband(nkpt*nsppol)=number of bands at each RF k point for each spin. nkpt=number of k points in the IBZ for this perturbation ngfft(3)=integer fft box dimensions. nspinor=number of spinorial components of the wavefunctions. nsppol=1 for unpolarized, 2 for spin-polarized. ntypat = number of atom types. occ(mband*nkpt*nsppol)=occupation number for each band and k. occopt==option for occupancies rmet(3,3)=real space metric ($\textrm{bohr}^{2}$).sigx(mom,nphicor)) rprimd(3,3)=real space primitive translations. of primitive translations. Sth=thermopower tsmear=smearing width (or temperature) in Hartree ucvol=unit cell volume in ($\textrm{bohr}^{3}$). wind=frequency windows for computations of sigma wtk(nkpt)=weight assigned to each k point. znucl(natom)=atomic number of atoms np_sum=noziere-pines sumrule
SOURCE
126 subroutine conducti_paw(filnam,filnam_out,varocc) 127 128 !Arguments ----------------------------------- 129 !scalars 130 character(len=fnlen) :: filnam,filnam_out 131 integer, optional :: varocc 132 133 !Local variables------------------------------- 134 !scalars 135 integer,parameter :: master=0 136 integer :: bsize,bd_stride,dimid,iomode,bantot,bdtot_index,ncid,varid,nb_per_proc,etiq 137 integer :: comm,fform1,headform,iband,ijband,ierr,ikpt,master_band 138 integer :: iom,isppol,jband,l1,l2,mband,me,mpierr,mom 139 integer :: natom,nband_k,nkpt,nproc,nspinor,nsppol,ntypat 140 integer :: occopt,iunt,opt_unt,occ_unt,iocc,my_iband,pnp_size 141 integer :: lij_unt,sig_unt,kth_unt,ocond_unt,occunit,occnpt 142 logical :: nc_unlimited,mykpt,myband,iomode_estf_mpiio,read_half_dipoles 143 real(dp) :: dirac,del,deltae,deltae_min,deltae_min_tmp,dhdk2_g,diff_eig,diff_occ 144 real(dp) :: dosdeltae,ecut,entropy,fact_diag,fermie,fermih,kin_fact,maxocc 145 real(dp) :: np_sum,np_sum_k1,np_sum_k2,omin,omax,dom,oml,sig,socc,socc_k 146 real(dp) :: Tatm,tphysel,tsmear,ucvol,eig_in_max,eig_in_min 147 character(len=fnlen) :: filnam1,filnam_gen,occfile 148 character(len=500) :: msg 149 type(hdr_type) :: hdr 150 type(MPI_type) :: mpi_enreg 151 !arrays 152 integer :: nc_count_5(5),nc_count_6(6),nc_start_5(5),nc_start_6(6),nc_stride_5(5),nc_stride_6(6) 153 integer,allocatable :: nband(:) 154 real(dp) :: dhdk2_r(3,3),gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3) 155 real(dp),allocatable :: cond_nd(:,:,:),cond_nd_k(:,:,:) 156 real(dp),allocatable :: doccde(:),doccde_k(:),eig0_k(:),eigen0(:),eig0nc(:,:,:) 157 real(dp),allocatable :: occ(:),occ_k(:),wtk(:),oml1(:),occ_in(:),eig_in(:),occ_tmp(:),ypp(:) 158 real(dp),allocatable :: kin11(:,:),kin12(:),kin21(:),kin22(:) 159 real(dp),allocatable :: kin11_k(:),kin12_k(:),kin21_k(:),kin22_k(:),Kth(:),Stp(:) 160 real(dp),allocatable :: psinablapsi(:,:,:),sig_abs(:) 161 162 ! ********************************************************************************* 163 164 ! --------------------------------------------------------------------------------- 165 ! Read input data 166 167 !Global MPI communicator 168 comm = xmpi_world 169 nproc = xmpi_comm_size(comm) 170 me = xmpi_comm_rank(comm) 171 172 !Read input parameters file 173 if (me==master) then 174 if (open_file(filnam,msg,newunit=iunt,form='formatted',action="read",status="old")/=0) then 175 ABI_ERROR(msg) 176 end if 177 rewind(iunt) 178 read(iunt,*) 179 read(iunt,'(a)') filnam_gen ! Generic name for the files 180 filnam1=trim(filnam_gen)//'_OPT' 181 ! Read frequency range 182 read(iunt,*) dom,omin,omax,mom 183 ! In case of varocc read filename of occupation datafile 184 if (present(varocc)) then 185 if (me==master) then 186 write(std_out,*) 'Warning, this undocumented feature is highly experimental' 187 write(std_out,*) 'and of limited physical validity, proceed with extreme caution!!!' 188 end if 189 read(iunt,*) occfile !filename of the non-eq distribution function 190 end if 191 close(iunt) 192 end if 193 194 !Send data to all procs 195 call xmpi_bcast(dom,master,comm,mpierr) 196 call xmpi_bcast(omin,master,comm,mpierr) 197 call xmpi_bcast(omax,master,comm,mpierr) 198 call xmpi_bcast(mom,master,comm,mpierr) 199 200 ! --------------------------------------------------------------------------------- 201 ! Read OPT file 202 203 !Check for FORTRAN/.nc OPT file and set iomode to IO_MODE_FORTRAN_MASTER/IO_MODE_ETSF 204 if (me==master) then 205 call nctk_fort_or_ncfile(filnam1,iomode,msg) 206 if (iomode/=IO_MODE_ETSF) iomode=IO_MODE_FORTRAN_MASTER 207 end if 208 call xmpi_bcast(filnam1,master,comm,mpierr) 209 call xmpi_bcast(iomode,master,comm,mpierr) 210 211 !Open OPT file and read HEADER 212 if (me==master) then 213 if (iomode==IO_MODE_ETSF) then 214 NCF_CHECK(nctk_open_read(ncid,filnam1,xmpi_comm_self)) 215 call hdr_ncread(hdr,ncid,fform1) 216 else 217 if (open_file(filnam1,msg,newunit=opt_unt,form="unformatted",status="old")/=0) then 218 ABI_ERROR(msg) 219 end if 220 call hdr_fort_read(hdr,opt_unt,fform1,rewind=.true.) 221 end if 222 ABI_CHECK(fform1/=0,sjoin("Error while reading ",filnam1)) 223 ABI_CHECK(fform1==610.or.fform1==620,"Conducti requires an OPT file with fform=610 or 620!") 224 end if 225 call hdr%bcast(master,me,comm) 226 call xmpi_bcast(fform1,master,comm,mpierr) 227 228 !Extract info from the header 229 headform=hdr%headform 230 bantot=hdr%bantot 231 ecut=hdr%ecut_eff 232 natom=hdr%natom 233 nkpt=hdr%nkpt 234 nspinor=hdr%nspinor 235 nsppol=hdr%nsppol 236 ntypat=hdr%ntypat 237 occopt=hdr%occopt 238 rprimd(:,:)=hdr%rprimd(:,:) 239 fermie=hdr%fermie 240 tsmear=hdr%tsmear 241 ABI_MALLOC(nband,(nkpt*nsppol)) 242 ABI_MALLOC(occ,(bantot)) 243 ABI_MALLOC(wtk,(nkpt)) 244 nband(1:nkpt*nsppol)=hdr%nband(1:nkpt*nsppol) 245 occ(1:bantot)=hdr%occ(1:bantot) 246 wtk(1:nkpt)=hdr%wtk(1:nkpt) 247 mband=maxval(nband(:)) ! Get mband, as the maximum value of nband(nkpt) 248 call metric(gmet,gprimd,-1,rmet,rprimd,ucvol) ! Get metrics of simulation cell 249 250 !Read eigenvalues 251 ABI_MALLOC(eigen0,(mband*nkpt*nsppol)) 252 if (me==master) then 253 if (iomode==IO_MODE_ETSF) then 254 varid=nctk_idname(ncid,"eigenvalues") 255 ABI_MALLOC(eig0nc,(mband,nkpt,nsppol)) 256 #ifdef HAVE_NETCDF 257 NCF_CHECK(nf90_get_var(ncid,varid,eig0nc)) 258 #endif 259 eigen0 = reshape(eig0nc,[mband*nkpt*nsppol]) 260 ABI_FREE(eig0nc) 261 !Close file here because the rest will possibly be read with collective I/O 262 #ifdef HAVE_NETCDF 263 NCF_CHECK(nf90_close(ncid)) 264 #endif 265 else 266 read(opt_unt)(eigen0(iband),iband=1,mband*nkpt*nsppol) 267 end if 268 end if 269 call xmpi_bcast(eigen0,master,comm,mpierr) 270 271 !In case of varocc, use arbitrary occupations 272 !Read occfile and overwrite occ by interpolating the data in the input file 273 if (present(varocc)) then 274 if (me==master) then 275 ABI_MALLOC(occ_tmp,(bantot)) 276 if (open_file(occfile,msg,newunit=occ_unt,form='formatted')/=0) then 277 ABI_ERROR(msg) 278 end if 279 ! Get units used in occfile (1=Ha, 2= eV) 280 read(occ_unt,*) occunit 281 read(occ_unt,*) occnpt 282 ABI_MALLOC(occ_in,(occnpt)) 283 ABI_MALLOC(eig_in,(occnpt)) 284 do iocc=1,occnpt 285 read(occ_unt,*) eig_in(iocc),occ_in(iocc) 286 if (occunit==2) then !Convert units from eV to Hartree 287 eig_in(iocc)=eig_in(iocc)/Ha_eV 288 occ_in(iocc)=occ_in(iocc) 289 end if 290 end do 291 close(occ_unt) 292 ! Interpolation 293 ABI_MALLOC(ypp,(occnpt)) 294 call spline(eig_in,occ_in,occnpt,zero,zero,ypp) 295 ! Interpolate neccessary values 296 eig_in_max=maxval(eig_in) 297 eig_in_min=minval(eig_in) 298 do iocc=1,bantot 299 ! Check for Extrapolation and set them to physically sound values 300 if (eigen0(iocc)<eig_in_min) then 301 occ_tmp(iocc)=one 302 else if (eigen0(iocc)>eig_in_max) then 303 occ_tmp(iocc)=zero 304 else 305 call splint(occnpt,eig_in,occ_in,ypp,1,eigen0(iocc),occ_tmp(iocc),ierr) 306 end if 307 end do 308 occ=occ_tmp 309 ! Clean up 310 ABI_FREE(ypp) 311 ABI_FREE(occ_tmp) 312 ABI_FREE(occ_in) 313 ABI_FREE(eig_in) 314 end if 315 call xmpi_bcast(occ,master,comm,mpierr) 316 occopt=2 317 end if ! varocc? 318 319 !--------------------------------------------------------------------------------- 320 ! Prepare kpt/band parallelization 321 322 call init_mpi_enreg(mpi_enreg) 323 mpi_enreg%comm_kpt=comm 324 mpi_enreg%me_kpt=me 325 mpi_enreg%nproc_spkpt=nproc 326 mpi_enreg%paralbd=1 327 ABI_MALLOC(mpi_enreg%proc_distrb,(nkpt,mband,nsppol)) 328 ABI_MALLOC(mpi_enreg%my_kpttab,(nkpt)) 329 call distrb2(mband,nb_per_proc,nband,nkpt,nproc,nsppol,mpi_enreg) 330 call initmpi_band(nkpt,mpi_enreg,nband,nkpt,nsppol) 331 332 !--------------------------------------------------------------------------------- 333 !Print some data 334 335 Tatm=tsmear*Ha_K 336 if (me==master) then 337 write(std_out,*) 338 write(std_out,'(a)' )' Input data:' 339 write(std_out,'(a,i8,3f10.5,a)')' npts,omin,omax,width =',mom,omin,omax,dom,' Ha' 340 write(std_out,*) 341 write(std_out,'(a,3f10.5,a)' )' rprimd(bohr) =',rprimd(1:3,1) 342 write(std_out,'(a,3f10.5,a)' )' ',rprimd(1:3,2) 343 write(std_out,'(a,3f10.5,a)' )' ',rprimd(1:3,3) 344 write(std_out,'(a,i8)') ' natom =',natom 345 write(std_out,'(a,3i8)') ' nkpt,mband,nsppol =',nkpt,mband,nsppol 346 write(std_out, '(a, f10.5,a)' ) ' ecut =',ecut,' Ha' 347 write(std_out,'(a,f10.5,a,f10.5,a)' )' fermie =',fermie,' Ha',fermie*Ha_eV,' eV' 348 write(std_out,'(a,f12.5,a,f12.5,a)') ' Temp =',tsmear,' Ha ',Tatm,' Kelvin' 349 end if 350 351 ! --------------------------------------------------------------------------------- 352 ! Compute derivative of occupations wrt the energy 353 354 ABI_MALLOC(doccde,(mband*nkpt*nsppol)) 355 if (occopt==1) then 356 if (me==master) then 357 write(std_out,'(a,i4)') ' occopt =',occopt 358 end if 359 doccde=zero 360 else 361 tphysel=zero 362 maxocc=two/(nsppol*nspinor) 363 end if 364 if (occopt==2) then 365 tsmear=one 366 entropy=one 367 if (me==master) then 368 write(std_out,'(a)') ' occopt=2 fixed occupation case' 369 end if 370 else 371 call getnel(doccde,dosdeltae,eigen0,entropy,fermie,fermih,maxocc,mband,nband,& 372 & socc,nkpt,nsppol,occ,occopt,1,tphysel,tsmear,12,wtk) 373 entropy=tsmear*entropy 374 if (me==master) then 375 write(std_out, '(a,es22.12)') ' tsmear*entropy (Ha) =',entropy 376 end if 377 entropy=entropy/socc 378 if (me==master) then 379 write(std_out, '(a,es22.12)') ' tsmear*entropy (Ha/e) =',entropy 380 end if 381 endif 382 383 !--------------------------------------------------------------------------------- 384 ! Determine the frequency range and allocate frequency-dependent arrays 385 386 del=(omax-omin)/(mom-1) 387 ABI_MALLOC(oml1,(mom)) 388 do iom=1,mom 389 oml1(iom)=omin+dble(iom-1)*del 390 end do 391 392 ABI_MALLOC(kin11,(mom,nsppol)) 393 ABI_MALLOC(kin12,(mom)) 394 ABI_MALLOC(kin21,(mom)) 395 ABI_MALLOC(kin22,(mom)) 396 ABI_MALLOC(cond_nd,(3,3,mom)) 397 ABI_MALLOC(sig_abs,(mom)) 398 ABI_MALLOC(Kth,(mom)) 399 ABI_MALLOC(Stp,(mom)) 400 kin11 = zero 401 kin12 = zero 402 kin21 = zero 403 kin22 = zero 404 cond_nd = zero 405 sig_abs = zero 406 Kth = zero 407 Stp = zero 408 409 !--------------------------------------------------------------------------------- 410 !Prepare valence-valence dipoles reading 411 412 iomode_estf_mpiio=(iomode==IO_MODE_ETSF.and.nctk_has_mpiio.and.use_netcdf_mpiio) 413 414 !In case of netCDF access to OPT file, prepare collective I/O 415 if (iomode == IO_MODE_ETSF) then 416 if (iomode_estf_mpiio) then 417 NCF_CHECK(nctk_open_read(ncid,filnam1,comm)) 418 varid=nctk_idname(ncid,"dipole_valence_valence") 419 if (nproc>1) then 420 NCF_CHECK(nctk_set_collective(ncid,varid)) 421 end if 422 #ifdef HAVE_NETCDF 423 nc_unlimited=(nf90_inq_dimid(ncid,"unlimited_bands",dimid)==NF90_NOERR) 424 read_half_dipoles=(nf90_inq_dimid(ncid,"max_number_of_state_pairs",dimid)==NF90_NOERR) 425 #endif 426 else 427 if (me==master) then 428 NCF_CHECK(nctk_open_read(ncid,filnam1,xmpi_comm_self)) 429 varid=nctk_idname(ncid,"dipole_valence_valence") 430 !if (nctk_has_mpiio.and.(.not.use_netcdf_mpiio)) then 431 ! NCF_CHECK(nctk_set_collective(ncid,varid)) 432 !end if 433 #ifdef HAVE_NETCDF 434 nc_unlimited=(nf90_inq_dimid(ncid,"unlimited_bands",dimid)==NF90_NOERR) 435 read_half_dipoles=(nf90_inq_dimid(ncid,"max_number_of_state_pairs",dimid)==NF90_NOERR) 436 #endif 437 end if 438 call xmpi_bcast(nc_unlimited,master,comm,ierr) 439 call xmpi_bcast(read_half_dipoles,master,comm,ierr) 440 end if 441 if (nc_unlimited.and.read_half_dipoles) then 442 msg="The OPT file has a wrong format!" 443 ABI_BUG(msg) 444 end if 445 else 446 read_half_dipoles=(fform1==620) 447 end if 448 449 if (iomode_estf_mpiio) then 450 !If MPI-IO, store only ib elements for each jb 451 ABI_MALLOC(psinablapsi,(2,3,mband)) 452 else 453 !If not, store all pairs (or half) 454 if (read_half_dipoles) then ! only ib>=jb 455 ABI_MALLOC(psinablapsi,(2,3,(mband*(mband+1))/2)) 456 else 457 ABI_MALLOC(psinablapsi,(2,3,mband*mband)) 458 end if 459 end if 460 pnp_size=size(psinablapsi) 461 462 !--------------------------------------------------------------------------------- 463 ! Compute conductivity 464 465 ABI_MALLOC(kin11_k,(mom)) 466 ABI_MALLOC(kin12_k,(mom)) 467 ABI_MALLOC(kin21_k,(mom)) 468 ABI_MALLOC(kin22_k,(mom)) 469 ABI_MALLOC(cond_nd_k,(3,3,mom)) 470 471 np_sum = zero 472 socc = zero 473 deltae = zero 474 deltae_min = 1.d99 475 476 !LOOP OVER SPINS/K 477 bdtot_index = 0 478 do isppol=1,nsppol 479 do ikpt=1,nkpt 480 etiq=ikpt+(isppol-1)*nkpt 481 nband_k=nband(ikpt+(isppol-1)*nkpt) 482 mykpt=.not.(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me)) 483 master_band=minval(mpi_enreg%proc_distrb(ikpt,1:nband_k,isppol)) 484 485 ! In case of non MPI-IO, has to read all (n,m) dipoles for this k-point 486 ! Master node reads and send to relevant processor 487 if (.not.iomode_estf_mpiio.and.me==master) then 488 if (iomode==IO_MODE_ETSF) then 489 psinablapsi=zero 490 #ifdef HAVE_NETCDF 491 if (nc_unlimited) then 492 nc_start_6=[1,1,1,ikpt,isppol,1] ; nc_count_6=[2,3,mband,1,1,mband] ; nc_stride_6=[1,1,1,1,1,1] 493 NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6)) 494 else if (.not.read_half_dipoles) then 495 nc_start_6=[1,1,1,1,ikpt,isppol] ; nc_count_6=[2,3,mband,mband,1,1] ; nc_stride_6=[1,1,1,1,1,1] 496 NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6)) 497 else 498 nc_start_5=[1,1,1,ikpt,isppol] ; nc_count_5=[2,3,(mband*(mband+1))/2,1,1] ; nc_stride_5=[1,1,1,1,1] 499 NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi,start=nc_start_5,stride=nc_stride_5,count=nc_count_5)) 500 end if 501 #endif 502 else 503 psinablapsi=zero 504 bsize=nband_k**2;if (read_half_dipoles) bsize=(nband_k*(nband_k+1))/2 505 read(opt_unt)(psinablapsi(1:2,1,ijband),ijband=1,bsize) 506 read(opt_unt)(psinablapsi(1:2,2,ijband),ijband=1,bsize) 507 read(opt_unt)(psinablapsi(1:2,3,ijband),ijband=1,bsize) 508 end if 509 if (.not.mykpt) then 510 call xmpi_exch(psinablapsi,pnp_size,master,psinablapsi,master_band,comm,etiq,ierr) 511 end if 512 end if 513 514 ! Select k-points for current proc 515 if (mykpt) then 516 517 ABI_MALLOC(eig0_k,(nband_k)) 518 ABI_MALLOC(occ_k,(nband_k)) 519 ABI_MALLOC(doccde_k,(nband_k)) 520 521 cond_nd_k = zero 522 kin11_k = zero 523 kin12_k = zero 524 kin21_k = zero 525 kin22_k = zero 526 np_sum_k1 = zero 527 np_sum_k2 = zero 528 socc_k = zero 529 530 ! k-dependent data 531 eig0_k(:)=eigen0(1+bdtot_index:nband_k+bdtot_index) 532 occ_k(:)=occ(1+bdtot_index:nband_k+bdtot_index) 533 doccde_k(:)=doccde(1+bdtot_index:nband_k+bdtot_index) 534 535 ! In case of non MPI-IO, receive all (n,m) dipoles from master proc 536 ! Then broadcast them to all band processors 537 if (.not.iomode_estf_mpiio) then 538 if (me/=master.and.me==master_band) then 539 call xmpi_exch(psinablapsi,pnp_size,master,psinablapsi,me,comm,etiq,ierr) 540 end if 541 call xmpi_bcast(psinablapsi,master,mpi_enreg%comm_band,mpierr) 542 end if 543 544 ! LOOP OVER BANDS n 545 do iband=1,nband_k 546 547 !If MPI-IO, store only ib elements for each jb 548 !If not, store all (ib,jb) pairs 549 my_iband=merge(1,iband,iomode_estf_mpiio) 550 551 ! Select bands for current proc 552 myband=(mpi_enreg%proc_distrb(ikpt,iband,isppol)==me) 553 if (myband) then 554 555 ! In case of MPI-IO, read valence-valence dipoles for band n 556 if (iomode_estf_mpiio) then 557 #ifdef HAVE_NETCDF 558 if (nc_unlimited) then 559 nc_start_6=[1,1,iband,ikpt,isppol,1] ; nc_count_6=[2,3,1,1,1,mband] ; nc_stride_6=[1,1,1,1,1,1] 560 NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6)) 561 else if (.not.read_half_dipoles) then 562 nc_start_6=[1,1,1,iband,ikpt,isppol] ; nc_count_6=[2,3,mband,1,1,1] ; nc_stride_6=[1,1,1,1,1,1] 563 NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6)) 564 else 565 nc_start_5=[1,1,(iband*(iband-1))/2+1,ikpt,isppol] ; nc_count_5=[2,3,iband,1,1] ; nc_stride_5=[1,1,1,1,1] 566 NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi,start=nc_start_5,stride=nc_stride_5,count=nc_count_5)) 567 end if 568 #endif 569 end if 570 571 ! LOOP OVER BANDS m 572 do jband=1,iband-1 573 diff_occ = occ_k(iband)-occ_k(jband) 574 diff_eig = eig0_k(iband)-eig0_k(jband) 575 if (dabs(diff_occ)>=tol8) then 576 577 dhdk2_r = zero 578 dhdk2_g = zero 579 580 if (read_half_dipoles) then 581 ijband=(my_iband*(my_iband-1))/2+jband 582 else 583 !psinablapsi size is mband for netCDF I/O, nband_k for Fortran I/O 584 bd_stride=merge(mband,nband_k,iomode==IO_MODE_ETSF) 585 ijband=(my_iband-1)*bd_stride+jband 586 end if 587 588 do l2=1,3 589 do l1=1,3 590 dhdk2_r(l1,l2)=dhdk2_r(l1,l2)+(& 591 & psinablapsi(1,l1,ijband)*psinablapsi(1,l2,ijband)& 592 & +psinablapsi(2,l1,ijband)*psinablapsi(2,l2,ijband)) 593 end do 594 end do 595 do l1=1,3 596 dhdk2_g=dhdk2_g & 597 & +(psinablapsi(1,l1,ijband)*psinablapsi(1,l1,ijband) & 598 & +psinablapsi(2,l1,ijband)*psinablapsi(2,l1,ijband)) 599 end do 600 601 602 !Minimal validity limit 603 deltae_min_tmp=dabs(diff_eig) 604 if ((deltae_min_tmp>=tol5).and.(deltae_min_tmp<=deltae_min)) deltae_min=deltae_min_tmp 605 606 !Conductivity for each omega - Apply KG formula 607 kin_fact=(eig0_k(iband)+eig0_k(jband))*half-(fermie+entropy) 608 do iom=1,mom 609 oml=oml1(iom) 610 dirac=(dexp(-((diff_eig+oml)/dom)**2)-dexp(-((diff_eig-oml)/dom)**2))/oml ! Take into account (n,m) and (m,n) 611 sig=dhdk2_g*diff_occ*dirac 612 kin11_k(iom)=kin11_k(iom)+sig 613 kin12_k(iom)=kin12_k(iom)-sig*kin_fact 614 kin21_k(iom)=kin21_k(iom)-sig*kin_fact 615 kin22_k(iom)=kin22_k(iom)+sig*kin_fact**2 616 do l2=1,3 617 do l1=1,3 618 cond_nd_k(l1,l2,iom)=cond_nd_k(l1,l2,iom)+dhdk2_r(l1,l2)*diff_occ*dirac 619 end do 620 end do 621 end do 622 623 !Evaluate sumrule 624 fact_diag=merge(one,two,iband==jband) 625 if (dabs(diff_eig)>=tol10) then 626 np_sum_k1=np_sum_k1 - fact_diag*dhdk2_g*diff_occ/diff_eig 627 else 628 np_sum_k2=np_sum_k2 - fact_diag*doccde_k(iband)*dhdk2_g 629 end if 630 631 end if ! diff_occ>tol8 632 end do !jband 633 634 socc_k=socc_k+occ_k(iband) 635 636 end if ! my band? 637 end do ! iband 638 639 ! Accumulate k-point contribution 640 do iom=1,mom 641 kin11(iom,isppol)=kin11(iom,isppol)+wtk(ikpt)*kin11_k(iom) 642 kin12(iom)=kin12(iom)+wtk(ikpt)*kin12_k(iom) 643 kin21(iom)=kin21(iom)+wtk(ikpt)*kin21_k(iom) 644 kin22(iom)=kin22(iom)+wtk(ikpt)*kin22_k(iom) 645 cond_nd(:,:,iom)=cond_nd(:,:,iom)+wtk(ikpt)*cond_nd_k(:,:,iom) 646 end do 647 np_sum=np_sum+wtk(ikpt)*(np_sum_k1+np_sum_k2) 648 socc=socc+wtk(ikpt)*socc_k 649 650 ! Validity limit 651 deltae=deltae+(eig0_k(nband_k)-fermie) 652 653 ABI_FREE(eig0_k) 654 ABI_FREE(occ_k) 655 ABI_FREE(doccde_k) 656 657 ! End loop over kpt/spin 658 end if ! My kpt? 659 bdtot_index=bdtot_index+nband_k 660 end do ! ikpt 661 end do ! isppol 662 663 !Accumulate kpt/band contributions over processors 664 call xmpi_sum(kin11,comm,mpierr) 665 call xmpi_sum(kin12,comm,mpierr) 666 call xmpi_sum(kin21,comm,mpierr) 667 call xmpi_sum(kin22,comm,mpierr) 668 call xmpi_sum(np_sum,comm,mpierr) 669 call xmpi_sum(socc,comm,mpierr) 670 call xmpi_sum(deltae,comm,mpierr) 671 call xmpi_min(deltae_min,comm,mpierr) 672 deltae=deltae/mpi_enreg%nproc_band 673 674 ABI_FREE(psinablapsi) 675 676 !--------------------------------------------------------------------------------- 677 ! Output results 678 679 !Print file headers (only master node) 680 if (me==master) then 681 682 ! Standard output 683 write(std_out,'(a,3f10.5)')' sumrule =',np_sum/socc/three/dble(nsppol),socc 684 write(std_out,'(a,f10.5,a,f10.5,a)')& 685 & ' Emax-Efermi =',deltae/dble(nkpt*nsppol),' Ha', & 686 & deltae/dble(nkpt*nsppol)*Ha_eV,' eV' 687 write(std_out,'(a,f10.5,a,f10.5,a)')& 688 & ' DeltaE min =',deltae_min,' Ha',deltae_min*Ha_eV,' eV' 689 690 ! _Lij file 691 if (open_file(trim(filnam_out)//'_Lij',msg, newunit=lij_unt, form='formatted', action="write") /= 0) then 692 ABI_ERROR(msg) 693 end if 694 write(lij_unt,'(a)')' # omega(ua) L12 L22 L22' 695 696 ! _sig file 697 if (open_file(trim(filnam_out)//'_sig', msg, newunit=sig_unt, form='formatted', action="write") /= 0) then 698 ABI_ERROR(msg) 699 end if 700 if (nsppol==1) then 701 write(sig_unt,'(a)')' # omega(ua) hbar*omega(eV) cond(ua) cond(ohm.cm)-1' 702 else 703 write(sig_unt,'(2a)')' # omega(ua) hbar*omega(eV) cond(ua) cond(ohm.cm)-1',& 704 & ' cond(ohm.cm)-1 UP cond(ohm.cm)-1 DN' 705 end if 706 707 ! _Kth file 708 if (open_file(trim(filnam_out)//'_Kth', msg, newunit=kth_unt, form='formatted', action="write") /=0) then 709 ABI_ERROR(msg) 710 end if 711 write(kth_unt,'(a)')& 712 & " #Thermal conductivity following B. Holst et al Phys. Rev. B 83 (2011) 235120" 713 write(kth_unt,'(a)')& 714 & ' #omega(ua) hbar*omega(eV) thermal cond(ua) Kth(W/m/K) thermopower(ua) Stp(microohm/K)' 715 716 ! Output file 717 if (open_file(trim(filnam_out)//'.out', msg, newunit=ocond_unt, form='formatted', action="write") /= 0) then 718 ABI_ERROR(msg) 719 end if 720 write(ocond_unt,'(a)' )'#Conducti output file:' 721 write(ocond_unt,'(a)' )'#Contains all results produced by conducti utility' 722 write(ocond_unt,'(a)' )'# ' 723 write(ocond_unt,'(a,i8,3f10.5,a)')'# npts,omin,omax,width =' ,mom,omin,omax,dom,' Ha' 724 write(ocond_unt,'(a,3f10.5,a)' )'# rprimd(bohr) =',rprimd(1:3,1) 725 write(ocond_unt,'(a,3f10.5,a)' )'# ',rprimd(1:3,2) 726 write(ocond_unt,'(a,3f10.5,a)' )'# ',rprimd(1:3,3) 727 write(ocond_unt,'(a,i8)' ) '# natom =',natom 728 write(ocond_unt,'(a,3i8)' ) '# nkpt,mband,nsppol =',nkpt,mband,nsppol 729 write(ocond_unt,'(a, f10.5,a)' )'# ecut =',ecut,' Ha' 730 write(ocond_unt,'(a,f10.5,a,f10.5,a)' )'# fermie =',fermie,' Ha ',fermie*Ha_eV,' eV' 731 732 write(ocond_unt,'(a,f12.5,a,f12.5,a)') '# Temp =',tsmear,' Ha ',Tatm,' Kelvin' 733 write(ocond_unt,'(a,f15.5,2x,f15.5)' )'# sumrule =',np_sum/socc/three/dble(nsppol),socc 734 write(ocond_unt,'(a,f10.5,a,f10.5,a)' )& 735 & '# Emax-Efermi =',deltae/dble(nkpt*nsppol),' Ha',deltae/dble(nkpt*nsppol)*Ha_eV,' eV' 736 write(ocond_unt,'(a)' )'# ' 737 write(ocond_unt,'(a)')'# omega(ua) cond(ua) thermal cond(ua) thermopower(ua)' 738 739 end if ! me==master? 740 741 !Compute (and print) thermal conductivity and thermopower 742 do iom=1,mom 743 oml=oml1(iom) 744 745 do isppol=1,nsppol 746 kin11(iom,isppol)=kin11(iom,isppol)*two_pi*third/(dom*ucvol)*half/dsqrt(pi) 747 if (dabs(kin11(iom,isppol))<tol19) kin11(iom,isppol)=zero 748 sig_abs(iom)=sig_abs(iom)+kin11(iom,isppol) 749 end do 750 751 kin21(iom)=kin21(iom)*two_pi*third/(dom*ucvol)*half/dsqrt(pi) 752 kin12(iom)=kin12(iom)*two_pi*third/(dom*ucvol)*half/dsqrt(pi) 753 kin22(iom)=kin22(iom)*two_pi*third/(dom*ucvol)*half/dsqrt(pi) 754 755 Kth(iom)=kin22(iom) 756 Stp(iom)=zero 757 if (sig_abs(iom)/=zero) then 758 Kth(iom)=Kth(iom)-(kin12(iom)*kin21(iom)/sig_abs(iom)) 759 Stp(iom)=kin12(iom)/(sig_abs(iom)*tsmear) 760 end if 761 762 if (dabs(Kth(iom))<tol19) Kth(iom)=zero 763 if (dabs(Stp(iom))<tol19) Stp(iom)=zero 764 if (abs(kin12(iom))<1.d-80) kin12=zero 765 if (abs(kin21(iom))<1.d-80) kin21=zero 766 if (abs(kin22(iom))<1.d-80) kin22=zero 767 768 if (me==master) then 769 write(lij_unt,'(f12.5,4es22.12)')oml,kin12(iom),kin22(iom),kin22(iom)/Tatm*3.4057d9 770 if (nsppol==1) then 771 write(sig_unt,'(2f12.5,2es22.12)') oml,oml*Ha_eV,sig_abs(iom),sig_abs(iom)*Ohmcm 772 else 773 write(sig_unt,'(2f12.5,4es22.12)') oml,oml*Ha_eV,sig_abs(iom),sig_abs(iom)*Ohmcm, & 774 & kin11(iom,1)*Ohmcm,kin11(iom,2)*Ohmcm 775 end if 776 write(kth_unt,'(2f12.5,4es22.12)') oml,oml*Ha_eV,Kth(iom),Kth(iom)*3.4057d9/Tatm, & 777 & Stp(iom),Stp(iom)*3.6753d-2 778 write(ocond_unt,'(1f12.5,3es22.12)') oml,sig_abs(iom),Kth(iom),Stp(iom) 779 end if 780 781 end do 782 783 !Compute the imaginary part of the conductivity (principal value) 784 ! +derived optical properties. 785 if (me==master) then 786 call msig(sig_abs,mom,oml1,filnam_out) 787 end if 788 789 !--------------------------------------------------------------------------------- 790 ! End 791 792 !Close all files 793 if (me==master) then 794 write(std_out,'(2a)')ch10,'OUTPUT' 795 write(std_out,'(a)')trim(filnam_out)//'_Lij : Onsager kinetic coefficients' 796 write(std_out,'(a)')trim(filnam_out)//'_sig : Optical conductivity' 797 write(std_out,'(a)')trim(filnam_out)//'_Kth : Thermal conductivity and thermopower' 798 write(std_out,'(a)')trim(filnam_out)//'_eps : Dielectric function' 799 write(std_out,'(a)')trim(filnam_out)//'_abs : n, k, reflectivity, absorption' 800 close(lij_unt) 801 close(sig_unt) 802 close(kth_unt) 803 close(ocond_unt) 804 end if 805 if (iomode == IO_MODE_ETSF) then 806 if (iomode_estf_mpiio.or.me==master) then 807 #ifdef HAVE_NETCDF 808 NCF_CHECK(nf90_close(ncid)) 809 #endif 810 end if 811 else if (me==master) then 812 ierr=close_unit(opt_unt,msg) 813 ABI_CHECK(ierr==0,sjoin("Error while closing ",filnam1)) 814 end if 815 816 !Release memory space 817 ABI_FREE(kin11) 818 ABI_FREE(kin22) 819 ABI_FREE(kin12) 820 ABI_FREE(kin21) 821 ABI_FREE(kin11_k) 822 ABI_FREE(kin22_k) 823 ABI_FREE(kin12_k) 824 ABI_FREE(kin21_k) 825 ABI_FREE(Stp) 826 ABI_FREE(Kth) 827 ABI_FREE(cond_nd) 828 ABI_FREE(cond_nd_k) 829 ABI_FREE(sig_abs) 830 ABI_FREE(eigen0) 831 ABI_FREE(nband) 832 ABI_FREE(oml1) 833 ABI_FREE(occ) 834 ABI_FREE(doccde) 835 ABI_FREE(wtk) 836 call hdr%free() 837 call destroy_mpi_enreg(mpi_enreg) 838 839 end subroutine conducti_paw
m_conducti/conducti_paw_core [ Functions ]
[ Top ] [ m_conducti ] [ Functions ]
NAME
conducti_paw_core
FUNCTION
This program computes the elements of the optical frequency dependent conductivity tensor and the conductivity along the three principal axes from the Kubo-Greenwood formula for PAW formalism
INPUTS
filnam=generic name for input data filnam_out=generic name for output data [with_absorption]=optiona lflag to activate the computation of absorption (_sigX file) (default=TRUE) [with_emissivity]=optiona lflag to activate the computation of emissivity (_emisX file) (default=FALSE)
OUTPUT
Only printing
NOTES
bantot dom=frequency range eigen0(mband*nkpt_rbz*nsppol)=GS eigenvalues at k (hartree). ecut=kinetic energy planewave cutoff (hartree). fermie= fermi energy (Hartree) mom=number of frequency for conductivity computation mband=maximum number of bands. natom = number of atoms in the unit cell. nband(nkpt*nsppol)=number of bands at each RF k point for each spin. nkpt=number of k points in the IBZ for this perturbation ngfft(3)=integer fft box dimensions. nspinor=number of spinorial components of the wavefunctions. nsppol=1 for unpolarized, 2 for spin-polarized. ntypat = number of atom types. occ(mband*nkpt*nsppol)=occupation number for each band and k. occopt==option for occupancies psinablapsi2(2,3,mband,nphicor,natom)Matrix elements = <Phi_core|Nabla|Phi_i> rmet(3,3)=real space metric ($\textrm{bohr}^{2}$).sigx(mom,nphicor)) rprimd(3,3)=real space primitive translations. of primitive translations. ucvol=unit cell volume in ($\textrm{bohr}^{3}$). wind=frequency window for computations of sigma wtk(nkpt)=weight assigned to each k point.
SOURCE
889 subroutine conducti_paw_core(filnam,filnam_out,with_absorption,with_emissivity) 890 891 !Arguments ----------------------------------- 892 !scalars 893 character(len=fnlen) :: filnam,filnam_out 894 logical,intent(in),optional :: with_absorption,with_emissivity 895 896 !Local variables------------------------------- 897 !scalars 898 integer,parameter :: master=0 899 integer :: iomode,atnbr,bantot,bdtot_index,comm,my_iband 900 integer :: fform2,headform,iatom,iband,icor,ierr,ikpt 901 integer :: iom,isppol,l1,mband,me,mom,mpierr,j2,etiq,pnp_size 902 integer :: natom,nband_k,nkpt,nphicor,nproc,nspinor,nsppol,ntypat 903 integer :: occopt,iunt,opt2_unt,ncid,varid,master_band,nb_per_proc 904 integer :: sigx1_unt,sigx1_s_unt,sigx1_tot_unt,ems_unt,ems_s_unt,ems_tot_unt 905 logical :: iomode_estf_mpiio,myband,mykpt,need_absorption,need_emissivity 906 real(dp) :: del_sig,del_emis,deltae,diff_occ,ecut,fermie 907 real(dp) :: omin,omax,omin_sig,omax_sig,omin_emis,omax_emis 908 real(dp) :: oml,dom,dom_ctr,dom_max,dom_tan1,dom_tan2 909 real(dp) :: Tatm,tsmear,ucvol 910 character(len=fnlen) :: filnam2,filnam_gen 911 character(len=500) :: msg 912 type(hdr_type) :: hdr 913 type(MPI_type) :: mpi_enreg 914 !arrays 915 integer :: nc_count(7),nc_start(7),nc_stride(7) 916 integer,allocatable :: nband(:),ncor(:),lcor(:),kappacor(:) 917 real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3) 918 real(dp),allocatable :: dom_var1(:,:),dhdk2_g(:) 919 real(dp),allocatable :: eig0_k(:),eigen0(:),eig0nc(:,:,:) 920 real(dp),allocatable :: energy_cor(:),edge(:) 921 real(dp),allocatable :: occ(:),occ_k(:),wtk(:) 922 real(dp),allocatable :: oml_edge(:,:),oml_emis(:) 923 real(dp),allocatable :: psinablapsi2(:,:,:,:,:) 924 real(dp),allocatable :: sigx1(:,:,:,:),sigx1_av(:,:,:),sigx1_k(:,:,:) 925 real(dp),allocatable :: sum_spin_sigx1(:,:,:),sum_spin_sigx1_av(:,:) 926 real(dp),allocatable :: emisx(:,:,:,:),emisx_av(:,:,:),emisx_k(:,:,:) 927 real(dp),allocatable :: sum_spin_emisx(:,:,:),sum_spin_emisx_av(:,:) 928 929 ! ********************************************************************************* 930 931 !optional flags 932 need_absorption=.true. ;if (present(with_absorption)) need_absorption=with_absorption 933 need_emissivity=.false.;if (present(with_emissivity)) need_emissivity=with_emissivity 934 if ((.not.need_absorption).and.(.not.need_emissivity)) return 935 936 ! --------------------------------------------------------------------------------- 937 ! Read input data 938 939 !Global MPI communicators 940 comm = xmpi_world 941 nproc = xmpi_comm_size(comm) 942 me = xmpi_comm_rank(comm) 943 944 !Read input parameters file 945 if (me==master) then 946 if (open_file(filnam,msg,newunit=iunt,form='formatted',action="read",status="old")/=0) then 947 ABI_ERROR(msg) 948 end if 949 rewind(iunt) 950 read(iunt,*) 951 read(iunt,'(a)')filnam_gen ! Generic name for the files 952 filnam2=trim(filnam_gen)//'_OPT2' 953 ! Read frequency range 954 if (need_absorption) then 955 read(iunt,err=11,end=11,fmt=*) dom,omin,omax,mom,atnbr,dom_max,dom_ctr 956 goto 12 957 11 backspace(iunt) ; read(iunt,*) dom,omin,omax,mom,atnbr ; dom_max=zero ; dom_ctr=zero 958 12 continue 959 else if (need_emissivity) then 960 read(iunt,*) dom,omin,omax,mom,atnbr 961 dom_max=zero;dom_ctr=zero 962 end if 963 close(iunt) 964 if (abs(dom_max)>tol10.and.dom_max<dom) then 965 msg = 'dom_max must be higher than dom!' 966 ABI_ERROR(msg) 967 end if 968 end if 969 970 !Send data to all procs 971 call xmpi_bcast(dom,master,comm,mpierr) 972 call xmpi_bcast(omin,master,comm,mpierr) 973 call xmpi_bcast(omax,master,comm,mpierr) 974 call xmpi_bcast(mom,master,comm,mpierr) 975 call xmpi_bcast(atnbr,master,comm,mpierr) 976 call xmpi_bcast(dom_max,master,comm,mpierr) 977 call xmpi_bcast(dom_ctr,master,comm,mpierr) 978 979 ! --------------------------------------------------------------------------------- 980 ! Read OPT2 file 981 982 !Check for FORTRAN/.nc OPT2 file and set iomode to IO_MODE_FORTRAN_MASTER/IO_MODE_ETSF 983 if (me==master) then 984 call nctk_fort_or_ncfile(filnam2,iomode,msg) 985 if (iomode/=IO_MODE_ETSF) iomode=IO_MODE_FORTRAN_MASTER 986 end if 987 call xmpi_bcast(filnam2,master,comm,mpierr) 988 call xmpi_bcast(iomode,master,comm,mpierr) 989 990 !Open OPT2 file and read HEADER 991 if (me==master) then 992 if (iomode==IO_MODE_ETSF) then 993 NCF_CHECK(nctk_open_read(ncid,filnam2,xmpi_comm_self)) 994 call hdr_ncread(hdr,ncid,fform2) 995 else 996 if (open_file(filnam2,msg,newunit=opt2_unt,form="unformatted",status="old")/=0) then 997 ABI_ERROR(msg) 998 end if 999 call hdr_fort_read(hdr,opt2_unt,fform2,rewind=.true.) 1000 end if 1001 ABI_CHECK(fform2/=0,sjoin("Error while reading ",filnam2)) 1002 ABI_CHECK(fform2==611.or.fform2==612.or.fform2==613,"OPT2 file format should be fform=611/612/613!") 1003 end if 1004 call hdr%bcast(master,me,comm) 1005 call xmpi_bcast(fform2,master,comm,mpierr) 1006 1007 !Extract info from the header 1008 headform=hdr%headform 1009 bantot=hdr%bantot 1010 ecut=hdr%ecut_eff 1011 natom=hdr%natom 1012 nkpt=hdr%nkpt 1013 nspinor=hdr%nspinor 1014 nsppol=hdr%nsppol 1015 ntypat=hdr%ntypat 1016 occopt=hdr%occopt 1017 rprimd(:,:)=hdr%rprimd(:,:) 1018 fermie=hdr%fermie 1019 tsmear=hdr%tsmear 1020 ABI_MALLOC(nband,(nkpt*nsppol)) 1021 ABI_MALLOC(occ,(bantot)) 1022 ABI_MALLOC(wtk,(nkpt)) 1023 occ(1:bantot)=hdr%occ(1:bantot) 1024 wtk(1:nkpt)=hdr%wtk(1:nkpt) 1025 nband(1:nkpt*nsppol)=hdr%nband(1:nkpt*nsppol) 1026 mband=maxval(nband(:)) ! Get mband, as the maximum value of nband(nkpt) 1027 call metric(gmet,gprimd,-1,rmet,rprimd,ucvol) ! Get metrics of simulation cell 1028 1029 !Read eigenvalues 1030 ABI_MALLOC(eigen0,(mband*nkpt*nsppol)) 1031 if (me==master) then 1032 if (iomode==IO_MODE_ETSF) then 1033 varid=nctk_idname(ncid,"eigenvalues") 1034 ABI_MALLOC(eig0nc,(mband,nkpt,nsppol)) 1035 #ifdef HAVE_NETCDF 1036 NCF_CHECK(nf90_get_var(ncid,varid,eig0nc)) 1037 #endif 1038 eigen0 = reshape(eig0nc,[mband*nkpt*nsppol]) 1039 ABI_FREE(eig0nc) 1040 else 1041 read(opt2_unt)(eigen0(iband),iband=1,mband*nkpt*nsppol) 1042 end if 1043 end if 1044 call xmpi_bcast(eigen0,master,comm,mpierr) 1045 1046 !Read core states 1047 if (me==master) then 1048 if (iomode==IO_MODE_ETSF) then 1049 #ifdef HAVE_NETCDF 1050 NCF_CHECK(nctk_get_dim(ncid,"number_of_core_states",nphicor)) 1051 #endif 1052 else 1053 read(opt2_unt) nphicor 1054 end if 1055 end if 1056 call xmpi_bcast(nphicor,master,comm,mpierr) 1057 1058 ABI_MALLOC(ncor,(nphicor)) 1059 ABI_MALLOC(lcor,(nphicor)) 1060 ABI_MALLOC(kappacor,(nphicor)) 1061 ABI_MALLOC(energy_cor,(nphicor)) 1062 ABI_MALLOC(edge,(nphicor)) 1063 1064 if (me==master) then 1065 if (iomode==IO_MODE_ETSF) then 1066 #ifdef HAVE_NETCDF 1067 varid=nctk_idname(ncid,"n_quantum_number_core") 1068 NCF_CHECK(nf90_get_var(ncid,varid,ncor)) 1069 varid=nctk_idname(ncid,"l_quantum_number_core") 1070 NCF_CHECK(nf90_get_var(ncid,varid,lcor)) 1071 varid=nctk_idname(ncid,"kappa_core") 1072 NCF_CHECK(nf90_get_var(ncid,varid,kappacor)) 1073 varid=nctk_idname(ncid,"eigenvalues_core") 1074 NCF_CHECK(nf90_get_var(ncid,varid,energy_cor)) 1075 !Close here netcdf file here because the rest has to be read with collective I/O 1076 NCF_CHECK(nf90_close(ncid)) 1077 #endif 1078 else 1079 do icor=1,nphicor 1080 read(unit=opt2_unt,err=23,end=23) ncor(icor),lcor(icor),kappacor(icor),energy_cor(icor) 1081 goto 24 1082 23 backspace(opt2_unt) ; read(unit=opt2_unt) ncor(icor),lcor(icor),energy_cor(icor) 1083 kappacor(icor)=0 1084 24 continue 1085 end do 1086 end if 1087 end if ! master 1088 call xmpi_bcast(nphicor,master,comm,mpierr) 1089 call xmpi_bcast(ncor,master,comm,mpierr) 1090 call xmpi_bcast(lcor,master,comm,mpierr) 1091 call xmpi_bcast(kappacor,master,comm,mpierr) 1092 call xmpi_bcast(energy_cor,master,comm,mpierr) 1093 edge(1:nphicor)=fermie-energy_cor(1:nphicor) 1094 1095 !--------------------------------------------------------------------------------- 1096 ! Prepare kpt/band parallelization 1097 1098 call init_mpi_enreg(mpi_enreg) 1099 mpi_enreg%comm_kpt=comm 1100 mpi_enreg%me_kpt=me 1101 mpi_enreg%nproc_spkpt=nproc 1102 mpi_enreg%paralbd=1 1103 ABI_MALLOC(mpi_enreg%proc_distrb,(nkpt,mband,nsppol)) 1104 ABI_MALLOC(mpi_enreg%my_kpttab,(nkpt)) 1105 call distrb2(mband,nb_per_proc,nband,nkpt,nproc,nsppol,mpi_enreg) 1106 call initmpi_band(nkpt,mpi_enreg,nband,nkpt,nsppol) 1107 1108 !--------------------------------------------------------------------------------- 1109 !Print some data 1110 1111 Tatm=tsmear*Ha_K 1112 if (me==master) then 1113 write(std_out,*) 1114 write(std_out,'(a)')'--------------------------------------------' 1115 write(std_out,'(a,i4)') 'selected atom for X ray emission',atnbr 1116 write(std_out,'(a)')'--------------------------------------------' 1117 if (need_absorption) then 1118 if (abs(dom_max)>tol10) then 1119 write(std_out,'(a)')'************************ ARCTAN SMEARING' 1120 write(std_out,'(a,i8,3f10.5,a)')' npts,omin,omax,width =',mom,omin,omax,dom,' Ha' 1121 write(std_out,'(a,2f10.5,a)')' dom_max,center =',dom_max,dom_ctr,' Ha' 1122 else 1123 write(std_out,'(a)')'************************ FIXED SMEARING' 1124 write(std_out,'(a,i8,3f10.5,a)')' npts,omin,omax,width =',mom,omin,omax,dom,' Ha' 1125 endif 1126 end if 1127 write(std_out,*) 1128 write(std_out,'(a,3f10.5,a)' )' rprimd(bohr) =',rprimd(1,1:3) 1129 write(std_out,'(a,3f10.5,a)' )' ',rprimd(2,1:3) 1130 write(std_out,'(a,3f10.5,a)' )' ',rprimd(3,1:3) 1131 write(std_out,'(a,i8)') ' natom =',natom 1132 write(std_out,'(a,3i8)') ' nkpt,mband,nsppol =',nkpt,mband,nsppol 1133 write(std_out, '(a, f10.5,a)' ) ' ecut =',ecut,' Ha' 1134 write(std_out,'(a,f10.5,a,f10.5,a)' )' fermie =',fermie,' Ha',fermie*Ha_eV,' eV' 1135 write(std_out,'(a,f12.5,a,f12.5,a)') ' Temp =',tsmear,' Ha ',Tatm,' Kelvin' 1136 write(std_out,*) 1137 write(std_out,*) 1138 write(std_out,'(a)')'--------------------------------------------' 1139 write(std_out,'(a,i4)') ' Number of core orbitals nc=',nphicor 1140 do icor=1,nphicor 1141 if (kappacor(icor)==0) then 1142 write(std_out,'(a,2i4,2f10.5)') ' n, l, Energy(Ha), Edge(Ha): ', & 1143 ncor(icor),lcor(icor),energy_cor(icor),edge(icor) 1144 else 1145 if (kappacor(icor)>0) then 1146 j2=2*lcor(icor)-1 1147 write(std_out,'(a,i4,i4,a,i4,2f10.5)') ' n, j, l, Energy(Ha), Edge(Ha): ',& 1148 & ncor(icor),j2,' / 2',lcor(icor),energy_cor(icor),edge(icor) 1149 else 1150 if (kappacor(icor)<-1) then 1151 j2=2*lcor(icor)+1 1152 write(std_out,'(a,i4,i4,a,i4,2f10.5)') ' n, j, l, Energy(Ha), Edge(Ha): ',& 1153 & ncor(icor),j2,'/2',lcor(icor),energy_cor(icor),edge(icor) 1154 else 1155 write(std_out,'(a,i4,a,i4,2f10.5)') ' n, j, l, Energy(Ha), Edge(Ha): ',& 1156 & ncor(icor),' 1/2',lcor(icor),energy_cor(icor),edge(icor) 1157 end if 1158 end if 1159 end if 1160 end do 1161 write(std_out,'(a)')'--------------------------------------------' 1162 end if ! master 1163 1164 !--------------------------------------------------------------------------------- 1165 ! Determine the frequency range and allocate frequency-dependent arrays 1166 1167 if (need_absorption) then 1168 ABI_MALLOC(oml_edge,(nphicor,mom)) 1169 ABI_MALLOC(dom_var1,(nphicor,mom)) 1170 omax_sig=omax ; omin_sig=omin 1171 del_sig=(omax_sig-omin_sig)/(mom-1) 1172 do iom=1,mom 1173 do icor=1,nphicor 1174 oml_edge(icor,iom)=-energy_cor(icor)+ dble(iom-1)*del_sig + omin_sig - one 1175 if ((oml_edge(icor,iom)<=edge(icor)).or.(abs(dom_max)<=tol10)) then 1176 dom_var1(icor,iom)= dom 1177 else 1178 dom_tan1= (oml_edge(icor,iom)-edge(icor))/dom_ctr 1179 dom_tan2=dom_tan1-one/dom_tan1**2 1180 dom_var1(icor,iom)=dom+dom_max*(half+piinv*datan(dom_tan2)) 1181 endif 1182 enddo 1183 enddo 1184 ABI_MALLOC(sigx1,(nphicor,mom,natom,nsppol)) 1185 sigx1=zero 1186 end if 1187 1188 if (need_emissivity) then 1189 ABI_MALLOC(oml_emis,(mom)) 1190 omin_emis=minval(eigen0) 1191 omax_emis=maxval(eigen0) 1192 del_emis=(omax_emis-omin_emis)/(mom-1) 1193 do iom=1,mom 1194 oml_emis(iom)=omin_emis+dble(iom-1)*del_emis 1195 end do 1196 ABI_MALLOC(emisx,(nphicor,mom,natom,nsppol)) 1197 emisx=zero 1198 end if 1199 1200 !--------------------------------------------------------------------------------- 1201 ! Prepare core-valence dipoles reading 1202 1203 iomode_estf_mpiio=(iomode==IO_MODE_ETSF.and.nctk_has_mpiio.and.use_netcdf_mpiio) 1204 1205 !In case of netCDF access to OPT file, prepare collective I/O 1206 if (iomode == IO_MODE_ETSF) then 1207 if (iomode_estf_mpiio) then 1208 NCF_CHECK(nctk_open_read(ncid,filnam2,comm)) 1209 varid=nctk_idname(ncid,"dipole_core_valence") 1210 if (nproc>1) then 1211 NCF_CHECK(nctk_set_collective(ncid,varid)) 1212 end if 1213 else if (me==master) then 1214 NCF_CHECK(nctk_open_read(ncid,filnam2,xmpi_comm_self)) 1215 varid=nctk_idname(ncid,"dipole_core_valence") 1216 !if (nctk_has_mpiio.and.(.not.use_netcdf_mpiio)) then 1217 ! NCF_CHECK(nctk_set_collective(ncid,varid)) 1218 !end if 1219 end if 1220 end if 1221 1222 if (iomode_estf_mpiio) then 1223 !If MPI-IO, store only elements for one band 1224 ABI_MALLOC(psinablapsi2,(2,3,nphicor,natom,1)) 1225 else 1226 !If not, store the elements for all bands 1227 ABI_MALLOC(psinablapsi2,(2,3,nphicor,natom,mband)) 1228 end if 1229 pnp_size=size(psinablapsi2) 1230 1231 !--------------------------------------------------------------------------------- 1232 ! Compute X absorption coefficient and/or X emissivity 1233 1234 if (need_absorption) then 1235 ABI_MALLOC(sigx1_k,(nphicor,mom,natom)) 1236 end if 1237 if (need_emissivity) then 1238 ABI_MALLOC(emisx_k,(nphicor,mom,natom)) 1239 end if 1240 ABI_MALLOC(dhdk2_g,(nphicor)) 1241 1242 deltae = zero 1243 1244 !LOOP OVER SPINS/K 1245 bdtot_index = 0 1246 do isppol=1,nsppol 1247 do ikpt=1,nkpt 1248 etiq=ikpt+(isppol-1)*nkpt 1249 nband_k=nband(ikpt+(isppol-1)*nkpt) 1250 mykpt=.not.(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me)) 1251 master_band=minval(mpi_enreg%proc_distrb(ikpt,1:nband_k,isppol)) 1252 1253 ! In case of non MPI-IO, has to read all (n,m) dipoles for this k-point 1254 ! Master node reads and send to relevant processor 1255 if (.not.iomode_estf_mpiio.and.me==master) then 1256 if (iomode==IO_MODE_ETSF) then 1257 nc_start=[1,1,1,1,1,ikpt,isppol];nc_stride=[1,1,1,1,1,1,1] 1258 nc_count=[2,3,nphicor,natom,mband,1,1] 1259 #ifdef HAVE_NETCDF 1260 NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi2,start=nc_start,stride=nc_stride,count=nc_count)) 1261 #endif 1262 else 1263 psinablapsi2=zero 1264 if (fform2==612) then ! New OPT2 file format 1265 read(opt2_unt) (((psinablapsi2(1:2,1,icor,iatom,iband),icor=1,nphicor),iatom=1,natom),iband=1,nband_k) 1266 read(opt2_unt) (((psinablapsi2(1:2,2,icor,iatom,iband),icor=1,nphicor),iatom=1,natom),iband=1,nband_k) 1267 read(opt2_unt) (((psinablapsi2(1:2,3,icor,iatom,iband),icor=1,nphicor),iatom=1,natom),iband=1,nband_k) 1268 else if (fform2==613) then ! Large OPT2 file format 1269 do iband=1,nband_k 1270 read(opt2_unt) ((psinablapsi2(1:2,1,icor,iatom,iband),icor=1,nphicor),iatom=1,natom) 1271 read(opt2_unt) ((psinablapsi2(1:2,2,icor,iatom,iband),icor=1,nphicor),iatom=1,natom) 1272 read(opt2_unt) ((psinablapsi2(1:2,3,icor,iatom,iband),icor=1,nphicor),iatom=1,natom) 1273 end do 1274 else 1275 !The old writing was not efficient (indexes order is bad) 1276 do iatom=1,natom 1277 read(opt2_unt) ((psinablapsi2(1:2,1,icor,iatom,iband),iband=1,nband_k),icor=1,nphicor) 1278 read(opt2_unt) ((psinablapsi2(1:2,2,icor,iatom,iband),iband=1,nband_k),icor=1,nphicor) 1279 read(opt2_unt) ((psinablapsi2(1:2,3,icor,iatom,iband),iband=1,nband_k),icor=1,nphicor) 1280 end do 1281 end if 1282 end if 1283 if (.not.mykpt) then 1284 call xmpi_exch(psinablapsi2,pnp_size,master,psinablapsi2,master_band,comm,etiq,ierr) 1285 end if 1286 end if 1287 1288 ! Select k-points for current proc 1289 if (mykpt) then 1290 1291 ABI_MALLOC(eig0_k,(nband_k)) 1292 ABI_MALLOC(occ_k,(nband_k)) 1293 1294 if (need_absorption) sigx1_k=zero 1295 if (need_emissivity) emisx_k=zero 1296 1297 ! k-dependent data 1298 eig0_k(:)=eigen0(1+bdtot_index:nband_k+bdtot_index) 1299 occ_k(:)=occ(1+bdtot_index:nband_k+bdtot_index) 1300 1301 ! In case of non MPI-IO, receive all (n,m) dipoles from master proc 1302 ! Then broadcast them to all band processors 1303 if (.not.iomode_estf_mpiio) then 1304 if (me/=master.and.me==master_band) then 1305 call xmpi_exch(psinablapsi2,pnp_size,master,psinablapsi2,me,comm,etiq,ierr) 1306 end if 1307 call xmpi_bcast(psinablapsi2,master,mpi_enreg%comm_band,mpierr) 1308 end if 1309 1310 ! LOOP OVER BANDS 1311 do iband=1,nband_k 1312 1313 !If MPI-IO, store only ib elements for each iband 1314 !If not, store all elements 1315 my_iband=merge(1,iband,iomode_estf_mpiio) 1316 dhdk2_g = zero 1317 1318 ! Select bands for current proc 1319 myband=(mpi_enreg%proc_distrb(ikpt,iband,isppol)==me) 1320 if (myband) then 1321 1322 diff_occ = (two/dble(nsppol*nspinor))-occ_k(iband) 1323 1324 ! In case of MPI-IO, read core-valence dipoles for band n 1325 if (iomode_estf_mpiio) then 1326 nc_start=[1,1,1,1,iband,ikpt,isppol];nc_stride=[1,1,1,1,1,1,1] 1327 nc_count=[2,3,nphicor,natom,1,1,1] 1328 #ifdef HAVE_NETCDF 1329 NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi2,start=nc_start,stride=nc_stride,count=nc_count)) 1330 #endif 1331 end if 1332 1333 ! LOOP OVER ATOMS 1334 do iatom=1,natom 1335 1336 dhdk2_g = zero 1337 do icor=1,nphicor 1338 do l1=1,3 1339 dhdk2_g(icor)=dhdk2_g(icor) & 1340 & +(psinablapsi2(1,l1,icor,iatom,my_iband)*psinablapsi2(1,l1,icor,iatom,my_iband) & 1341 & +psinablapsi2(2,l1,icor,iatom,my_iband)*psinablapsi2(2,l1,icor,iatom,my_iband)) 1342 end do 1343 end do 1344 1345 ! Absoption for each omega 1346 if (need_absorption) then 1347 do iom=1,mom 1348 do icor=1,nphicor 1349 !Lorentzian var arctan 1350 sigx1_k(icor,iom,iatom)=sigx1_k(icor,iom,iatom) & 1351 & +dhdk2_g(icor)*diff_occ*oml_edge(icor,iom) & 1352 & *(dom_var1(icor,iom)/((-energy_cor(icor)+eig0_k(iband) & 1353 & -oml_edge(icor,iom))**2+(dom_var1(icor,iom)/two)**2)) 1354 end do 1355 end do 1356 end if 1357 1358 ! Emissivity for each omega 1359 if (need_emissivity) then 1360 do iom=1,mom 1361 do icor=1,nphicor 1362 oml=-energy_cor(icor)-oml_emis(iom) 1363 emisx_k(icor,iom,iatom)=emisx_k(icor,iom,iatom) & 1364 & +dhdk2_g(icor)*occ_k(iband)/oml & 1365 & *dexp(-((-energy_cor(icor)+eig0_k(iband)-oml)/dom)**2) 1366 end do 1367 end do 1368 end if 1369 1370 end do ! iatom 1371 1372 end if ! my band? 1373 end do ! iband 1374 1375 ! Accumulate k-point contribution 1376 if (need_absorption) then 1377 sigx1(1:nphicor,1:mom,1:natom,isppol)=sigx1(1:nphicor,1:mom,1:natom,isppol) & 1378 & +wtk(ikpt)*sigx1_k(1:nphicor,1:mom,1:natom) 1379 end if 1380 if (need_emissivity) then 1381 emisx(1:nphicor,1:mom,1:natom,isppol)=emisx(1:nphicor,1:mom,1:natom,isppol) & 1382 & +wtk(ikpt)*emisx_k(1:nphicor,1:mom,1:natom) 1383 end if 1384 1385 ! Validity limit 1386 deltae=deltae+eig0_k(nband_k) 1387 1388 ABI_FREE(eig0_k) 1389 ABI_FREE(occ_k) 1390 1391 ! End loop over kpt/spin 1392 end if ! My kpt? 1393 bdtot_index=bdtot_index+nband_k 1394 end do ! ikpt 1395 end do ! isppol 1396 1397 !Accumulate kpt/band contributions over processors 1398 if (need_absorption) then 1399 call xmpi_sum(sigx1,comm,mpierr) 1400 end if 1401 if (need_emissivity) then 1402 call xmpi_sum(emisx,comm,mpierr) 1403 end if 1404 call xmpi_sum(deltae,comm,mpierr) 1405 deltae=deltae/mpi_enreg%nproc_band 1406 1407 !Release some memory 1408 ABI_FREE(dhdk2_g) 1409 ABI_FREE(psinablapsi2) 1410 if (need_absorption) then 1411 ABI_FREE(sigx1_k) 1412 end if 1413 if (need_emissivity) then 1414 ABI_FREE(emisx_k) 1415 end if 1416 1417 !Close core-valence dipoles file 1418 if (iomode == IO_MODE_ETSF) then 1419 if (iomode_estf_mpiio.or.me==master) then 1420 #ifdef HAVE_NETCDF 1421 NCF_CHECK(nf90_close(ncid)) 1422 #endif 1423 end if 1424 else if (me==master) then 1425 ierr=close_unit(opt2_unt,msg) 1426 ABI_CHECK(ierr==0,sjoin("Error while closing ",filnam2)) 1427 end if 1428 1429 !--------------------------------------------------------------------------------- 1430 ! Post-processing 1431 1432 !Absorption: post-processing 1433 if (need_absorption) then 1434 1435 ! Absorption: apply scaling factor 1436 do isppol=1,nsppol 1437 do iatom=1,natom 1438 do iom=1,mom 1439 do icor=1,nphicor 1440 sigx1(icor,iom,iatom,isppol)=sigx1(icor,iom,iatom,isppol)*two_pi*dble(natom)/ucvol/two/(dabs(energy_cor(icor))) 1441 end do 1442 end do 1443 end do 1444 end do 1445 1446 ! Absorption: average over atoms 1447 ABI_MALLOC(sigx1_av,(nphicor,mom,nsppol)) 1448 sigx1_av=zero 1449 do isppol=1,nsppol 1450 do iatom=1,natom 1451 do iom=1,mom 1452 do icor=1,nphicor 1453 sigx1_av(icor,iom,isppol)=sigx1_av(icor,iom,isppol)+sigx1(icor,iom,iatom,isppol) 1454 end do 1455 end do 1456 end do 1457 end do 1458 1459 ! Absorption: spin treatment 1460 if(nsppol==2) then 1461 ABI_MALLOC(sum_spin_sigx1,(nphicor,mom,natom)) 1462 ABI_MALLOC(sum_spin_sigx1_av,(nphicor,mom)) 1463 sum_spin_sigx1=zero ; sum_spin_sigx1_av=zero 1464 do isppol=1,nsppol 1465 do iatom=1,natom 1466 do iom=1,mom 1467 do icor=1,nphicor 1468 sum_spin_sigx1(icor,iom,iatom)=sum_spin_sigx1(icor,iom,iatom) & 1469 & +sigx1(icor,iom,iatom,isppol) 1470 end do 1471 end do 1472 end do 1473 end do 1474 do isppol=1,nsppol 1475 do icor=1,nphicor 1476 do iom=1,mom 1477 sum_spin_sigx1_av(icor,iom)=sum_spin_sigx1_av(icor,iom)+sigx1_av(icor,iom,isppol) 1478 end do 1479 end do 1480 end do 1481 endif 1482 end if 1483 1484 !Emissivity: post-processing 1485 if (need_emissivity) then 1486 1487 ! Emissivity: filter low values 1488 do isppol=1,nsppol 1489 do iatom=1,natom 1490 do iom=1,mom 1491 do icor=1,nphicor 1492 if (emisx(icor,iom,iatom,isppol)<=tol16) emisx(icor,iom,iatom,isppol)=zero 1493 end do 1494 end do 1495 end do 1496 end do 1497 1498 ! Emissivity: apply scaling factor 1499 emisx=emisx*two_pi*third*dble(natom)/(dom*ucvol)*half/dsqrt(pi) 1500 1501 ! Emissivity: average over atoms 1502 ABI_MALLOC(emisx_av,(nphicor,mom,nsppol)) 1503 emisx_av=zero 1504 do isppol=1,nsppol 1505 do iatom=1,natom 1506 do iom=1,mom 1507 do icor=1,nphicor 1508 emisx_av(icor,iom,isppol)=emisx_av(icor,iom,isppol)+emisx(icor,iom,iatom,isppol) 1509 end do 1510 end do 1511 end do 1512 end do 1513 emisx_av=emisx_av/dble(natom) 1514 1515 ! Emissivity: spin treatment 1516 if(nsppol==2) then 1517 ABI_MALLOC(sum_spin_emisx,(nphicor,mom,natom)) 1518 ABI_MALLOC(sum_spin_emisx_av,(nphicor,mom)) 1519 sum_spin_emisx=zero ; sum_spin_emisx_av=zero 1520 do isppol=1,nsppol 1521 do iatom=1,natom 1522 do iom=1,mom 1523 do icor=1,nphicor 1524 sum_spin_emisx(icor,iom,iatom)=sum_spin_emisx(icor,iom,iatom) & 1525 & +emisx(icor,iom,iatom,isppol) 1526 end do 1527 end do 1528 end do 1529 end do 1530 do isppol=1,nsppol 1531 do icor=1,nphicor 1532 do iom=1,mom 1533 sum_spin_emisx_av(icor,iom)=sum_spin_emisx_av(icor,iom)+emisx_av(icor,iom,isppol) 1534 end do 1535 end do 1536 end do 1537 endif 1538 end if 1539 1540 !--------------------------------------------------------------------------------- 1541 ! Output results 1542 1543 !Only master node outputs results in files (only master node) 1544 if (me==master) then 1545 1546 ! Standard output 1547 if (need_absorption) then 1548 write(std_out,*) 'Absorption: valence state orbital energies: omin,omax',omin_sig,omax_sig 1549 end if 1550 if (need_emissivity) then 1551 write(std_out,*) 'Emissivity: valence state orbital energies: omin,omax',omin_emis,omax_emis 1552 end if 1553 if (need_absorption) then 1554 write(std_out,'(a,f10.5,a,f10.5,a)')& 1555 & ' Emax =',deltae/dble(nkpt*nsppol),' Ha',deltae/dble(nkpt*nsppol)*Ha_eV,' eV' 1556 end if 1557 1558 ! _sigX file 1559 if (need_absorption) then 1560 if (open_file(trim(filnam_out)//'_sigX',msg,newunit=sigx1_unt,form='formatted',action="write")/=0) then 1561 ABI_ERROR(msg) 1562 end if 1563 if (abs(dom_max)>tol10) then 1564 write(sigx1_unt,'(a)')'#***************************************************** ARCTAN SMEARING ********' 1565 write(sigx1_unt,'(a,i8,3f10.5,a)')'# npts,omin,omax,width =',mom,omin,omax,dom,' Ha' 1566 write(sigx1_unt,'(a,2f10.5,a)')'# dom_max,center =',dom_max,dom_ctr,' Ha' 1567 else 1568 write(sigx1_unt,'(a)')'#***************************************************** FIXED SMEARING ********' 1569 write(sigx1_unt,'(a,i8,3f10.5,a)')'# npts,omin,omax,width =',mom,omin,omax,dom,' Ha' 1570 endif 1571 write(sigx1_unt,'(a,3f10.5,a)' )'# rprimd(bohr) =',rprimd(1:3,1) 1572 write(sigx1_unt,'(a,3f10.5,a)' )'# ',rprimd(1:3,2) 1573 write(sigx1_unt,'(a,3f10.5,a)' )'# ',rprimd(1:3,3) 1574 write(sigx1_unt,'(a,i8)' ) '# natom =',natom 1575 write(sigx1_unt,'(a,3i8)' ) '# nkpt,mband,nsppol =',nkpt,mband,nsppol 1576 write(sigx1_unt,'(a, f10.5,a)' )'# ecut =',ecut,' Ha' 1577 write(sigx1_unt,'(a,f10.5,a,f10.5,a)' )'# fermie =',fermie,' Ha ',fermie*Ha_eV,' eV' 1578 write(sigx1_unt,'(a,f12.5,a,f12.5,a)') '# Temp =',tsmear,' Ha ',Tatm,' Kelvin' 1579 write(sigx1_unt,'(a)')'#----------------------------------------------------------------------------' 1580 write(sigx1_unt,'(a,i4)') '# Number of core orbitals nc=',nphicor 1581 do icor=1,nphicor 1582 if (kappacor(icor)==0) then 1583 write(sigx1_unt,'(a,2i4,2f10.5)') '# n, l, Energy(Ha), Edge(Ha): ',ncor(icor),lcor(icor),energy_cor(icor),edge(icor) 1584 else 1585 if (kappacor(icor)>0) then 1586 j2=2*lcor(icor)-1 1587 write(sigx1_unt,'(a,i4,i4,a,i4,2f10.5)') '# n, j, l, Energy(Ha), Edge(Ha): ', & 1588 & ncor(icor),j2,' / 2',lcor(icor),energy_cor(icor),edge(icor) 1589 else 1590 if (kappacor(icor)<-1) then 1591 j2=2*lcor(icor)+1 1592 write(sigx1_unt,'(a,i4,i4,a,i4,2f10.5)') '# n, j, l, Energy(Ha), Edge(Ha): ', & 1593 & ncor(icor),j2,' / 2',lcor(icor),energy_cor(icor),edge(icor) 1594 else 1595 write(sigx1_unt,'(a,i4,a,i4,2f10.5)') '# n, j, l, Energy(Ha), Edge(Ha): ', & 1596 & ncor(icor),' 1 / 2',lcor(icor),energy_cor(icor),edge(icor) 1597 end if 1598 end if 1599 end if 1600 end do 1601 write(sigx1_unt,'(a)')'#----------------------------------------------------------------------------' 1602 write(sigx1_unt,'(a,f10.5,a,f10.5,a)')& 1603 & '# Emax =',deltae/dble(nkpt*nsppol),' Ha',deltae/dble(nkpt*nsppol)*Ha_eV,' eV' 1604 write(sigx1_unt,'(a)')'#----------------------------------------------------------------------------' 1605 do iom=1,mom 1606 write(sigx1_unt,'(100(1x,e15.8))') & 1607 & (oml_edge(icor,iom),sigx1_av(icor,iom,1)/dble(natom),sigx1(icor,iom,atnbr,1),icor=1,nphicor) 1608 end do 1609 close(sigx1_unt) 1610 end if 1611 1612 ! _s_sigX and tot_sigX files 1613 if (need_absorption.and.nsppol==2) then 1614 if (open_file(trim(filnam_out)//'_s_sigX',msg,newunit=sigx1_s_unt,form='formatted',action="write")/=0) then 1615 ABI_ERROR(msg) 1616 end if 1617 if (open_file(trim(filnam_out)//'_tot_sigX',msg,newunit=sigx1_tot_unt,form='formatted',action="write")/=0) then 1618 ABI_ERROR(msg) 1619 end if 1620 do iom=1,mom 1621 write(sigx1_s_unt,'(100(1x,e15.8))') & 1622 & (oml_edge(icor,iom),sigx1_av(icor,iom,nsppol)/dble(natom),sigx1(icor,iom,atnbr,nsppol),icor=1,nphicor) 1623 write(sigx1_tot_unt,'(100(1x,e15.8))') & 1624 & (oml_edge(icor,iom),sum_spin_sigx1_av(icor,iom)/dble(natom),sum_spin_sigx1(icor,iom,atnbr),icor=1,nphicor) 1625 end do 1626 close(sigx1_s_unt) 1627 close(sigx1_tot_unt) 1628 end if 1629 1630 ! _emisX file 1631 if (need_emissivity) then 1632 if (open_file(trim(filnam_out)//'_emisX',msg,newunit=ems_unt,form='formatted',action="write")/=0) then 1633 ABI_ERROR(msg) 1634 end if 1635 write(ems_unt,*) '# conducti: Xray emission spectrum, all in atomic units by default ' 1636 write(ems_unt,*) '# One block of 3 columns per core wavefunction' 1637 write(ems_unt,*) '# energy, sigx_av, sigx, etc... ' 1638 do iom=1,mom 1639 write(ems_unt,'(3(3(1x,e15.8),2x))') & 1640 & ((-energy_cor(icor)+oml_emis(iom)),emisx_av(icor,iom,1),emisx(icor,iom,atnbr,1),icor=1,nphicor) 1641 end do 1642 close(ems_unt) 1643 end if 1644 1645 ! _s_emisX and tot_emisX files 1646 if (need_emissivity.and.nsppol==2) then 1647 if (open_file(trim(filnam_out)//'_s_emisX',msg,newunit=ems_s_unt,form='formatted',action="write")/=0) then 1648 ABI_ERROR(msg) 1649 end if 1650 if (open_file(trim(filnam_out)//'_tot_emisX',msg,newunit=ems_tot_unt,form='formatted',action="write")/=0) then 1651 ABI_ERROR(msg) 1652 end if 1653 do iom=1,mom 1654 write(ems_s_unt,'(3(3(1x,e15.8),2x))') & 1655 & ((-energy_cor(icor)+oml_emis(iom)),emisx_av(icor,iom,nsppol)/dble(natom),emisx(icor,iom,atnbr,nsppol),icor=1,nphicor) 1656 write(ems_tot_unt,'(3(3(1x,e15.8),2x))') & 1657 & ((-energy_cor(icor)+oml_emis(iom)),sum_spin_emisx_av(icor,iom)/dble(natom),sum_spin_emisx(icor,iom,atnbr),icor=1,nphicor) 1658 end do 1659 close(ems_s_unt) 1660 close(ems_tot_unt) 1661 end if 1662 1663 endif ! master node 1664 1665 !--------------------------------------------------------------------------------- 1666 ! End 1667 1668 !Release memory space 1669 if (need_absorption) then 1670 ABI_FREE(sigx1) 1671 ABI_FREE(sigx1_av) 1672 if (nsppol==2) then 1673 ABI_FREE(sum_spin_sigx1) 1674 ABI_FREE(sum_spin_sigx1_av) 1675 end if 1676 ABI_FREE(dom_var1) 1677 ABI_FREE(oml_edge) 1678 end if 1679 if (need_emissivity) then 1680 ABI_FREE(emisx) 1681 ABI_FREE(emisx_av) 1682 if (nsppol==2) then 1683 ABI_FREE(sum_spin_emisx) 1684 ABI_FREE(sum_spin_emisx_av) 1685 end if 1686 ABI_FREE(oml_emis) 1687 end if 1688 ABI_FREE(ncor) 1689 ABI_FREE(lcor) 1690 ABI_FREE(kappacor) 1691 ABI_FREE(energy_cor) 1692 ABI_FREE(edge) 1693 ABI_FREE(eigen0) 1694 ABI_FREE(nband) 1695 ABI_FREE(occ) 1696 ABI_FREE(wtk) 1697 call hdr%free() 1698 call destroy_mpi_enreg(mpi_enreg) 1699 1700 end subroutine conducti_paw_core
m_conducti/msig [ Functions ]
[ Top ] [ m_conducti ] [ Functions ]
NAME
msig
FUNCTION
This program computes the elements of the optical frequency dependent conductivity tensor and the conductivity along the three principal axes from the Kubo-Greenwood formula for PAW formalism
INPUTS
fcti(npti)= conductivity, as calculated in conducti npti= number of points to calculate conductivity xi(npti)= energies where the conductivity is calculated
OUTPUT
no output, only files
NOTES
this program calculates the imaginary part of the conductivity (principal value) +derived optical properties. the calculation is performed on the same grid as the initial input to calculate the principal value, a trapezoidale integration +taylor expansion to third order is used (W.J. Thomson computer in physics vol 12 p94 1998) two input files are needed inppv.dat (parameters) and sigma.dat (energy,sigma_1) two output files ppsigma.dat (energy,sigma_1,sigma_2,epsilon_1,epsilon_2) abs.dat (energy,nomega,komega,romega,absomega) march 2002 s.mazevet
SOURCE
2373 subroutine msig(fcti,npti,xi,filnam_out_sig) 2374 2375 !Arguments ----------------------------------- 2376 !scalars 2377 integer,intent(in) :: npti 2378 !arrays 2379 real(dp),intent(in) :: fcti(npti),xi(npti) 2380 character(len=fnlen),intent(in) :: filnam_out_sig 2381 2382 !Local variables------------------------------- 2383 !scalars 2384 integer :: npt = 10000 2385 integer :: ii,ip,npt1,npt2,eps_unt,abs_unt 2386 real(dp),parameter :: del=0.001_dp,ohmtosec=9.d11 2387 real(dp) :: dx,dx1,dx2,eps1,eps2,idel,komega,pole,refl,sigma2,xsum 2388 character(len=500) :: msg 2389 !arrays 2390 real(dp),allocatable :: abso(:),fct(:),fct1(:),fct2(:),fct3(:),fct4(:),fct5(:) 2391 real(dp),allocatable :: fctii(:),fp(:),fpp(:),fppp(:),nomega(:),ppsig(:) 2392 real(dp),allocatable :: x1(:),x2(:) 2393 2394 ! ********************************************************************************* 2395 2396 if (npti > 12000) then 2397 msg = "Sorry - the interpolator INTRPL is hard coded for maximum 12000 points." // & 2398 & ch10 // " Reduce the conducti input npti, or implement a better interpolator!" 2399 ABI_ERROR(msg) 2400 end if 2401 2402 write(std_out,'(2a)')ch10,'Calculate the principal value and related optical properties' 2403 write(std_out,'(a)')'following W.J. Thomson computer in physics vol 12 p94 1998 for ' 2404 write(std_out,'(a)')'the principal value.' 2405 write(std_out,'(a)')'OPTIONS' 2406 write(std_out,'(a)')'use default number of integration pts: npt=10000' 2407 write(std_out,'(a)')'Use default value for delta interval: del=1e-3' 2408 2409 if (open_file(trim(filnam_out_sig)//'_eps',msg,newunit=eps_unt,status='replace',action="write")/=0) then 2410 ABI_ERROR(msg) 2411 end if 2412 write(eps_unt,'(a)')'#energy (eV),sigma_1(Ohm-1cm-1),sigma_2(Ohm-1cm-1),epsilon_1,epsilon_2' 2413 2414 if (open_file(trim(filnam_out_sig)//'_abs',msg,newunit=abs_unt,status='replace',action="write")/=0) then 2415 ABI_ERROR(msg) 2416 end if 2417 write(abs_unt,'(a)')'#energy(eV),nomega,komega,refl.,abso.(cm-1)' 2418 2419 ABI_MALLOC(fct,(npt)) 2420 ABI_MALLOC(fct2,(npt)) 2421 ABI_MALLOC(fct3,(npt)) 2422 ABI_MALLOC(fct4,(npt)) 2423 ABI_MALLOC(fct5,(npt)) 2424 ABI_MALLOC(fp,(npt)) 2425 ABI_MALLOC(fpp,(npt)) 2426 ABI_MALLOC(fppp,(npt)) 2427 ABI_MALLOC(x1,(npt)) 2428 ABI_MALLOC(x2,(npt)) 2429 ABI_MALLOC(fct1,(npt)) 2430 ABI_MALLOC(ppsig,(npt)) 2431 ABI_MALLOC(fctii,(npt)) 2432 ABI_MALLOC(abso,(npt)) 2433 ABI_MALLOC(nomega,(npt)) 2434 2435 !loop on the initial energy grid 2436 do ip=1,npti 2437 2438 ! adjust the interval before and after the pole to reflect range/npt interval 2439 xsum=zero 2440 dx=(xi(npti)-xi(1))/dble(npt-1) 2441 pole=xi(ip) 2442 npt1=int((pole-del)/dx) 2443 dx1=zero 2444 if(npt1/=1) dx1=(pole-del)/(npt1-1) 2445 npt2=int((xi(npti)-pole-del)/dx) 2446 dx2=(xi(npti)-pole-del)/(npt2-1) 2447 2448 ! for the moment skip the pp calculation when the pole if too close to the end of the range 2449 if (npt1<=1.or.npt2<=1) then 2450 2451 xsum=zero 2452 ppsig(ip)=zero 2453 2454 else 2455 2456 ! define the fct for which the pp calculation is needed using xi^2-pole^2 factorization 2457 fctii(1:npti) = zero 2458 fctii(1:npti)=fcti(1:npti)*pole/(xi(1:npti)+pole) 2459 2460 ! define the grid on each side of the pole x1 before x2 after 2461 do ii=1,npt1 2462 x1(ii)=dx1*dble(ii-1) 2463 end do 2464 do ii=1,npt2 2465 x2(ii)=pole+del+dx2*dble(ii-1) 2466 end do 2467 2468 ! interpolate the initial fct fii on the new grids x1 and x2 (cubic spline) 2469 ! write(std_out,*) npti,npt1 2470 2471 ! MJV 6/12/2008: 2472 ! For each use of fctii should ensure that npt1 npt2 etc... are less than 2473 ! npt=len(fctii) 2474 ! TODO: move to spline/splint routines with no memory limitation 2475 call intrpl(npti,xi,fctii,npt1,x1,fct4,fct1,fct5,1) 2476 call intrpl(npti,xi,fctii,npt2,x2,fct3,fct2,fct5,1) 2477 2478 ! calculate the two integrals from 0-->pole-lamda and pole+lamda--> end range 2479 ! trapezoidal integration 2480 do ii=1,npt1 2481 fct1(ii)=fct4(ii)/(x1(ii)-pole) 2482 end do 2483 do ii=1,npt2 2484 fct2(ii)=fct3(ii)/(x2(ii)-pole) 2485 end do 2486 2487 do ii=2,npt1-1 2488 xsum=xsum+fct1(ii)*dx1 2489 end do 2490 do ii=2,npt2-1 2491 xsum=xsum+fct2(ii)*dx2 2492 end do 2493 xsum=xsum+half*(fct1(1)+fct1(npt1))*dx1+half*(fct2(1)+fct2(npt2))*dx2 2494 2495 ! Calculate the first and third derivative at the pole and add the taylor expansion 2496 ! TODO: move to spline/splint routines with no memory limitation 2497 call intrpl(npti,xi,fctii,npti,xi,fct3,fct4,fct5,1) 2498 call intrpl(npti,xi,fct4,1,(/pole/),fp,fpp,fppp,1) 2499 2500 idel=two*fp(1)*(del)+fppp(1)*(del**3)/nine 2501 xsum=xsum+idel 2502 2503 end if 2504 2505 ! Calculate the derivated optical quantities and output the value 2506 sigma2=(-two/pi)*xsum 2507 eps1=one-(four_pi*sigma2/(pole)) 2508 eps2=four*fcti(ip)*pi/(pole) 2509 2510 ! A special treatment of the case where eps2 is very small compared to eps1 is needed 2511 if(eps2**2 > eps1**2 * tol12)then 2512 nomega(ip)=sqrt(half*(eps1 + sqrt(eps1**2 + eps2**2))) 2513 komega=sqrt(half*(-eps1 + sqrt(eps1**2 + eps2**2))) 2514 abso(ip)=four_pi*fcti(ip)*ohmtosec*Ohmcm/nomega(ip)/(Sp_Lt_SI*100._dp) 2515 else if(eps1>zero)then 2516 nomega(ip)=sqrt(half*(eps1 + sqrt(eps1**2 + eps2**2))) 2517 komega=half*abs(eps2/sqrt(eps1)) 2518 abso(ip)=four_pi*fcti(ip)*ohmtosec*Ohmcm/nomega(ip)/(Sp_Lt_SI*100._dp) 2519 else if(eps1<zero)then 2520 nomega(ip)=half*abs(eps2/sqrt(-eps1)) 2521 komega=sqrt(half*(-eps1 + sqrt(eps1**2 + eps2**2))) 2522 abso(ip)=two*sqrt(-eps1)*pole*ohmtosec*Ohmcm/(Sp_Lt_SI*100._dp) 2523 end if 2524 2525 refl=((one-nomega(ip))**2 + komega**2)/ & 2526 & ((one+nomega(ip))**2 + komega**2) 2527 2528 write(eps_unt,'(5e18.10)') Ha_eV*pole,fcti(ip)*Ohmcm,sigma2*Ohmcm,eps1,eps2 2529 write(abs_unt,'(5e18.10)') Ha_eV*pole,nomega(ip),komega,refl,abso(ip) 2530 2531 end do 2532 2533 close(eps_unt) 2534 close(abs_unt) 2535 2536 ABI_FREE(fct) 2537 ABI_FREE(x1) 2538 ABI_FREE(x2) 2539 ABI_FREE(fct2) 2540 ABI_FREE(fct3) 2541 ABI_FREE(fct4) 2542 ABI_FREE(fct5) 2543 ABI_FREE(fp) 2544 ABI_FREE(fpp) 2545 ABI_FREE(fppp) 2546 ABI_FREE(fct1) 2547 ABI_FREE(ppsig) 2548 ABI_FREE(fctii) 2549 ABI_FREE(abso) 2550 ABI_FREE(nomega) 2551 2552 end subroutine msig