TABLE OF CONTENTS
- ABINIT/m_ebands
- m_ebands/ebands_apply_scissors
- m_ebands/ebands_calc_nelect
- m_ebands/ebands_chop
- m_ebands/ebands_copy
- m_ebands/ebands_downsample
- m_ebands/ebands_enclose_degbands
- m_ebands/ebands_expandk
- m_ebands/ebands_free
- m_ebands/ebands_from_dtset
- m_ebands/ebands_from_hdr
- m_ebands/ebands_get_bandenergy
- m_ebands/ebands_get_bands_e0
- m_ebands/ebands_get_bands_from_erange
- m_ebands/ebands_get_carriers
- m_ebands/ebands_get_edos
- m_ebands/ebands_get_edos_matrix_elements
- m_ebands/ebands_get_erange
- m_ebands/ebands_get_gaps
- m_ebands/ebands_get_jdos
- m_ebands/ebands_get_minmax
- m_ebands/ebands_get_muT_with_fd
- m_ebands/ebands_get_occupied
- m_ebands/ebands_get_valence_idx
- m_ebands/ebands_has_metal_scheme
- m_ebands/ebands_init
- m_ebands/ebands_interp_kmesh
- m_ebands/ebands_interp_kpath
- m_ebands/ebands_interpolate_kpath
- m_ebands/ebands_move_alloc
- m_ebands/ebands_ncwrite
- m_ebands/ebands_ncwrite_path
- m_ebands/ebands_nelect_per_spin
- m_ebands/ebands_print
- m_ebands/ebands_print_gaps
- m_ebands/ebands_prtbltztrp
- m_ebands/ebands_prtbltztrp_tau_out
- m_ebands/ebands_report_gap
- m_ebands/ebands_set_extrael
- m_ebands/ebands_set_fermie
- m_ebands/ebands_set_scheme
- m_ebands/ebands_sort
- m_ebands/ebands_update_occ
- m_ebands/ebands_vcbm_range_from_gaps
- m_ebands/ebands_write
- m_ebands/ebands_write_bxsf
- m_ebands/ebands_write_gnuplot
- m_ebands/ebands_write_nesting
- m_ebands/ebands_write_xmgrace
- m_ebands/edos_free
- m_ebands/edos_get_carriers
- m_ebands/edos_ncwrite
- m_ebands/edos_print
- m_ebands/edos_t
- m_ebands/edos_write
- m_ebands/gaps_free
- m_ebands/gaps_print
- m_ebands/gaps_t
- m_ebands/get_eneocc_vect
- m_ebands/get_gaps_
- m_ebands/jdos_free
- m_ebands/jdos_ncwrite
- m_ebands/jdos_t
- m_ebands/klinterp_eval_bsd
- m_ebands/klinterp_free
- m_ebands/klinterp_new
- m_ebands/klinterp_t
- m_ebands/pack_eneocc
- m_ebands/put_eneocc_vect
- m_ebands/unpack_eneocc
ABINIT/m_ebands [ Modules ]
NAME
m_ebands
FUNCTION
This module contains utilities to analyze and retrieve information from the ebands_t.
COPYRIGHT
Copyright (C) 2008-2024 ABINIT group (MG, MJV, BXu) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt .
TODO
1) Remove npwarr, istwfk. 2) Use 3d arrays for ebands%nband 3) Solve issue with Hdr dependency
SOURCE
21 #if defined HAVE_CONFIG_H 22 #include "config.h" 23 #endif 24 25 #include "abi_common.h" 26 27 MODULE m_ebands 28 29 use defs_basis 30 use m_errors 31 use m_abicore 32 use m_xmpi 33 use m_htetra 34 use m_nctk 35 use netcdf 36 use m_hdr 37 use m_krank 38 use m_skw 39 use m_kpts 40 use m_sort 41 use m_dtset 42 use m_yaml 43 44 use defs_datatypes, only : ebands_t 45 use m_copy, only : alloc_copy 46 use m_io_tools, only : file_exists, open_file 47 use m_time, only : cwtime, cwtime_report 48 use m_fstrings, only : tolower, itoa, sjoin, ftoa, ltoa, ktoa, strcat, basename, replace 49 use m_numeric_tools, only : arth, imin_loc, imax_loc, bisect, stats_t, stats_eval, simpson, simpson_int, wrap2_zero_one, & 50 isdiagmat, get_diag, interpol3d_0d, interpol3d_indices 51 use m_special_funcs, only : gaussian 52 use m_geometry, only : normv 53 use m_cgtools, only : set_istwfk 54 use m_pptools, only : printbxsf 55 use m_occ, only : getnel, newocc, occ_fd 56 use m_nesting, only : mknesting 57 use m_crystal, only : crystal_t 58 use m_bz_mesh, only : isamek, kpath_t, kpath_new 59 use m_fftcore, only : get_kg 60 61 implicit none 62 63 private 64 65 ! Helper functions 66 public :: pack_eneocc ! Helper function for reshaping (energies|occupancies|derivate of occupancies). 67 public :: get_eneocc_vect ! Reshape (ene|occ|docdde) returning a matrix instead of a vector. 68 public :: put_eneocc_vect ! Put (ene|occ|doccde) in vectorial form into the data type doing a reshape. 69 public :: unpack_eneocc ! Helper function for reshaping (energies|occupancies|derivate of occupancies). 70 71 ! Ebands methods 72 public :: ebands_init ! Main creation method. 73 public :: ebands_from_hdr ! Init object from the abinit header. 74 public :: ebands_from_dtset ! Init object from the abinit dataset. 75 public :: ebands_free ! Destruction method. 76 public :: ebands_copy ! Copy of the ebands_t. 77 public :: ebands_move_alloc ! Transfer allocation. 78 public :: ebands_print ! Printout basic info on the data type. 79 public :: ebands_get_bandenergy ! Returns the band energy of the system. 80 public :: ebands_get_valence_idx ! Gives the index of the (valence|bands at E_f). 81 public :: ebands_get_bands_from_erange ! Return the indices of the mix and max band within an energy window. 82 public :: ebands_vcbm_range_from_gaps ! Find band and energy range for states close to the CBM/VBM given input energies. 83 public :: ebands_apply_scissors ! Apply scissors operator (no k-dependency) 84 public :: ebands_get_occupied ! Returns band indices after wich occupations are less than an input value. 85 public :: ebands_enclose_degbands ! Adjust band indices such that all degenerate states are treated. 86 public :: ebands_get_bands_e0 ! Find min/max band indices crossing energy e0 87 public :: ebands_get_erange ! Compute the minimum and maximum energy enclosing a list of states. 88 public :: ebands_nelect_per_spin ! Returns number of electrons per spin channel 89 public :: ebands_get_minmax ! Returns min and Max value of (eig|occ|doccde). 90 public :: ebands_has_metal_scheme ! .True. if metallic occupation scheme is used. 91 public :: ebands_write_bxsf ! Write 3D energies for Fermi surface visualization (XSF format) 92 public :: ebands_update_occ ! Update the occupation numbers. 93 public :: ebands_set_scheme ! Set the occupation scheme. 94 public :: ebands_set_fermie ! Change the fermi level (assume metallic scheme). 95 public :: ebands_set_extrael ! Add extrael to initial number of electrons to simulate e/h doping. 96 ! (assume metallic scheme). 97 public :: ebands_get_muT_with_fd ! Change the number of electrons (assume metallic scheme). 98 public :: ebands_calc_nelect ! Compute nelect from Fermi level and Temperature. 99 public :: ebands_report_gap ! Print info on the fundamental and direct gap. 100 public :: ebands_ncwrite ! Write object to NETCDF file (use ncid) 101 public :: ebands_ncwrite_path ! Dump the object into NETCDF file (use filepath) 102 public :: ebands_write_nesting ! Calculate the nesting function and output data to file. 103 public :: ebands_expandk ! Build a new ebands_t in the full BZ. 104 public :: ebands_downsample ! Build a new ebands_t with a downsampled IBZ. 105 public :: ebands_chop ! Build a new ebands_t with selected nbands. 106 public :: ebands_get_edos ! Compute e-DOS from band structure. 107 public :: ebands_get_jdos ! Compute electron joint-DOS from band structure. 108 109 public :: ebands_get_edos_matrix_elements ! Compute e-DOS and other DOS-like quantities involving 110 ! vectorial or tensorial matrix elements. 111 112 public :: ebands_interp_kmesh ! Use SWK to interpolate energies on a k-mesh. 113 public :: ebands_interp_kpath ! Interpolate energies on a k-path. 114 public :: ebands_interpolate_kpath 115 116 public :: ebands_prtbltztrp ! Output files for BoltzTraP code. 117 public :: ebands_prtbltztrp_tau_out ! Output files for BoltzTraP code, 118 public :: ebands_write ! Driver routine to write bands in different txt formats. 119 public :: ebands_get_carriers ! Compute carrier concentration from input Fermi level and list of Temperatures.
m_ebands/ebands_apply_scissors [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_apply_scissors
FUNCTION
Apply a scissor operator of amplitude scissor_energy.
INPUTS
scissor_energy=The energy shift
OUTPUT
SIDE EFFECT ebands<ebands_t>=The following quantities are modified: %eig(mband,nkpt,nsppol)=The band structure after the application of the scissor operator %fermi_energy
SOURCE
1722 subroutine ebands_apply_scissors(ebands, scissor_energy) 1723 1724 !Arguments ------------------------------------ 1725 !scalars 1726 real(dp),intent(in) :: scissor_energy 1727 class(ebands_t),intent(inout) :: ebands 1728 1729 !Local variables------------------------------- 1730 integer :: ikpt,spin,ival,nband_k 1731 real(dp) :: spinmagntarget_ 1732 character(len=500) :: msg 1733 !arrays 1734 integer :: val_idx(ebands%nkpt,ebands%nsppol) 1735 ! ************************************************************************* 1736 1737 ! Get the valence band index for each k and spin 1738 val_idx(:,:) = ebands_get_valence_idx(ebands) 1739 1740 do spin=1,ebands%nsppol 1741 if (any(val_idx(:, spin) /= val_idx(1, spin))) then 1742 write(msg,'(a,i0,a)')& 1743 'Trying to apply a scissor operator on a metallic band structure for spin: ',spin,& 1744 'Assuming you know what you are doing, continuing anyway! ' 1745 ABI_COMMENT(msg) 1746 !Likely newocc will stop, unless the system is semimetallic ? 1747 end if 1748 end do 1749 1750 ! Apply the scissor 1751 do spin=1,ebands%nsppol 1752 do ikpt=1,ebands%nkpt 1753 nband_k = ebands%nband(ikpt+(spin-1)*ebands%nkpt) 1754 ival = val_idx(ikpt,spin) 1755 1756 if (nband_k >= ival+1) then 1757 ebands%eig(ival+1:,ikpt,spin) = ebands%eig(ival+1:,ikpt,spin) + scissor_energy 1758 else 1759 write(msg,'(2a,4(a,i0))')& 1760 'Not enough bands to apply the scissor operator. ',ch10,& 1761 'spin: ',spin,' ikpt: ',ikpt,' nband_k: ',nband_k,' but valence index: ',ival 1762 ABI_COMMENT(msg) 1763 end if 1764 1765 end do 1766 end do 1767 1768 ! Recalculate the Fermi level and occupation factors. 1769 ! For Semiconductors only the Fermi level is changed (in the middle of the new gap) 1770 spinmagntarget_ = -99.99_dp !?; if (PRESENT(spinmagntarget)) spinmagntarget_=spinmagntarget 1771 call ebands_update_occ(ebands, spinmagntarget_) 1772 1773 end subroutine ebands_apply_scissors
m_ebands/ebands_calc_nelect [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_calc_nelect
FUNCTION
Compute nelect from Fermi level and Temperature.
INPUTS
OUTPUT
SOURCE
2747 real(dp) pure function ebands_calc_nelect(self, kt, fermie) result(nelect) 2748 2749 !Arguments ------------------------------------ 2750 !scalars 2751 class(ebands_t),intent(in) :: self 2752 real(dp),intent(in) :: kt, fermie 2753 2754 !Local variables------------------------------- 2755 !scalars 2756 integer :: spin, ik, ib 2757 real(dp) :: ofact 2758 2759 ! ************************************************************************* 2760 2761 ofact = two / (self%nsppol * self%nspinor) 2762 nelect = zero 2763 do spin=1,self%nsppol 2764 do ik=1,self%nkpt 2765 do ib=1,self%nband(ik + (spin-1)*self%nkpt) 2766 nelect = nelect + self%wtk(ik) * occ_fd(self%eig(ib,ik,spin), kt, fermie) 2767 end do 2768 end do 2769 end do 2770 2771 nelect = ofact * nelect 2772 2773 end function ebands_calc_nelect
m_ebands/ebands_chop [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_chop
FUNCTION
Return a new ebands_t object with a selected number of bands between bstart and bstop
INPUTS
SOURCE
4081 type(ebands_t) function ebands_chop(self, bstart, bstop) result(new) 4082 4083 !Arguments ------------------------------------ 4084 !scalars 4085 class(ebands_t),intent(in) :: self 4086 integer,intent(in) :: bstart, bstop 4087 4088 !Local variables ------------------------------ 4089 integer :: mband, nkpt, nsppol 4090 4091 ! ********************************************************************* 4092 4093 ABI_CHECK_IRANGE(bstart, 1, self%mband, "Invalid bstart") 4094 ABI_CHECK_IRANGE(bstop, 1, self%mband, "Invalid bstop") 4095 ABI_CHECK_ILEQ(bstart, bstop, "bstart should be <= bstop") 4096 4097 ! First copy the bands 4098 call ebands_copy(self, new) 4099 4100 ! Now chop them 4101 ABI_FREE(new%eig) 4102 ABI_FREE(new%occ) 4103 ABI_FREE(new%doccde) 4104 4105 mband = bstop - bstart + 1 4106 nkpt = self%nkpt 4107 nsppol = self%nsppol 4108 4109 ABI_MALLOC(new%eig, (mband, nkpt, nsppol)) 4110 ABI_MALLOC(new%occ, (mband, nkpt, nsppol)) 4111 ABI_MALLOC(new%doccde, (mband, nkpt, nsppol)) 4112 4113 new%mband = mband 4114 new%nband = mband 4115 new%eig = self%eig(bstart:bstop,:,:) 4116 new%occ = self%occ(bstart:bstop,:,:) 4117 new%doccde = self%doccde(bstart:bstop,:,:) 4118 4119 new%bantot = sum(new%nband) 4120 4121 end function ebands_chop
m_ebands/ebands_copy [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_copy
FUNCTION
This subroutine performs a deep copy of an ebands_t datatype.
INPUTS
ibands<ebands_t>=The data type to be copied.
OUTPUT
obands<ebands_t>=The copy.
SOURCE
1062 subroutine ebands_copy(ibands, obands) 1063 1064 !Arguments ------------------------------------ 1065 !scalars 1066 class(ebands_t),intent(in) :: ibands 1067 class(ebands_t),intent(out) :: obands 1068 1069 ! ********************************************************************* 1070 1071 call ebands_free(obands) 1072 1073 ! Copy scalars 1074 obands%bantot = ibands%bantot 1075 obands%ivalence = ibands%ivalence 1076 obands%mband = ibands%mband 1077 obands%nkpt = ibands%nkpt 1078 obands%nspinor = ibands%nspinor 1079 obands%nsppol = ibands%nsppol 1080 obands%occopt = ibands%occopt 1081 obands%kptopt = ibands%kptopt 1082 obands%nshiftk_orig = ibands%nshiftk_orig 1083 obands%nshiftk = ibands%nshiftk 1084 1085 obands%cellcharge = ibands%cellcharge 1086 obands%extrael = ibands%extrael 1087 obands%entropy = ibands%entropy 1088 obands%fermie = ibands%fermie 1089 obands%fermih = ibands%fermih 1090 obands%nelect = ibands%nelect 1091 obands%ne_qFD = ibands%ne_qFD 1092 obands%nh_qFD = ibands%nh_qFD 1093 obands%tphysel = ibands%tphysel 1094 obands%tsmear = ibands%tsmear 1095 1096 obands%kptrlatt_orig = ibands%kptrlatt_orig 1097 obands%kptrlatt = ibands%kptrlatt 1098 1099 ! Copy allocatable arrays 1100 ! integer 1101 call alloc_copy(ibands%istwfk, obands%istwfk) 1102 call alloc_copy(ibands%nband , obands%nband ) 1103 call alloc_copy(ibands%npwarr, obands%npwarr) 1104 1105 ! real 1106 call alloc_copy(ibands%kptns , obands%kptns ) 1107 call alloc_copy(ibands%eig , obands%eig ) 1108 call alloc_copy(ibands%occ , obands%occ ) 1109 call alloc_copy(ibands%doccde, obands%doccde) 1110 call alloc_copy(ibands%wtk , obands%wtk ) 1111 call alloc_copy(ibands%shiftk_orig, obands%shiftk_orig) 1112 call alloc_copy(ibands%shiftk, obands%shiftk) 1113 1114 if (allocated(ibands%linewidth)) call alloc_copy(ibands%linewidth, obands%linewidth) 1115 1116 end subroutine ebands_copy
m_ebands/ebands_downsample [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_downsample
FUNCTION
Return a new ebands_t object of type ebands_t with a coarser IBZ contained in the inititial one.
INPUTS
cryst<crystal_t>=Info on unit cell and symmetries. in_kptrlatt(3,3)=Defines the sampling of the "small" IBZ. Must be submesh of the "fine" mesh. in_nshiftk= Number of shifts in the coarse k-mesh in_shiftk(3, in_nshiftk) = Shifts of the coarse k-mesh
SOURCE
3956 type(ebands_t) function ebands_downsample(self, cryst, in_kptrlatt, in_nshiftk, in_shiftk) result(new) 3957 3958 !Arguments ------------------------------------ 3959 !scalars 3960 integer,intent(in) :: in_nshiftk 3961 type(ebands_t),intent(in) :: self 3962 type(crystal_t),intent(in) :: cryst 3963 !arrays 3964 integer,intent(in) :: in_kptrlatt(3,3) 3965 real(dp),intent(in) :: in_shiftk(3, in_nshiftk) 3966 3967 !Local variables------------------------------- 3968 !scalars 3969 integer,parameter :: sppoldbl1 = 1 3970 integer :: new_nkbz , timrev, bantot, new_nkibz, ik_ibz, ikf, spin,mband, comm 3971 real(dp) :: dksqmax 3972 character(len=500) :: msg 3973 !arrays 3974 integer,allocatable :: ibz_c2f(:,:) 3975 integer :: new_kptrlatt(3,3) 3976 integer,allocatable :: istwfk(:),nband(:,:),npwarr(:) 3977 real(dp),allocatable :: new_kbz(:,:), new_wtk(:), new_kibz(:,:), doccde(:), eig(:), occ(:) 3978 real(dp),allocatable :: doccde_3d(:,:,:), eig_3d(:,:,:), occ_3d(:,:,:), new_shiftk(:,:) 3979 3980 ! ********************************************************************* 3981 3982 comm = xmpi_comm_self 3983 3984 ! Find IBZ associated to the new mesh. 3985 call kpts_ibz_from_kptrlatt(cryst, in_kptrlatt, self%kptopt, in_nshiftk, in_shiftk, & 3986 new_nkibz, new_kibz, new_wtk, new_nkbz, new_kbz, new_kptrlatt=new_kptrlatt, new_shiftk=new_shiftk) 3987 3988 ! Costruct mapping IBZ_coarse --> IBZ_fine 3989 ! We don't change the value of nsppol hence sppoldbl1 is set to 1 3990 ABI_MALLOC(ibz_c2f, (new_nkibz*sppoldbl1, 6)) 3991 3992 timrev = kpts_timrev_from_kptopt(self%kptopt) 3993 call listkk(dksqmax, cryst%gmet, ibz_c2f, self%kptns, new_kibz, self%nkpt, new_nkibz, cryst%nsym, & 3994 sppoldbl1, cryst%symafm, cryst%symrel, timrev, comm, use_symrec=.False.) 3995 3996 if (dksqmax > tol12) then 3997 write(msg, '(a,es16.6,6a)' )& 3998 "At least one of the k-points could not be generated from a symmetrical one. dksqmax: ",dksqmax, ch10,& 3999 "kptrlatt of input ebands: ",trim(ltoa(pack(self%kptrlatt, mask=.True.))),ch10, & 4000 "downsampled K-mesh: ",trim(ltoa(pack(in_kptrlatt, mask=.True.))) 4001 ABI_ERROR(msg) 4002 end if 4003 4004 ABI_MALLOC(istwfk, (new_nkibz)) 4005 ABI_MALLOC(nband, (new_nkibz, self%nsppol)) 4006 ABI_MALLOC(npwarr, (new_nkibz)) 4007 4008 do ik_ibz=1,new_nkibz 4009 ikf = ibz_c2f(ik_ibz, 1) 4010 do spin=1,self%nsppol 4011 nband(ik_ibz, spin) = self%nband(ikf + (spin-1) * self%nkpt) 4012 end do 4013 istwfk(ik_ibz) = self%istwfk(ikf) 4014 npwarr(ik_ibz) = self%npwarr(ikf) 4015 end do 4016 4017 ! Recostruct eig, occ and doccde in the new IBZ. 4018 bantot = sum(nband); mband = maxval(nband) 4019 4020 ABI_MALLOC(doccde_3d, (mband, new_nkibz, self%nsppol)) 4021 ABI_MALLOC(eig_3d, (mband, new_nkibz, self%nsppol)) 4022 ABI_MALLOC(occ_3d, (mband, new_nkibz, self%nsppol)) 4023 4024 do spin=1,self%nsppol 4025 do ik_ibz=1,new_nkibz 4026 ikf = ibz_c2f(ik_ibz, 1) 4027 doccde_3d(:, ik_ibz, spin) = self%doccde(:, ikf, spin) 4028 eig_3d(:, ik_ibz, spin) = self%eig(:, ikf, spin) 4029 occ_3d(:, ik_ibz, spin) = self%occ(:, ikf, spin) 4030 end do 4031 end do 4032 4033 ! Have to pack data to call ebands_init (I wonder who decided to use vectors!) 4034 ABI_MALLOC(doccde, (bantot)) 4035 ABI_MALLOC(eig, (bantot)) 4036 ABI_MALLOC(occ, (bantot)) 4037 4038 call pack_eneocc(new_nkibz, self%nsppol, mband, nband, bantot, doccde_3d, doccde) 4039 call pack_eneocc(new_nkibz, self%nsppol, mband, nband, bantot, eig_3d, eig) 4040 call pack_eneocc(new_nkibz, self%nsppol, mband, nband, bantot, occ_3d, occ) 4041 4042 ABI_FREE(doccde_3d) 4043 ABI_FREE(eig_3d) 4044 ABI_FREE(occ_3d) 4045 4046 call ebands_init(bantot, new, self%nelect, self%ne_qFD, self%nh_qFD, self%ivalence, doccde, eig, istwfk, new_kibz, & 4047 nband, new_nkibz, npwarr, self%nsppol, self%nspinor, self%tphysel, self%tsmear, self%occopt, occ, new_wtk, & 4048 self%cellcharge, self%kptopt, in_kptrlatt, in_nshiftk, self%shiftk, new_kptrlatt, size(new_shiftk, dim=2), new_shiftk) 4049 4050 new%fermie = self%fermie 4051 new%fermih = self%fermih 4052 4053 ABI_FREE(istwfk) 4054 ABI_FREE(nband) 4055 ABI_FREE(npwarr) 4056 ABI_FREE(doccde) 4057 ABI_FREE(eig) 4058 ABI_FREE(occ) 4059 ABI_FREE(new_kibz) 4060 ABI_FREE(new_kbz) 4061 ABI_FREE(new_wtk) 4062 ABI_FREE(new_shiftk) 4063 ABI_FREE(ibz_c2f) 4064 4065 end function ebands_downsample
m_ebands/ebands_enclose_degbands [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_enclose_degbands
FUNCTION
Adjust ibmin and ibmax such that all the degenerate states are enclosed between ibmin and ibmax. The routine works for a given k-point a spin.
INPUTS
ebands<ebands_t>=The object describing the band structure. ikibz=Index of the k-point. spin=Spin index. tol_enedif=Tolerance on the energy difference.
OUTPUT
changed=.TRUE. if ibmin or ibmax has been changed. [degblock(2,ndeg)]=Table allocated by the routine containing the index of the bands in the `ndeg` degenerate sub-sets degblock(1, ii) = first band index in the ii-th degenerate subset. degblock(2, ii) = last band index in the ii-th degenerate subset.
SIDE EFFECTS
ibmin,ibmax= Input: initial guess for the indices Output: All the denerate states are between ibmin and ibmax
SOURCE
1866 subroutine ebands_enclose_degbands(ebands, ikibz, spin, ibmin, ibmax, changed, tol_enedif, degblock) 1867 1868 !Arguments ------------------------------------ 1869 !scalars 1870 class(ebands_t),intent(in) :: ebands 1871 integer,intent(in) :: ikibz,spin 1872 integer,intent(inout) :: ibmin,ibmax 1873 real(dp),intent(in) :: tol_enedif 1874 logical,intent(out) :: changed 1875 !arrays 1876 integer,allocatable,optional,intent(out) :: degblock(:,:) 1877 1878 !Local variables------------------------------- 1879 !scalars 1880 integer :: ib,ibmin_bkp,ibmax_bkp,ndeg 1881 real(dp) :: emin,emax 1882 1883 ! ************************************************************************* 1884 1885 ibmin_bkp = ibmin; ibmax_bkp = ibmax 1886 1887 emin = ebands%eig(ibmin,ikibz,spin) 1888 do ib=ibmin-1,1,-1 1889 if (ABS(ebands%eig(ib,ikibz,spin) - emin) > tol_enedif) then 1890 ibmin = ib +1 1891 EXIT 1892 else 1893 ibmin = ib 1894 end if 1895 end do 1896 1897 emax = ebands%eig(ibmax,ikibz,spin) 1898 do ib=ibmax+1,ebands%nband(ikibz+(spin-1)*ebands%nkpt) 1899 if ( ABS(ebands%eig(ib,ikibz,spin) - emax) > tol_enedif) then 1900 ibmax = ib - 1 1901 EXIT 1902 else 1903 ibmax = ib 1904 end if 1905 end do 1906 1907 changed = (ibmin /= ibmin_bkp) .or. (ibmax /= ibmax_bkp) 1908 1909 ! Compute degeneracy table. 1910 if (present(degblock)) then 1911 ! Count number of degeneracies. 1912 ndeg = 1 1913 do ib=ibmin+1,ibmax 1914 if ( abs(ebands%eig(ib,ikibz,spin) - ebands%eig(ib-1,ikibz,spin) ) > tol_enedif) ndeg = ndeg + 1 1915 end do 1916 ! Build degblock table. 1917 ABI_REMALLOC(degblock, (2, ndeg)) 1918 ndeg = 1; degblock(1, 1) = ibmin 1919 do ib=ibmin+1,ibmax 1920 if ( abs(ebands%eig(ib,ikibz,spin) - ebands%eig(ib-1,ikibz,spin) ) > tol_enedif) then 1921 degblock(2, ndeg) = ib - 1 1922 ndeg = ndeg + 1 1923 degblock(1, ndeg) = ib 1924 end if 1925 end do 1926 degblock(2, ndeg) = ibmax 1927 end if 1928 1929 end subroutine ebands_enclose_degbands
m_ebands/ebands_expandk [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_expandk
FUNCTION
Return a new object of type ebands_t corresponding to a list of k-points specified in input. Symmetry properties of the eigenvectors are used to symmetrize energies and occupation numbers.
INPUTS
inb<ebands_t>=Initial band structure with energies in the IBZ. ecut_eff=Effective cutoff energy i.e. ecut * dilatmx**2 force_istwfk1=If True, istwfk if forced to 1 for all the k-points in the BZ.
OUTPUT
dksqmax=maximal value of the norm**2 of the difference between a kpt in the BZ and the closest k-point found in the inb%kpts set, using symmetries. bz2ibz(nkpt2,6)=describe k point number of kpt1 that allows to generate wavefunctions closest to given kpt2 bz2ibz(:,1)=k point number of kptns1 bz2ibz(:,2)=symmetry operation to be applied to kpt1, to give kpt1a (if 0, means no symmetry operation, equivalent to identity ) bz2ibz(:,3:5)=shift in reciprocal space to be given to kpt1a, to give kpt1b, that is the closest to kpt2. bz2ibz(:,6)=1 if time-reversal was used to generate kpt1a from kpt1, 0 otherwise outb<ebands_t>=band structure with energies in the BZ.
SOURCE
3801 subroutine ebands_expandk(inb, cryst, ecut_eff, force_istwfk1, dksqmax, bz2ibz, outb) 3802 3803 !Arguments ------------------------------------ 3804 !scalars 3805 real(dp),intent(in) :: ecut_eff 3806 real(dp),intent(out) :: dksqmax 3807 logical,intent(in) :: force_istwfk1 3808 class(ebands_t),intent(in) :: inb 3809 class(ebands_t),intent(out) :: outb 3810 class(crystal_t),intent(in) :: cryst 3811 !arrays 3812 integer,allocatable,intent(out) :: bz2ibz(:,:) 3813 3814 !Local variables------------------------------- 3815 !scalars 3816 integer,parameter :: istwfk_1=1,kptopt3=3 3817 integer :: nkfull,timrev,bantot,sppoldbl,npw_k,nsppol,istw 3818 integer :: ik_ibz,ikf,isym,itimrev,spin,mband,my_nkibz,comm 3819 logical :: isirred_k 3820 !character(len=500) :: msg 3821 !arrays 3822 integer :: g0(3) 3823 integer,allocatable :: istwfk(:),nband(:,:),npwarr(:),kg_k(:,:) 3824 real(dp),allocatable :: kfull(:,:),doccde(:),eig(:),occ(:),wtk(:),my_kibz(:,:) 3825 real(dp),allocatable :: doccde_3d(:,:,:),eig_3d(:,:,:),occ_3d(:,:,:) 3826 3827 ! ********************************************************************* 3828 3829 ABI_CHECK(inb%kptopt /= 0, "ebands_expandk does not support kptopt == 0") 3830 3831 comm = xmpi_comm_self 3832 nsppol = inb%nsppol 3833 3834 ! Note kptopt=3 3835 call kpts_ibz_from_kptrlatt(cryst, inb%kptrlatt, kptopt3, inb%nshiftk, inb%shiftk, & 3836 my_nkibz, my_kibz, wtk, nkfull, kfull) ! new_kptrlatt, new_shiftk) 3837 3838 ABI_FREE(my_kibz) 3839 ABI_FREE(wtk) 3840 3841 ! Costruct full BZ and create mapping BZ --> IBZ 3842 ! Note: 3843 ! - we don't change the value of nsppol hence sppoldbl is set to 1 3844 ! - we use symrel so that bz2ibz can be used to reconstruct the wavefunctions. 3845 ! 3846 sppoldbl = 1 !; if (any(cryst%symafm == -1) .and. inb%nsppol == 1) sppoldbl=2 3847 ABI_MALLOC(bz2ibz, (nkfull*sppoldbl,6)) 3848 3849 timrev = kpts_timrev_from_kptopt(inb%kptopt) 3850 call listkk(dksqmax, cryst%gmet, bz2ibz, inb%kptns, kfull, inb%nkpt, nkfull, cryst%nsym, & 3851 sppoldbl, cryst%symafm, cryst%symrel, timrev, comm, use_symrec=.False.) 3852 3853 ABI_MALLOC(wtk, (nkfull)) 3854 wtk = one / nkfull ! weights normalized to one 3855 3856 ABI_MALLOC(istwfk, (nkfull)) 3857 ABI_MALLOC(nband, (nkfull, nsppol)) 3858 ABI_MALLOC(npwarr, (nkfull)) 3859 3860 if (any(cryst%symrel(:,:,1) /= identity_3d) .and. any(abs(cryst%tnons(:,1)) > tol10) ) then 3861 ABI_ERROR('The first symmetry is not the identity operator!') 3862 end if 3863 3864 do ikf=1,nkfull 3865 ik_ibz = bz2ibz(ikf,1) 3866 isym = bz2ibz(ikf,2) 3867 itimrev = bz2ibz(ikf,6) 3868 g0 = bz2ibz(ikf,3:5) ! IS(k_ibz) + g0 = k_bz 3869 isirred_k = (isym == 1 .and. itimrev == 0 .and. all(g0 == 0)) 3870 3871 do spin=1,nsppol 3872 nband(ikf,spin) = inb%nband(ik_ibz+(spin-1)*inb%nkpt) 3873 end do 3874 3875 if (force_istwfk1) then 3876 call get_kg(kfull(:,ikf),istwfk_1,ecut_eff,cryst%gmet,npw_k,kg_k) 3877 ABI_FREE(kg_k) 3878 istwfk(ikf) = 1 3879 npwarr(ikf) = npw_k 3880 else 3881 if (isirred_k) then 3882 istwfk(ikf) = inb%istwfk(ik_ibz) 3883 npwarr(ikf) = inb%npwarr(ik_ibz) 3884 else 3885 istw = set_istwfk(kfull(:,ikf)) 3886 call get_kg(kfull(:,ikf),istw,ecut_eff,cryst%gmet,npw_k,kg_k) 3887 ABI_FREE(kg_k) 3888 istwfk(ikf) = istw 3889 npwarr(ikf) = npw_k 3890 end if 3891 end if 3892 end do 3893 3894 ! Recostruct eig, occ and doccde in the BZ. 3895 bantot = sum(nband); mband = maxval(nband) 3896 3897 ABI_MALLOC(doccde_3d, (mband, nkfull, nsppol)) 3898 ABI_MALLOC(eig_3d, (mband, nkfull, nsppol)) 3899 ABI_MALLOC(occ_3d, (mband, nkfull, nsppol)) 3900 3901 do spin=1,nsppol 3902 do ikf=1,nkfull 3903 ik_ibz = bz2ibz(ikf,1) 3904 doccde_3d(:,ikf,spin) = inb%doccde(:,ik_ibz,spin) 3905 eig_3d(:,ikf,spin) = inb%eig(:,ik_ibz,spin) 3906 occ_3d(:,ikf,spin) = inb%occ(:,ik_ibz,spin) 3907 end do 3908 end do 3909 3910 ! Have to pack data to call ebands_init (I wonder who decided to use vectors!) 3911 ABI_MALLOC(doccde, (bantot)) 3912 ABI_MALLOC(eig, (bantot)) 3913 ABI_MALLOC(occ, (bantot)) 3914 3915 call pack_eneocc(nkfull, nsppol, mband, nband, bantot, doccde_3d, doccde) 3916 call pack_eneocc(nkfull, nsppol, mband, nband, bantot, eig_3d, eig) 3917 call pack_eneocc(nkfull, nsppol, mband, nband, bantot, occ_3d, occ) 3918 3919 ABI_FREE(doccde_3d) 3920 ABI_FREE(eig_3d) 3921 ABI_FREE(occ_3d) 3922 3923 call ebands_init(bantot, outb, inb%nelect, inb%ne_qFD, inb%nh_qFD, inb%ivalence, doccde, eig, istwfk, kfull, & 3924 nband, nkfull, npwarr, nsppol, inb%nspinor, inb%tphysel, inb%tsmear, inb%occopt, occ, wtk, & 3925 inb%cellcharge, kptopt3, inb%kptrlatt_orig, inb%nshiftk_orig, inb%shiftk_orig, inb%kptrlatt, inb%nshiftk, inb%shiftk) 3926 3927 ABI_FREE(istwfk) 3928 ABI_FREE(nband) 3929 ABI_FREE(npwarr) 3930 ABI_FREE(doccde) 3931 ABI_FREE(eig) 3932 ABI_FREE(occ) 3933 ABI_FREE(wtk) 3934 ABI_FREE(kfull) 3935 3936 end subroutine ebands_expandk
m_ebands/ebands_free [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_free
FUNCTION
Deallocates the components of the ebands_t structured datatype
INPUTS
ebands<ebands_t>=The data type to be deallocated.
OUTPUT
Deallocate the dynamic arrays in the ebands_t type.
SOURCE
1022 subroutine ebands_free(ebands) 1023 1024 !Arguments ------------------------------------ 1025 class(ebands_t),intent(inout) :: ebands 1026 ! ************************************************************************* 1027 1028 ABI_SFREE(ebands%istwfk) 1029 ABI_SFREE(ebands%nband) 1030 ABI_SFREE(ebands%npwarr) 1031 ABI_SFREE(ebands%kptns) 1032 ABI_SFREE(ebands%eig) 1033 ABI_SFREE(ebands%linewidth) 1034 ABI_SFREE(ebands%occ) 1035 ABI_SFREE(ebands%doccde) 1036 ABI_SFREE(ebands%wtk) 1037 !ABI_SFREE(ebands%velocity) 1038 !ABI_SFREE(ebands%kTmesh) 1039 ABI_SFREE(ebands%shiftk_orig) 1040 ABI_SFREE(ebands%shiftk) 1041 1042 end subroutine ebands_free
m_ebands/ebands_from_dtset [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_from_dtset
FUNCTION
Build and return a new ebands_t datatype. Dimensions are taken from the abinit dataset.
INPUTS
dtset<dataset_type>=Abinit dataset npwarr(dtset%nkpt)=Number of G-vectors for each k-point. [nband]= If present, use these values instead of dtset%nband
OUTPUT
ebands<ebands_t>=The ebands_t datatype completely initialized. The Fermi level and the entropy are set to zero.
SOURCE
965 type(ebands_t) function ebands_from_dtset(dtset, npwarr, nband) result(new) 966 967 !Arguments ------------------------------------ 968 !scalars 969 type(dataset_type),target,intent(in) :: dtset 970 integer,target,optional,intent(in) :: nband(dtset%nkpt * dtset%nsppol) 971 !arrays 972 integer,intent(in) :: npwarr(dtset%nkpt) 973 974 !Local variables------------------------------- 975 !scalars 976 integer :: bantot 977 !arrays 978 real(dp),allocatable :: ugly_doccde(:), ugly_ene(:), ugly_occ(:) 979 integer,pointer :: nband__(:) 980 ! ************************************************************************* 981 982 nband__ => dtset%nband; if (present(nband)) nband__ => nband 983 984 ! Have to use ugly 1d vectors to call ebands_init 985 bantot = sum(nband__) 986 ABI_CALLOC(ugly_doccde, (bantot)) 987 ABI_CALLOC(ugly_ene, (bantot)) 988 ABI_CALLOC(ugly_occ, (bantot)) 989 990 call ebands_init(bantot, new, dtset%nelect, dtset%ne_qFD, dtset%nh_qFD, dtset%ivalence, ugly_doccde, ugly_ene, & 991 dtset%istwfk, dtset%kptns, nband__, dtset%nkpt, & 992 npwarr, dtset%nsppol, dtset%nspinor, dtset%tphysel, dtset%tsmear, dtset%occopt, ugly_occ, dtset%wtk,& 993 dtset%cellcharge(1), dtset%kptopt, dtset%kptrlatt_orig, dtset%nshiftk_orig, dtset%shiftk_orig, & 994 dtset%kptrlatt, dtset%nshiftk, dtset%shiftk) 995 996 !new%extrael = dtset%eph_extrael 997 998 ABI_FREE(ugly_doccde) 999 ABI_FREE(ugly_ene) 1000 ABI_FREE(ugly_occ) 1001 1002 end function ebands_from_dtset
m_ebands/ebands_from_hdr [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_from_hdr
FUNCTION
This subroutine initializes the ebands_t datatype from the abinit header by calling the main creation method.
INPUTS
Hdr<hdr_type>=Abinit header. mband=Maximum number of bands. ene3d(mband,Hdr%nkpt,Hdr%nsppol)=Energies. [nelect]=Number of electrons per unit cell. Optional argument that can be used for performing a ridid shift of the fermi level. in the case of metallic occupancies. If not specified, nelect will be initialized from Hdr.
OUTPUT
ebands<ebands_t>=The ebands_t datatype completely initialized.
SOURCE
904 type(ebands_t) function ebands_from_hdr(hdr, mband, ene3d, nelect) result(ebands) 905 906 !Arguments ------------------------------------ 907 !scalars 908 integer,intent(in) :: mband 909 type(hdr_type),intent(in) :: hdr 910 real(dp),optional,intent(in) :: nelect 911 !arrays 912 real(dp),intent(in) :: ene3d(mband,hdr%nkpt,hdr%nsppol) 913 914 !Local variables------------------------------- 915 !scalars 916 real(dp) :: my_nelect 917 !arrays 918 real(dp),allocatable :: ugly_doccde(:),ugly_ene(:) 919 920 ! ************************************************************************* 921 922 my_nelect = hdr%nelect; if (present(nelect)) my_nelect = nelect 923 924 ! Have to use ugly 1d vectors to call ebands_init 925 ABI_CALLOC(ugly_doccde, (hdr%bantot)) 926 ABI_MALLOC(ugly_ene, (hdr%bantot)) 927 928 call pack_eneocc(hdr%nkpt, hdr%nsppol, mband, hdr%nband, hdr%bantot, ene3d, ugly_ene) 929 930 call ebands_init(hdr%bantot, ebands, my_nelect, hdr%ne_qFD, hdr%nh_qFD, hdr%ivalence, & 931 ugly_doccde, ugly_ene, hdr%istwfk, hdr%kptns, hdr%nband, hdr%nkpt, & 932 hdr%npwarr, hdr%nsppol, hdr%nspinor, hdr%tphysel, hdr%tsmear, hdr%occopt, hdr%occ, hdr%wtk, & 933 hdr%cellcharge, hdr%kptopt, hdr%kptrlatt_orig, hdr%nshiftk_orig, hdr%shiftk_orig, hdr%kptrlatt, hdr%nshiftk, hdr%shiftk) 934 935 ! Copy the fermi level reported in the header 936 ebands%fermie = hdr%fermie 937 ebands%fermih = hdr%fermih 938 939 ABI_FREE(ugly_doccde) 940 ABI_FREE(ugly_ene) 941 942 end function ebands_from_hdr
m_ebands/ebands_get_bandenergy [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_get_bandenergy
FUNCTION
Return the band energy (weighted sum of occupied eigenvalues)
INPUTS
OUTPUT
NOTES
TODO Likely this expression is not accurate since it is not variatonal One should use band_energy = \int e N(e) de for e<Ef , where N(e) is the e-DOS
SOURCE
1483 pure real(dp) function ebands_get_bandenergy(ebands) result(band_energy) 1484 1485 !Arguments ------------------------------------ 1486 !scalars 1487 class(ebands_t),intent(in) :: ebands 1488 1489 !Local variables------------------------------- 1490 integer :: spin,ikibz,nband_k 1491 real(dp) :: wtk 1492 ! ********************************************************************* 1493 1494 band_energy=zero 1495 do spin=1,ebands%nsppol 1496 do ikibz=1,ebands%nkpt 1497 wtk=ebands%wtk(ikibz) 1498 nband_k=ebands%nband(ikibz+(spin-1)*ebands%nkpt) 1499 band_energy = band_energy + wtk*SUM( ebands%eig(1:nband_k,ikibz,spin)*ebands%occ(1:nband_k,ikibz,spin) ) 1500 end do 1501 end do 1502 1503 end function ebands_get_bandenergy
m_ebands/ebands_get_bands_e0 [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_get_bands_e0
FUNCTION
Find min/max band indices crossing energy e0 min/max are returned in brange_spin(1:2, spin) for each spin. If no band crosses e0, bmin is set to +huge(1) and bmax to -huge(1) and ierr != 0
INPUTS
OUTPUT
SOURCE
1949 subroutine ebands_get_bands_e0(ebands, e0, brange_spin, ierr) 1950 1951 !Arguments ------------------------------------ 1952 !scalars 1953 class(ebands_t),intent(in) :: ebands 1954 real(dp),intent(in) :: e0 1955 integer,intent(out) :: brange_spin(2, ebands%nsppol) 1956 integer,intent(out) :: ierr 1957 1958 !Local variables------------------------------- 1959 integer :: band, spin, bmin, bmax 1960 real(dp) :: emin, emax 1961 1962 ! ************************************************************************* 1963 1964 ierr = 0 1965 do spin=1,ebands%nsppol 1966 bmin = +huge(1); bmax = -huge(1) 1967 1968 do band=1,minval(ebands%nband) 1969 emin = minval(ebands%eig(band, :, spin)) 1970 emax = maxval(ebands%eig(band, :, spin)) 1971 if (emin <= e0 .and. emax >= e0) then 1972 bmin = min(bmin, band) 1973 bmax = max(bmax, band) 1974 end if 1975 end do 1976 1977 brange_spin(:, spin) = [bmin, bmax] 1978 if (bmin == +huge(1)) ierr = ierr + 1 1979 end do 1980 1981 end subroutine ebands_get_bands_e0
m_ebands/ebands_get_bands_from_erange [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_get_bands_from_erange
FUNCTION
Return the indices of the min and max band index within an energy window.
INPUTS
elow, ehigh: Min and max energy
OUTPUT
bstart, bstop: Min and max band index. Initialized to bstart = huge(1); bstop = -huge(1)
SOURCE
1580 pure subroutine ebands_get_bands_from_erange(ebands, elow, ehigh, bstart, bstop) 1581 1582 !Arguments ------------------------------------ 1583 !scalars 1584 class(ebands_t),intent(in) :: ebands 1585 real(dp),intent(in) :: elow, ehigh 1586 integer,intent(out) :: bstart, bstop 1587 1588 !Local variables------------------------------- 1589 integer :: band, ik, spin 1590 1591 ! ************************************************************************* 1592 1593 bstart = huge(1); bstop = -huge(1) 1594 do spin=1,ebands%nsppol 1595 do ik=1,ebands%nkpt 1596 do band=1,ebands%nband(ik + (spin - 1) * ebands%nkpt) 1597 if (ebands%eig(band, ik , spin) >= elow .and. ebands%eig(band, ik , spin) <= ehigh) then 1598 bstart = min(bstart, band) 1599 bstop = max(bstop, band) 1600 end if 1601 end do 1602 end do 1603 end do 1604 1605 end subroutine ebands_get_bands_from_erange
m_ebands/ebands_get_carriers [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_get_carriers
FUNCTION
Compute number of electrons (e) and holes (h) per unit cell from a given list of `ntemp` temperatures `kTmesh` and chemical potentials `mu_e`. Return n_ehst(2, nsppol, ntemp) where the first dimension if for electrons/holes. If nsppol == 2, the second dimension is the number of e/h for spin else the total number of e/h summed over spins. To discern between electrons and holes in semiconductors we assume that ef is inside the gap.
SOURCE
6108 subroutine ebands_get_carriers(self, ntemp, kTmesh, mu_e, n_ehst) 6109 6110 !Arguments ------------------------------------ 6111 !scalars 6112 class(ebands_t),intent(in) :: self 6113 integer,intent(in) :: ntemp 6114 !arrays 6115 real(dp),intent(in) :: kTmesh(ntemp), mu_e(ntemp) 6116 real(dp),intent(out) :: n_ehst(2, self%nsppol, ntemp) 6117 6118 !Local variables------------------------------- 6119 integer :: spin, ik_ibz, ib, itemp 6120 real(dp) :: max_occ, wtk, eig_nk 6121 6122 ! ********************************************************************* 6123 6124 max_occ = two / (self%nspinor * self%nsppol) 6125 n_ehst = zero 6126 6127 do spin=1,self%nsppol 6128 do ik_ibz=1,self%nkpt 6129 wtk = self%wtk(ik_ibz) 6130 do ib=1, self%nband(ik_ibz + (spin-1) * self%nkpt) 6131 eig_nk = self%eig(ib, ik_ibz, spin) 6132 6133 do itemp=1,ntemp 6134 if (eig_nk >= mu_e(itemp)) then 6135 ! electron (assuming ef inside the gap if semiconductor) 6136 n_ehst(1, spin, itemp) = n_ehst(1, spin, itemp) + & 6137 wtk * occ_fd(eig_nk, kTmesh(itemp), mu_e(itemp)) * max_occ 6138 else 6139 ! holes 6140 n_ehst(2, spin, itemp) = n_ehst(2, spin, itemp) + & 6141 wtk * (one - occ_fd(eig_nk, kTmesh(itemp), mu_e(itemp))) * max_occ 6142 end if 6143 end do 6144 6145 end do 6146 end do 6147 end do 6148 6149 end subroutine ebands_get_carriers
m_ebands/ebands_get_edos [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_get_edos
FUNCTION
Calculate the electronic density of states from ebands_t
INPUTS
ebands<ebands_t>=Band structure object. cryst<cryst_t>=Info on the crystalline structure. intmeth= 1 for Gaussian, 2 or -2 for tetrahedra (-2 if Blochl corrections must be included). If nkpt == 1 (Gamma only), the routine fallbacks to gaussian method. step=Step on the linear mesh in Ha. If <0, the routine will use the mean of the energy level spacing broad=Gaussian broadening, If <0, the routine will use a default value for the broadening computed from the mean of the energy level spacing. No meaning for tetrahedra comm=MPI communicator
OUTPUT
edos<edos_t>=Electronic DOS and IDOS.
SOURCE
3146 type(edos_t) function ebands_get_edos(ebands, cryst, intmeth, step, broad, comm) result(edos) 3147 3148 !Arguments ------------------------------------ 3149 !scalars 3150 integer,intent(in) :: intmeth,comm 3151 real(dp),intent(in) :: step,broad 3152 class(ebands_t),target,intent(in) :: ebands 3153 type(crystal_t),intent(in) :: cryst 3154 3155 !Local variables------------------------------- 3156 !scalars 3157 integer :: nw,spin,band,ikpt,ief,ihf,nproc,my_rank,ierr,cnt,bcorr 3158 real(dp) :: max_ene,min_ene,wtk,max_occ 3159 character(len=500) :: msg 3160 type(htetra_t) :: tetra 3161 !arrays 3162 real(dp) :: eminmax_spin(2,ebands%nsppol) 3163 real(dp),allocatable :: wme0(:),wdt(:,:),tmp_eigen(:) 3164 3165 ! ********************************************************************* 3166 3167 nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm) 3168 ierr = 0 3169 3170 edos%nkibz = ebands%nkpt; edos%nsppol = ebands%nsppol; edos%nspinor = ebands%nspinor 3171 edos%intmeth = intmeth 3172 edos%nelect = ebands%nelect 3173 3174 if (ebands%nkpt == 1) then 3175 ABI_COMMENT("Cannot use tetrahedra for e-DOS when nkpt == 1. Switching to gaussian method") 3176 edos%intmeth = 1 3177 end if 3178 3179 edos%broad = broad; edos%step = step 3180 3181 ! Compute the linear mesh so that it encloses all bands. 3182 eminmax_spin = ebands_get_minmax(ebands, "eig") 3183 min_ene = minval(eminmax_spin(1, :)); min_ene = min_ene - 0.1_dp * abs(min_ene) 3184 max_ene = maxval(eminmax_spin(2, :)); max_ene = max_ene + 0.1_dp * abs(max_ene) 3185 3186 nw = nint((max_ene - min_ene) / edos%step) + 1; edos%nw = nw 3187 3188 ABI_MALLOC(edos%mesh, (nw)) 3189 edos%mesh = arth(min_ene, edos%step, nw) 3190 3191 ABI_CALLOC(edos%gef, (0:edos%nsppol)) 3192 ABI_CALLOC(edos%ghf, (0:edos%nsppol)) 3193 ABI_CALLOC(edos%dos, (nw, 0:edos%nsppol)) 3194 ABI_CALLOC(edos%idos, (nw, 0:edos%nsppol)) 3195 3196 select case (edos%intmeth) 3197 case (1) 3198 !call wrtout(std_out, " Computing electron-DOS with Gaussian method") 3199 !call wrtout(std_out, sjoin(" broadening: ", ftoa(edos%broad * Ha_eV), " (eV), step: ", ftoa(edos%step * Ha_eV), "(eV), npts: ", 3200 !itoa(nw))) 3201 ! Gaussian 3202 ABI_MALLOC(wme0, (nw)) 3203 cnt = 0 3204 do spin=1,edos%nsppol 3205 do ikpt=1,ebands%nkpt 3206 cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle ! MPI parallelism 3207 wtk = ebands%wtk(ikpt) 3208 do band=1,ebands%nband(ikpt+(spin-1)*ebands%nkpt) 3209 wme0 = edos%mesh - ebands%eig(band, ikpt, spin) 3210 edos%dos(:, spin) = edos%dos(:, spin) + wtk * gaussian(wme0, edos%broad) 3211 end do 3212 end do 3213 end do 3214 ABI_FREE(wme0) 3215 call xmpi_sum(edos%dos, comm, ierr) 3216 3217 case (2, -2) 3218 !call wrtout(std_out, " Computing electron-DOS with tetrahedron method") 3219 ! Consistency test 3220 if (any(ebands%nband /= ebands%nband(1)) ) ABI_ERROR('for tetrahedra, nband(:) must be constant') 3221 3222 ! Build tetra object. 3223 tetra = tetra_from_kptrlatt(cryst, ebands%kptopt, ebands%kptrlatt, & 3224 ebands%nshiftk, ebands%shiftk, ebands%nkpt, ebands%kptns, comm, msg, ierr) 3225 ABI_CHECK(ierr == 0, msg) 3226 3227 ! For each spin and band, interpolate over kpoints, calculate integration weights and DOS contribution. 3228 ABI_MALLOC(tmp_eigen, (ebands%nkpt)) 3229 ABI_MALLOC(wdt, (nw, 2)) 3230 3231 bcorr = 0; if (intmeth == -2) bcorr = 1 3232 cnt = 0 3233 do spin=1,ebands%nsppol 3234 do band=1,ebands%nband(1) 3235 ! For each band get its contribution 3236 tmp_eigen = ebands%eig(band,:,spin) 3237 do ikpt=1,ebands%nkpt 3238 cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle ! MPI parallelism. 3239 3240 ! Calculate integration weights at each irred k-point (Blochl et al PRB 49 16223 [[cite:Bloechl1994a]]) 3241 call tetra%get_onewk(ikpt, bcorr, nw, ebands%nkpt, tmp_eigen, min_ene, max_ene, one, wdt) 3242 3243 edos%dos(:,spin) = edos%dos(:,spin) + wdt(:, 1) * ebands%wtk(ikpt) 3244 edos%idos(:,spin) = edos%idos(:,spin) + wdt(:, 2) * ebands%wtk(ikpt) 3245 end do ! ikpt 3246 end do ! band 3247 end do ! spin 3248 3249 call xmpi_sum(edos%dos, comm, ierr) 3250 call xmpi_sum(edos%idos, comm, ierr) 3251 3252 ! Free memory 3253 ABI_FREE(tmp_eigen) 3254 ABI_FREE(wdt) 3255 call tetra%free() 3256 3257 ! Filter so that dos[i] is always >= 0 and idos is monotonic 3258 ! IDOS is computed afterwards with simpson 3259 where (edos%dos(:,1:) <= zero) 3260 edos%dos(:,1:) = zero 3261 end where 3262 3263 case default 3264 ABI_ERROR(sjoin("Wrong integration method:", itoa(intmeth))) 3265 end select 3266 3267 ! Compute total DOS and IDOS by summing the two spin channels. 3268 max_occ = two / (ebands%nspinor * ebands%nsppol) 3269 edos%dos(:, 0) = max_occ * sum(edos%dos(:,1:), dim=2) 3270 3271 if (edos%intmeth == 1) then 3272 do spin=1,edos%nsppol 3273 call simpson_int(nw, edos%step, edos%dos(:,spin), edos%idos(:,spin)) 3274 end do 3275 end if 3276 edos%idos(:, 0) = max_occ * sum(edos%idos(:,1:), dim=2) 3277 3278 ! Use bisection to find the Fermi level at T = 0 3279 ! Warning: this code assumes idos[i+1] >= idos[i]. This condition may not be 3280 ! fullfilled if we use tetra and this is the reason why we have filtered the DOS. 3281 if (ebands%occopt == 9) then 3282 ihf = bisect(edos%idos(:,0), ebands%nelect-ebands%nh_qFD) 3283 ief = bisect(edos%idos(:,0), ebands%nelect+ebands%ne_qFD) 3284 else 3285 ief = bisect(edos%idos(:,0), ebands%nelect) 3286 ihf = ief 3287 end if 3288 3289 ! Handle out of range condition. 3290 if (ief == 0 .or. ief == nw) then 3291 write(msg,"(3a)")& 3292 "Bisection could not find an initial guess for the Fermi level!",ch10,& 3293 "Possible reasons: not enough bands or wrong number of electrons" 3294 ABI_WARNING(msg) 3295 return 3296 else if (ihf == 0 .or. ihf == nw) then 3297 write(msg,"(3a)")& 3298 "Bisection could not find an initial guess for the holes Fermi level!",ch10,& 3299 "Possible reasons: not enough bands or wrong number of holes" 3300 ABI_WARNING(msg) 3301 return 3302 end if 3303 3304 ! TODO: Use linear interpolation to find an improved estimate of the Fermi level? 3305 edos%ief = ief 3306 edos%ihf = ihf 3307 do spin=0,edos%nsppol 3308 edos%gef(spin) = edos%dos(ief,spin) 3309 edos%ghf(spin) = edos%dos(ihf,spin) 3310 end do 3311 3312 !write(std_out,*)"fermie from ebands: ",ebands%fermie 3313 !write(std_out,*)"fermie from IDOS: ",edos%mesh(ief) 3314 !write(std_out,*)"gef:from ebands%fermie: " ,edos%dos(bisect(edos%mesh, ebands%fermie), 0) 3315 !write(std_out,*)"gef:from edos: " ,edos%gef(0) 3316 3317 end function ebands_get_edos
m_ebands/ebands_get_edos_matrix_elements [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_get_edos_matrix_elements
FUNCTION
Compute electron DOS and weighted e-DOS with weights given by precomputed scalar, vectorial or tensorial matrix elements. Weights are provided in input as (..., num_entries, bsize, nkpt, nsppol) tables, see below.
INPUTS
ebands<ebands_t>=Band structure object. cryst<cryst_t>=Info on the crystalline structure. bsize=Number of bands in bks_vals, bks_vecs and bks_tens Not necessarily equal to ebands%mband when brange is used. nvals=Number of scalar entries. Maybe zero bks_vals=Scalar matrix elements nvecs=Number of 3d-vectorial entries. Maybe zero bks_vecs=Vectorial matrix elements in Cartesian Coordinates ntens=Numer of 3x3 tensorial entries in Cartesian coordinates. Maybe zero bks_tens= Tensorial matrix elements (3x3) in Cartesian Coordinates intmeth= 1 for Gaussian, 2 or -2 for tetrahedra (-2 if Blochl corrections must be included). If nkpt == 1 (Gamma only), the routine fallbacks to the Gaussian method. step=Step on the linear mesh in Ha. If < 0, the routine will use the mean of the energy level spacing broad=Gaussian broadening, If < 0, the routine will use a default value for the broadening computed from the mean of the energy level spacing. No meaning for tetrahedra comm=MPI communicator [brange(2)]=Minimum and maximum band index. Default if not present is `full band range`. If given bsize must be equal: to brange(2) - brange(1) + 1 [erange(2)]=Minimum and maximum energy to be considered. Default if not present is `full energy range`.
OUTPUT
out_valsdos: (nw, 2, nvals, nsppol) array with DOS for scalar quantities if nvals > 0 out_vecsdos: (nw, 2, 3, nvecs, nsppol)) array with DOS weighted by vectorial terms if nvecs > 0 out_tensdos: (nw, 2,3, 3, ntens, nsppol) array with DOS weighted by tensorial terms if ntens > 0 All these arrays are allocated by the routine. The number of points is available in edos%nw. (nw, 1, ...) stores the weighted DOS (w-DOS) (nw, 2, ...) stores the integrated w-DOS
SOURCE
4527 type(edos_t) function ebands_get_edos_matrix_elements(ebands, cryst, bsize, & 4528 nvals, bks_vals, nvecs, bks_vecs, ntens, bks_tens, & 4529 intmeth, step, broad, out_valsdos, out_vecsdos, out_tensdos, comm, & 4530 brange, erange) result(edos) 4531 4532 !Arguments ------------------------------------ 4533 !scalars 4534 integer,intent(in) :: bsize, nvals, nvecs, ntens, intmeth, comm 4535 real(dp),intent(in) :: step, broad 4536 class(ebands_t),intent(in) :: ebands 4537 type(crystal_t),intent(in) :: cryst 4538 !arrays 4539 integer,optional,intent(in) :: brange(2) 4540 real(dp),optional,intent(in) :: erange(2) 4541 real(dp),intent(in) :: bks_vals(nvals, bsize, ebands%nkpt, ebands%nsppol) 4542 real(dp),intent(in) :: bks_vecs(3, nvecs, bsize, ebands%nkpt, ebands%nsppol) 4543 real(dp),intent(in) :: bks_tens(3, 3, ntens, bsize, ebands%nkpt, ebands%nsppol) 4544 real(dp),allocatable,intent(out) :: out_valsdos(:,:,:,:), out_vecsdos(:,:,:,:,:), out_tensdos(:,:,:,:,:,:) 4545 4546 !Local variables------------------------------- 4547 !scalars 4548 integer :: nproc, my_rank, nw, spin, band, ib, ik_ibz, cnt, idat, ierr, bcorr, time_opt 4549 integer :: ii, jj, ief, ihf, bmin_, bmax_ 4550 real(dp),parameter :: max_occ1 = one 4551 real(dp) :: emax, emin, wtk, max_occ 4552 real(dp) :: cpu, wall, gflops 4553 logical :: check_erange 4554 character(len=500) :: msg 4555 type(htetra_t) :: tetra 4556 !arrays 4557 real(dp) :: eminmax_spin(2,ebands%nsppol), vsum(3), tsum(3,3) 4558 real(dp),allocatable :: wme0(:),tmp_eigen(:), weights(:,:) 4559 4560 ! ********************************************************************* 4561 4562 call cwtime(cpu, wall, gflops, "start") 4563 4564 nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm) 4565 4566 edos%nkibz = ebands%nkpt; edos%nsppol = ebands%nsppol; edos%nspinor = ebands%nspinor 4567 edos%intmeth = intmeth 4568 edos%nelect = ebands%nelect 4569 if (ebands%nkpt == 1) then 4570 ABI_COMMENT("Cannot use tetrahedra for e-DOS when nkpt == 1. Switching to gaussian method") 4571 edos%intmeth = 1 4572 end if 4573 4574 edos%broad = broad; edos%step = step 4575 4576 ! Define band range. 4577 bmin_ = 1; bmax_ = ebands%mband 4578 if (present(brange)) then 4579 bmin_ = brange(1); bmax_ = brange(2) 4580 end if 4581 4582 ABI_CHECK_IRANGE(bmin_, 1, ebands%mband, "Wrong bmin:") 4583 ABI_CHECK_IRANGE(bmax_, bmin_, ebands%mband, "Wrong bmax:") 4584 ABI_CHECK_IRANGE(bsize, 1, ebands%mband, "Wrong bsize:") 4585 4586 if (present(erange)) then 4587 ! use optional args if provided. 4588 emin = erange(1) 4589 emax = erange(2) 4590 check_erange = .True. 4591 else 4592 ! Compute the linear mesh so that it encloses all bands. 4593 eminmax_spin = ebands_get_minmax(ebands, "eig") 4594 emin = minval(eminmax_spin(1, :)); emin = emin - 0.1_dp * abs(emin) 4595 emax = maxval(eminmax_spin(2, :)); emax = emax + 0.1_dp * abs(emax) 4596 check_erange = .False. 4597 end if 4598 4599 nw = nint((emax - emin) / edos%step) + 1 4600 edos%nw = nw 4601 4602 ABI_MALLOC(edos%mesh, (nw)) 4603 edos%mesh = arth(emin, edos%step, nw) 4604 4605 ABI_CALLOC(edos%gef, (0:edos%nsppol)) 4606 ABI_CALLOC(edos%ghf, (0:edos%nsppol)) 4607 ABI_CALLOC(edos%dos, (nw, 0:edos%nsppol)) 4608 ABI_CALLOC(edos%idos, (nw, 0:edos%nsppol)) 4609 4610 ! Allocate output arrays depending on input. 4611 if (nvals > 0) then 4612 ABI_CALLOC(out_valsdos, (nw, 2, nvals, ebands%nsppol)) 4613 endif 4614 if (nvecs > 0) then 4615 ABI_CALLOC(out_vecsdos, (nw, 2, 3, nvecs, ebands%nsppol)) 4616 end if 4617 if (ntens > 0) then 4618 ABI_CALLOC(out_tensdos, (nw, 2, 3, 3, ntens, ebands%nsppol)) 4619 end if 4620 4621 time_opt = 0 ! This to preserve the previous behaviour in which TR was not used. 4622 4623 !call wrtout(std_out, " Computing DOS weighted by matrix elements.") 4624 select case (intmeth) 4625 case (1) 4626 ! Gaussian 4627 ABI_MALLOC(wme0, (nw)) 4628 cnt = 0 4629 do spin=1,ebands%nsppol 4630 do ik_ibz=1,ebands%nkpt 4631 cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle ! MPI parallelism 4632 wtk = ebands%wtk(ik_ibz) 4633 do band=bmin_,bmax_ 4634 ib = band - bmin_ + 1 4635 4636 if (check_erange) then 4637 if (ebands%eig(band, ik_ibz, spin) < emin - five * broad) cycle 4638 if (ebands%eig(band, ik_ibz, spin) > emax + five * broad) cycle 4639 end if 4640 4641 wme0 = edos%mesh - ebands%eig(band, ik_ibz, spin) 4642 wme0 = gaussian(wme0, broad) * wtk 4643 edos%dos(:,spin) = edos%dos(:,spin) + wme0(:) 4644 4645 ! scalars 4646 do idat=1,nvals 4647 out_valsdos(:, 1, idat, spin) = out_valsdos(:,1, idat, spin) + wme0(:) * bks_vals(idat, ib, ik_ibz, spin) 4648 ! FIXME: This is quite inefficient! Integration should be performed outside! 4649 call simpson_int(nw, step, out_valsdos(:,1, idat, spin), out_valsdos(:,2,idat,spin)) 4650 end do 4651 4652 ! vectors 4653 do idat=1,nvecs 4654 ! get components, symmetrize and accumulate. 4655 vsum = cryst%symmetrize_cart_vec3(bks_vecs(:, idat, ib, ik_ibz, spin), time_opt) 4656 do ii=1,3 4657 out_vecsdos(:, 1, ii, idat, spin) = out_vecsdos(:, 1, ii, idat, spin) + wme0(:) * vsum(ii) 4658 call simpson_int(nw, step, out_vecsdos(:,1,ii,idat,spin), out_vecsdos(:,2,ii,idat,spin)) 4659 end do 4660 end do 4661 4662 ! tensor 4663 do idat=1,ntens 4664 ! get components, symmetrize and accumulate. 4665 tsum = cryst%symmetrize_cart_tens33(bks_tens(:, :, idat, ib, ik_ibz, spin), time_opt) 4666 do ii=1,3 4667 do jj=1,3 4668 out_tensdos(:,1,jj,ii,idat,spin) = out_tensdos(:,1,jj,ii,idat,spin) + wme0(:) * tsum(jj,ii) 4669 call simpson_int(nw, step, out_tensdos(:,1,jj,ii,idat,spin), out_tensdos(:,2,jj,ii,idat,spin)) 4670 end do 4671 end do 4672 end do 4673 4674 end do !band 4675 end do !ik_ibz 4676 end do !spin 4677 4678 ABI_FREE(wme0) 4679 call xmpi_sum(edos%dos, comm, ierr) 4680 if (nvals > 0) call xmpi_sum(out_valsdos, comm, ierr) 4681 if (nvecs > 0) call xmpi_sum(out_vecsdos, comm, ierr) 4682 if (ntens > 0) call xmpi_sum(out_tensdos, comm, ierr) 4683 4684 case (2, -2) 4685 ! Consistency test 4686 ABI_CHECK(all(ebands%nband == ebands%nband(1)), 'For tetrahedra, nband(:) must be constant') 4687 4688 ! Build tetra object. 4689 tetra = tetra_from_kptrlatt(cryst, ebands%kptopt, ebands%kptrlatt, & 4690 ebands%nshiftk, ebands%shiftk, ebands%nkpt, ebands%kptns, comm, msg, ierr) 4691 ABI_CHECK(ierr == 0, msg) 4692 4693 ! For each spin and band, interpolate over kpoints, 4694 ! calculate integration weights and DOS contribution. 4695 ABI_MALLOC(tmp_eigen, (ebands%nkpt)) 4696 ABI_MALLOC(weights, (nw, 2)) 4697 4698 ! Blochl's corrections? 4699 bcorr = 0; if (intmeth == -2) bcorr = 1 4700 4701 cnt = 0 4702 do spin=1,ebands%nsppol 4703 do band=bmin_,bmax_ 4704 ! For each band get its contribution 4705 tmp_eigen = ebands%eig(band,:,spin) 4706 ib = band - bmin_ + 1 4707 4708 if (check_erange) then 4709 if (all(tmp_eigen < emin)) cycle 4710 if (all(tmp_eigen > emax)) cycle 4711 end if 4712 4713 do ik_ibz=1,ebands%nkpt 4714 cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle ! MPI parallelism 4715 4716 call tetra%get_onewk(ik_ibz, bcorr, nw, ebands%nkpt, tmp_eigen, emin, emax, max_occ1, weights) 4717 weights = weights * ebands%wtk(ik_ibz) 4718 4719 ! Compute DOS and IDOS 4720 edos%dos(:,spin) = edos%dos(:,spin) + weights(:, 1) 4721 edos%idos(:,spin) = edos%idos(:,spin) + weights(:, 2) 4722 4723 ! scalar 4724 !$OMP PARALLEL DO 4725 do idat=1,nvals 4726 out_valsdos(:, :, idat, spin) = out_valsdos(:, :, idat, spin) + weights(:, :) * bks_vals(idat, ib, ik_ibz, spin) 4727 end do 4728 4729 ! vector 4730 !$OMP PARALLEL DO PRIVATE(vsum) 4731 do idat=1,nvecs 4732 ! get components, symmetrize and accumulate. 4733 vsum = cryst%symmetrize_cart_vec3(bks_vecs(:, idat, ib, ik_ibz, spin), time_opt) 4734 do ii=1,3 4735 out_vecsdos(:, :, ii, idat, spin) = out_vecsdos(:, :, ii, idat, spin) + weights(:, :) * vsum(ii) 4736 end do 4737 end do 4738 4739 ! tensor 4740 !$OMP PARALLEL DO PRIVATE(tsum) 4741 do idat=1,ntens 4742 ! get components, symmetrize and accumulate. 4743 tsum = cryst%symmetrize_cart_tens33(bks_tens(:, :, idat, ib, ik_ibz, spin), time_opt) 4744 do ii=1,3 4745 do jj=1,3 4746 out_tensdos(:, :, jj, ii, idat, spin) = out_tensdos(:, :, jj, ii, idat, spin) + weights(:, :) * tsum(jj,ii) 4747 end do 4748 end do 4749 end do 4750 4751 end do ! ik_ibz 4752 end do ! band 4753 end do ! spin 4754 4755 ! Free memory 4756 ABI_FREE(weights) 4757 ABI_FREE(tmp_eigen) 4758 call tetra%free() 4759 4760 call xmpi_sum(edos%dos, comm, ierr) 4761 call xmpi_sum(edos%idos, comm, ierr) 4762 if (nvals > 0) call xmpi_sum(out_valsdos, comm, ierr) 4763 if (nvecs > 0) call xmpi_sum(out_vecsdos, comm, ierr) 4764 if (ntens > 0) call xmpi_sum(out_tensdos, comm, ierr) 4765 4766 case default 4767 ABI_ERROR(sjoin("Wrong integration method:", itoa(intmeth))) 4768 end select 4769 4770 ! Compute total DOS and IDOS 4771 max_occ = two / (ebands%nspinor * ebands%nsppol) 4772 edos%dos(:, 0) = max_occ * sum(edos%dos(:,1:), dim=2) 4773 4774 if (intmeth == 1) then 4775 do spin=1,edos%nsppol 4776 call simpson_int(nw, edos%step, edos%dos(:,spin), edos%idos(:,spin)) 4777 end do 4778 end if 4779 edos%idos(:, 0) = max_occ * sum(edos%idos(:,1:), dim=2) 4780 4781 ! Use bisection to find the Fermi level. 4782 ! Warning: this code assumes idos[i+1] >= idos[i]. This condition may not be 4783 ! fullfilled if we use tetra and this is the reason why we have filtered the DOS. 4784 if (ebands%occopt == 9) then 4785 ihf = bisect(edos%idos(:,0), ebands%nelect-ebands%nh_qFD) 4786 ief = bisect(edos%idos(:,0), ebands%nelect+ebands%ne_qFD) 4787 else 4788 ief = bisect(edos%idos(:,0), ebands%nelect) 4789 ihf = ief 4790 end if 4791 4792 ! Handle out of range condition. 4793 if (ief == 0 .or. ief == nw) then 4794 write(msg,"(a, f14.2, 4a)") & 4795 "Bisection could not find an initial guess for the Fermi level with nelect: ",ebands%nelect, ch10, & 4796 "Possible reasons: not enough bands for DOS or wrong number of electrons.", ch10, & 4797 "Returning from ebands_get_edos_matrix_elements without setting edos%ief !" 4798 ABI_WARNING(msg) 4799 return 4800 end if 4801 4802 if (ihf == 0 .or. ihf == nw) then 4803 write(msg,"(3a)")& 4804 "Bisection could not find an initial guess for the holes Fermi level!",ch10,& 4805 "Possible reasons: not enough bands or wrong number of holes" 4806 ABI_WARNING(msg) 4807 return 4808 end if 4809 4810 ! TODO: Use linear interpolation to find an improved estimate of the Fermi level? 4811 edos%ief = ief 4812 edos%ihf = ihf 4813 do spin=0,edos%nsppol 4814 edos%gef(spin) = edos%dos(ief,spin) 4815 edos%ghf(spin) = edos%dos(ihf,spin) 4816 end do 4817 4818 call cwtime_report(" ebands_get_edos_matrix_elements", cpu, wall, gflops) 4819 4820 end function ebands_get_edos_matrix_elements
m_ebands/ebands_get_erange [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_get_erange
FUNCTION
Compute the minimum and maximum energy enclosing a list of states specified by k-points and band indices.
INPUTS
ebands<ebands_t>=The object describing the band structure. nkpts=Number of k-points kpoints(3,nkpts)=K-points band_block(2,nkpts)=Gives for each k-points, the initial and the final band index to include.
OUTPUT
emin,emax=min and max energy
SOURCE
2005 subroutine ebands_get_erange(ebands, nkpts, kpoints, band_block, emin, emax) 2006 2007 !Arguments ------------------------------------ 2008 !scalars 2009 integer,intent(in) :: nkpts 2010 real(dp),intent(out) :: emin,emax 2011 class(ebands_t),intent(in) :: ebands 2012 !arrays 2013 integer,intent(in) :: band_block(2,nkpts) 2014 real(dp),intent(in) :: kpoints(3,nkpts) 2015 2016 !Local variables------------------------------- 2017 !scalars 2018 integer :: spin,ik,ikpt,cnt 2019 type(krank_t) :: krank 2020 2021 ! ************************************************************************* 2022 2023 krank = krank_new(ebands%nkpt, ebands%kptns) 2024 emin = huge(one); emax = -huge(one); cnt = 0 2025 2026 do spin=1,ebands%nsppol 2027 do ik=1,nkpts 2028 ikpt = krank%get_index(kpoints(:,ik)) 2029 if (ikpt == -1) then 2030 ABI_WARNING(sjoin("Cannot find k-point:", ktoa(kpoints(:,ik)))) 2031 cycle 2032 end if 2033 if (.not. (band_block(1,ik) >= 1 .and. band_block(2,ik) <= ebands%mband)) cycle 2034 cnt = cnt + 1 2035 emin = min(emin, minval(ebands%eig(band_block(1,ik):band_block(2,ik), ikpt, spin))) 2036 emax = max(emax, maxval(ebands%eig(band_block(1,ik):band_block(2,ik), ikpt, spin))) 2037 end do 2038 end do 2039 2040 call krank%free() 2041 2042 ! This can happen if wrong input. 2043 if (cnt == 0) then 2044 ABI_WARNING("None of the k-points/bands provided was found in ebands%") 2045 emin = minval(ebands%eig); emax = maxval(ebands%eig) 2046 end if 2047 2048 end subroutine ebands_get_erange
m_ebands/ebands_get_gaps [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_get_gaps
FUNCTION
Returns a gaps_t object with info on the fundamental and direct gap.
INPUTS
ebands<ebands_t>=Info on the band structure, the smearing technique and the physical temperature used.
OUTPUT
ierr=Return code (!=0 signals failure) gaps<gaps_t>=object with info on the gaps (caller is responsible for freeing the object).
SOURCE
436 type(gaps_t) function ebands_get_gaps(ebands, ierr) result(gaps) 437 438 !Arguments ------------------------------------ 439 !scalars 440 class(ebands_t),target,intent(in) :: ebands 441 integer,intent(out) :: ierr 442 443 !Local variables------------------------------- 444 !scalars 445 integer,parameter :: occopt3 = 3, prtvol0 = 0 446 real(dp),parameter :: spinmagntarget_ = -99.99_dp 447 real(dp) :: tsmear 448 type(ebands_t) :: tmp_ebands 449 !character(len=500) :: msg 450 451 ! ********************************************************************* 452 453 gaps = get_gaps_(ebands, ierr) 454 455 if (ierr /= 0) then 456 ! get_gaps_ will fail if we have a real metal/semimetal 457 ! but it's also possible to have a false negative if the input ebands represents a: 458 ! 459 ! 1) highly degenerate doped semiconductor with the Fermi level in the bands. 460 ! 2) Small gap semiconductor at relatively high T. 461 ! 462 ! Here I try to compute the gaps of an intrinsic semiconductor at low T with Fermi-Dirac. 463 ! This might still fail though and the caller should handle that. 464 call gaps%free() 465 call ebands_copy(ebands, tmp_ebands) 466 tsmear = 0.01_dp * eV_Ha 467 call ebands_set_scheme(tmp_ebands, occopt3, tsmear, spinmagntarget_, prtvol0, update_occ=.False.) 468 ! Remove extrael to go back to intrinsic system 469 if (ebands%extrael /= zero) tmp_ebands%nelect = ebands%nelect - ebands%extrael 470 !if (ebands%cellcharge /= zero) tmp_ebands%nelect = ebands%nelect + ebands%cellcharge 471 call ebands_update_occ(tmp_ebands, spinmagntarget_) 472 473 ! Try to compute gaps the again with new Fermi level at FD T = tsmear computed from update_occ. 474 ! Return ierr 475 gaps = get_gaps_(tmp_ebands, ierr) 476 call ebands_free(tmp_ebands) 477 end if 478 479 end function ebands_get_gaps
m_ebands/ebands_get_jdos [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_get_jdos
FUNCTION
Compute the joint density of states.
INPUTS
ebands<ebands_t>=Band structure object. cryst<cryst_t>=Info on the crystalline structure. intmeth= 1 for gaussian, 2 or -2 for tetrahedra (-2 if Blochl corrections must be included). step=Step on the linear mesh in Ha. If <0, the routine will use the mean of the energy level spacing broad=Gaussian broadening, If <0, the routine will use a default value for the broadening computed from the mean of the energy level spacing. No meaning if tetra method comm=MPI communicator
OUTPUT
SOURCE
4846 type(jdos_t) function ebands_get_jdos(ebands, cryst, intmeth, step, broad, comm, ierr) result (jdos) 4847 4848 !Arguments ------------------------------------ 4849 !scalars 4850 integer,intent(in) :: intmeth,comm 4851 integer,intent(out) :: ierr 4852 real(dp),intent(in) :: step,broad 4853 class(ebands_t),intent(in) :: ebands 4854 type(crystal_t),intent(in) :: cryst 4855 4856 !Local variables------------------------------- 4857 !scalars 4858 integer :: ik_ibz,ibc,ibv,spin,nw,nband_k,nbv,nproc,my_rank,cnt,mpierr,bcorr !iw, unt, 4859 real(dp) :: wtk,wmax 4860 type(htetra_t) :: tetra 4861 character(len=500) :: msg 4862 !character(len=fnlen) :: path 4863 !arrays 4864 integer :: val_idx(ebands%nkpt,ebands%nsppol) 4865 real(dp) :: eminmax(2,ebands%nsppol) 4866 real(dp),allocatable :: cvmw(:),wdt(:,:) 4867 4868 ! ********************************************************************* 4869 4870 ierr = 0 4871 nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm) 4872 4873 jdos%nsppol = ebands%nsppol 4874 jdos%nkibz = ebands%nkpt 4875 4876 ! Find the valence band index for each k and spin. 4877 val_idx = ebands_get_valence_idx(ebands) 4878 4879 do spin=1,ebands%nsppol 4880 if (any(val_idx(:,spin) /= val_idx(1,spin))) then 4881 write(msg,'(a,i0,a)')& 4882 'Trying to compute JDOS with a metallic band structure for spin: ',spin,& 4883 'Assuming you know what you are doing, continuing anyway! ' 4884 ABI_COMMENT(msg) 4885 end if 4886 end do 4887 4888 ! Compute the linear mesh so that it encloses all bands. 4889 !if (.not. present(mesh)) then 4890 eminmax = ebands_get_minmax(ebands, "eig") 4891 wmax = maxval(eminmax(2,:) - eminmax(1,:)) 4892 nw = nint(wmax/step) + 1 4893 ABI_MALLOC(jdos%mesh, (nw)) 4894 jdos%mesh = arth(zero, step, nw) 4895 4896 jdos%nw = nw 4897 jdos%intmeth = intmeth 4898 jdos%broad = broad 4899 4900 !if (ebands%nkpt == 1) then 4901 ! ABI_COMMENT("Cannot use tetrahedra for e-DOS when nkpt == 1. Switching to gaussian method") 4902 ! jdos%intmeth = 1 4903 !end if 4904 4905 ABI_CALLOC(jdos%values, (nw, ebands%nsppol)) 4906 4907 select case (intmeth) 4908 case (1) 4909 ! Gaussian 4910 ABI_MALLOC(cvmw, (nw)) 4911 4912 cnt = 0 4913 do spin=1,ebands%nsppol 4914 do ik_ibz=1,ebands%nkpt 4915 wtk = ebands%wtk(ik_ibz) 4916 nband_k = ebands%nband(ik_ibz + (spin-1)*ebands%nkpt) 4917 nbv = val_idx(ik_ibz, spin) 4918 4919 do ibv=1,nbv 4920 cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle 4921 do ibc=nbv+1,nband_k 4922 cvmw = ebands%eig(ibc,ik_ibz,spin) - ebands%eig(ibv,ik_ibz,spin) - jdos%mesh 4923 jdos%values(:, spin) = jdos%values(:, spin) + wtk * gaussian(cvmw, broad) 4924 end do 4925 end do 4926 4927 end do ! ik_ibz 4928 end do ! spin 4929 4930 ABI_FREE(cvmw) 4931 call xmpi_sum(jdos%values, comm, mpierr) 4932 4933 case (2, -2) 4934 ! Tetrahedron method 4935 if (any(ebands%nband /= ebands%nband(1)) ) then 4936 ABI_WARNING('For tetrahedra, nband(:) must be constant') 4937 ierr = ierr + 1 4938 end if 4939 if (ierr/=0) return 4940 4941 tetra = tetra_from_kptrlatt(cryst, ebands%kptopt, ebands%kptrlatt, & 4942 ebands%nshiftk, ebands%shiftk, ebands%nkpt, ebands%kptns, comm, msg, ierr) 4943 if (ierr /= 0) then 4944 call tetra%free(); return 4945 end if 4946 4947 ! For each spin and band, interpolate over kpoints, 4948 ! calculate integration weights and DOS contribution. 4949 ABI_MALLOC(cvmw, (jdos%nkibz)) 4950 ABI_MALLOC(wdt, (nw, 2)) 4951 4952 bcorr = 0; if (intmeth == -2) bcorr = 1 4953 cnt = 0 4954 do spin=1,ebands%nsppol 4955 nbv = val_idx(1, spin) 4956 do ibv=1,nbv 4957 do ibc=nbv+1,ebands%mband 4958 ! For each (c, v) get its contribution 4959 cvmw = ebands%eig(ibc,:,spin) - ebands%eig(ibv,:,spin) 4960 do ik_ibz=1,ebands%nkpt 4961 cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle ! mpi-parallelism 4962 4963 ! Calculate integration weights at each irred k-point (Blochl et al PRB 49 16223 [[cite:Bloechl1994a]]) 4964 call tetra%get_onewk(ik_ibz, bcorr, nw, ebands%nkpt, cvmw, jdos%mesh(0), jdos%mesh(nw), one, wdt) 4965 jdos%values(:,spin) = jdos%values(:,spin) + wdt(:, 1) * ebands%wtk(ik_ibz) 4966 end do 4967 end do ! ibc 4968 end do ! ibv 4969 end do ! spin 4970 4971 call xmpi_sum(jdos%values, comm, mpierr) 4972 4973 ! Free memory 4974 ABI_FREE(wdt) 4975 ABI_FREE(cvmw) 4976 call tetra%free() 4977 4978 case default 4979 ABI_ERROR(sjoin("Wrong integration method:", itoa(intmeth))) 4980 end select 4981 4982 if (ebands%nsppol == 1) then 4983 jdos%values(0,:) = two * jdos%values(1,:) 4984 else 4985 jdos%values(0,:) = sum(jdos%values(1:2, :), dim=2) 4986 end if 4987 4988 ! Write data. 4989 !if (my_rank == 0) then 4990 ! path = "jdos_gauss.data"; if (intmeth == 2) path = "jdos_tetra.data" 4991 ! if (open_file(path, msg, newunit=unt, form="formatted", action="write") /= 0) then 4992 ! ABI_ERROR(msg) 4993 ! end if 4994 ! do iw=1,nw 4995 ! write(unt,*)jdos%mesh(iw),(jdos(iw,spin), spin=1,ebands%nsppol) 4996 ! end do 4997 ! close(unt) 4998 !end if 4999 5000 end function ebands_get_jdos
m_ebands/ebands_get_minmax [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_get_minmax
FUNCTION
Report the min and max value over k-points and bands of (eig|occ|doccde) for each spin. Cannot use F90 array syntax due to the internal storage used in abinit.
INPUTS
ebands<ebands_t>=The object describing the band structure. arr_name=The name of the array whose min and Max value has to be calculated. Possible values: 'occ', 'eig' 'doccde'
OUTPUT
minmax(2,ebands%nsppol)=For each spin the min and max value of the quantity specified by "arr_name"
SOURCE
2117 function ebands_get_minmax(ebands, arr_name) result(minmax) 2118 2119 !Arguments ------------------------------------ 2120 !scalars 2121 class(ebands_t),target,intent(in) :: ebands 2122 character(len=*),intent(in) :: arr_name 2123 !arrays 2124 real(dp) :: minmax(2,ebands%nsppol) 2125 2126 !Local variables------------------------------- 2127 !scalars 2128 integer :: band,ikpt,spin,nband_k 2129 real(dp) :: datum 2130 !arrays 2131 real(dp), ABI_CONTIGUOUS pointer :: rdata(:,:,:) 2132 2133 ! ************************************************************************* 2134 2135 select case (tolower(arr_name)) 2136 case ('occ') 2137 rdata => ebands%occ 2138 case ('eig') 2139 rdata => ebands%eig 2140 case ('doccde') 2141 rdata => ebands%doccde 2142 case default 2143 ABI_BUG(sjoin('Wrong arr_name:', arr_name)) 2144 end select 2145 2146 minmax(1,:)=greatest_real 2147 minmax(2,:)=smallest_real 2148 2149 do spin=1,ebands%nsppol 2150 do ikpt=1,ebands%nkpt 2151 nband_k=ebands%nband(ikpt+(spin-1)*ebands%nkpt) 2152 do band=1,nband_k 2153 datum=rdata(band,ikpt,spin) 2154 minmax(1,spin)=MIN(minmax(1,spin),datum) 2155 minmax(2,spin)=MAX(minmax(2,spin),datum) 2156 end do 2157 end do 2158 end do 2159 2160 end function ebands_get_minmax
m_ebands/ebands_get_muT_with_fd [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_get_muT_with_fd
FUNCTION
Compute the Fermi level for different temperatures using Fermi-Dirac occupation function (physical T) Use ebands%nelect provided in input. Does not change input ebands.
INPUTS
OUTPUT
SOURCE
2669 subroutine ebands_get_muT_with_fd(self, ntemp, kTmesh, spinmagntarget, prtvol, mu_e, comm) 2670 2671 !Arguments ------------------------------------ 2672 !scalars 2673 class(ebands_t),intent(in) :: self 2674 integer,intent(in) :: ntemp, prtvol, comm 2675 real(dp),intent(in) :: spinmagntarget 2676 real(dp),intent(in) :: kTmesh(ntemp) 2677 real(dp),intent(out) :: mu_e(ntemp) 2678 2679 !Local variables------------------------------- 2680 !scalars 2681 integer,parameter :: occopt3 = 3 2682 integer :: ierr, it, nprocs, my_rank 2683 real(dp) :: nelect, cpu, wall, gflops 2684 type(ebands_t) :: tmp_ebands 2685 character(len=500) :: msg 2686 2687 ! ************************************************************************* 2688 2689 my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm) 2690 call cwtime(cpu, wall, gflops, "start") 2691 2692 call ebands_copy(self, tmp_ebands) 2693 2694 mu_e = zero 2695 2696 do it=1,ntemp 2697 if (mod(it, nprocs) /= my_rank) cycle ! MPI parallelism inside comm. 2698 2699 ! Use Fermi-Dirac occopt 2700 call ebands_set_scheme(tmp_ebands, occopt3, kTmesh(it), spinmagntarget, prtvol) 2701 mu_e(it) = tmp_ebands%fermie 2702 ! 2703 ! Check that the total number of electrons is correct 2704 ! This is to trigger problems as the routines that calculate the occupations in ebands_set_extrael 2705 ! are different from the occ_fd that will be used in the rest of the code. 2706 nelect = ebands_calc_nelect(tmp_ebands, kTmesh(it), mu_e(it)) 2707 2708 if (abs(nelect - self%nelect) > tol6) then 2709 ! For T = 0 the number of occupied states goes in discrete steps (according to the k-point sampling) 2710 ! for finite doping its hard to find nelect that exactly matches self%nelect. 2711 ! in this case we print a warning 2712 write(msg,'(2(a,f10.6,a), f10.6)') & 2713 'Calculated number of electrons nelect : ',nelect, ch10, & 2714 ' does not correspond with ebands%nelect: ',tmp_ebands%nelect,' for kT: ', kTmesh(it) 2715 2716 if (kTmesh(it) == zero) then 2717 ABI_WARNING(msg) 2718 else 2719 ABI_ERROR(msg) 2720 end if 2721 end if 2722 end do ! it 2723 2724 call ebands_free(tmp_ebands) 2725 call xmpi_sum(mu_e, comm, ierr) 2726 2727 call cwtime_report(" ebands_get_muT_with_fd", cpu, wall, gflops, end_str=ch10) 2728 2729 end subroutine ebands_get_muT_with_fd
m_ebands/ebands_get_occupied [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_get_occupied
FUNCTION
For each k-point and spin polarisation, report the band index after which the occupation numbers are less than tol_occ.
INPUTS
ebands<ebands_t>=The object describing the band structure. tol_occ[Optional]=Tollerance on the occupation factors.
OUTPUT
NOTES
We assume that the occupation factors monotonically decrease as a function of energy. This is not always true for every smearing technique implemented in Abinit. CP: this also not true for occopt 9
SOURCE
1799 pure function ebands_get_occupied(ebands, tol_occ) result(occ_idx) 1800 1801 !Arguments ------------------------------------ 1802 !scalars 1803 real(dp),optional,intent(in) :: tol_occ 1804 class(ebands_t),intent(in) :: ebands 1805 !arrays 1806 integer :: occ_idx(ebands%nkpt,ebands%nsppol) 1807 1808 !Local variables------------------------------- 1809 integer :: band,ikpt,spin,idx,nband_k 1810 real(dp) :: tol_ 1811 1812 ! ************************************************************************* 1813 1814 tol_=tol8; if (PRESENT(tol_occ)) tol_=tol_occ 1815 1816 do spin=1,ebands%nsppol 1817 do ikpt=1,ebands%nkpt 1818 nband_k = ebands%nband(ikpt+(spin-1)*ebands%nkpt) 1819 1820 idx=0 1821 do band=1,nband_k 1822 if (ebands%occ(band,ikpt,spin) < ABS(tol_)) then 1823 idx=band; EXIT 1824 end if 1825 end do 1826 occ_idx(ikpt,spin)=idx-1 1827 if (idx==1) occ_idx(ikpt,spin)=idx 1828 if (idx==0) occ_idx(ikpt,spin)=nband_k 1829 1830 end do 1831 end do 1832 1833 end function ebands_get_occupied
m_ebands/ebands_get_valence_idx [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_get_valence_idx
FUNCTION
For each k-point and spin polarisation, report: 1) the index of the valence in case of semiconductors at T = 0 2) (band_k - 1) where band_k is the first band whose energy is > Fermi energy + told_fermi using the value of the Fermi level.
INPUTS
ebands<ebands_t>=The object describing the band structure. tol_fermi[optional]
OUTPUT
SOURCE
1526 pure function ebands_get_valence_idx(ebands, tol_fermi) result(val_idx) 1527 1528 !Arguments ------------------------------------ 1529 !scalars 1530 real(dp),optional,intent(in) :: tol_fermi 1531 class(ebands_t),intent(in) :: ebands 1532 !arrays 1533 integer :: val_idx(ebands%nkpt,ebands%nsppol) 1534 1535 !Local variables------------------------------- 1536 integer :: band,ikpt,spin,idx,nband_k 1537 real(dp) :: tol_ 1538 1539 ! ************************************************************************* 1540 1541 tol_ = tol6; if (present(tol_fermi)) tol_ = tol_fermi 1542 1543 do spin=1,ebands%nsppol 1544 do ikpt=1,ebands%nkpt 1545 if (ebands%occopt == 9) then 1546 val_idx(ikpt,spin) = ebands%ivalence 1547 else 1548 nband_k = ebands%nband(ikpt+(spin-1)*ebands%nkpt) 1549 idx = 0 1550 do band=1,nband_k 1551 if (ebands%eig(band,ikpt,spin) > ebands%fermie + abs(tol_)) then 1552 idx = band; exit 1553 end if 1554 end do 1555 val_idx(ikpt,spin) = idx - 1 1556 if (idx == 1) val_idx(ikpt, spin) = idx 1557 if (idx == 0) val_idx(ikpt, spin) = nband_k 1558 end if 1559 end do 1560 end do 1561 1562 end function ebands_get_valence_idx
m_ebands/ebands_has_metal_scheme [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_metallic_scheme
FUNCTION
Returns .TRUE. if metallic occupation scheme is used. Note that this does not imply that the system is metallic.
INPUTS
ebands<ebands_t>=The ebands_t datatype
SOURCE
2178 pure logical function ebands_has_metal_scheme(ebands) result(ans) 2179 2180 !Arguments ------------------------------------ 2181 class(ebands_t),intent(in) :: ebands 2182 2183 ! ************************************************************************* 2184 2185 ans = (any(ebands%occopt == [3, 4, 5, 6, 7, 8, 9])) 2186 2187 end function ebands_has_metal_scheme
m_ebands/ebands_init [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_init
FUNCTION
This subroutine initializes the ebands_t structured datatype
INPUTS
bantot=total number of bands (=sum(nband(:)) doccde(bantot)=derivative of the occupation numbers with respect to the energy (Ha) eig(bantot)=eigenvalues (hartree) istwfk(nkpt)=parameter that describes the storage of wfs. ivalence = index of the valence band separating thermalized excited holes from excited thermalized excited electrons kptns(3,nkpt)=k points in terms of recip primitive translations nband(nkpt*nsppol)=number of bands nelect=Number of electrons. ne_qFD, nh_qFD= number of electrons (holes resp.) excited in the bands above band index ivalence + 1 (below ivalence resp.) nkpt=number of k points npwarr(nkpt)=number of planewaves at each k point nsppol=1 for unpolarized, 2 for spin-polarized nspinor=Number of spinor components occopt=Occupation options (see input variable) occ(bantot)=occupation numbers tphysel=Physical temperature (input variable) tsmear=Temperature of smearing. wtk(nkpt)=weight assigned to each k point cellcharge=Additional charge added to the unit cell (input variable). kptopt=Option for k-point generation (see input variable) kptrlatt_orig=Original value of kptrlatt given in input nshiftk_orig=Original number of shifts given in input shiftk_orig(3,nshiftk_orig)=Original set of shifts given in input kptrlatt=Value of kptrlatt after inkpts nshiftk=Number of shifts after inkpts shiftk(3,nshiftk)=Set of shifts after inkpts.
OUTPUT
ebands<ebands_t>=the ebands_t datatype
SOURCE
799 subroutine ebands_init(bantot, ebands, nelect, ne_qFD, nh_qFD, ivalence, doccde, eig, istwfk, kptns, & 800 nband, nkpt, npwarr, nsppol, nspinor, tphysel, tsmear, occopt, occ, wtk, & 801 cellcharge, kptopt, kptrlatt_orig, nshiftk_orig, shiftk_orig, kptrlatt, nshiftk, shiftk) 802 803 !Arguments ------------------------------------ 804 !scalars 805 integer,intent(in) :: bantot,nkpt,nsppol,nspinor,occopt,ivalence 806 real(dp),intent(in) :: nelect,ne_qFD,nh_qFD,tphysel,tsmear 807 type(ebands_t),intent(out) :: ebands 808 !arrays 809 integer,intent(in) :: istwfk(nkpt),nband(nkpt*nsppol),npwarr(nkpt) 810 real(dp),intent(in) :: doccde(bantot),eig(bantot),kptns(3,nkpt),occ(bantot) 811 real(dp),intent(in) :: wtk(nkpt) 812 integer,intent(in) :: kptopt, nshiftk_orig, nshiftk 813 real(dp),intent(in) :: cellcharge 814 integer,intent(in) :: kptrlatt_orig(3,3),kptrlatt(3,3) 815 real(dp),intent(in) :: shiftk_orig(3,nshiftk_orig),shiftk(3,nshiftk) 816 817 ! ************************************************************************* 818 819 ! Copy the scalars 820 ! MG TODO here there is a inconsistency in the way occ are treated in the header 821 ! (only the states used, bantot. are saved, and the way occ. and energies 822 ! are passed to routines (mband,nkpt,nsppol). It might happen that bantot<mband*nktp*nsppol 823 ! this should not lead to problems since arrays are passed by reference 824 ! anyway the treatment of these arrays have to be rationalized 825 ebands%bantot = bantot 826 ebands%mband = MAXVAL(nband(1:nkpt*nsppol)) 827 ebands%nkpt = nkpt 828 ebands%nspinor= nspinor 829 ebands%nsppol = nsppol 830 ebands%occopt = occopt 831 832 ebands%entropy= zero 833 ebands%fermie = zero 834 ebands%fermih = zero 835 ebands%ivalence =ivalence 836 ebands%nelect = nelect 837 ebands%ne_qFD =ne_qFD 838 ebands%nh_qFD =nh_qFD 839 ebands%tphysel= tphysel 840 ebands%tsmear = tsmear 841 842 ! Allocate the components 843 ABI_MALLOC(ebands%nband, (nkpt*nsppol)) 844 ABI_MALLOC(ebands%istwfk, (nkpt)) 845 ABI_MALLOC(ebands%npwarr, (nkpt)) 846 ABI_MALLOC(ebands%kptns, (3, nkpt)) 847 848 ! Copy the arrays 849 ebands%nband(1:nkpt*nsppol) = nband(1:nkpt*nsppol) 850 ebands%istwfk(1:nkpt) = istwfk(1:nkpt) 851 ebands%npwarr(1:nkpt) = npwarr(1:nkpt) 852 ebands%kptns(1:3,1:nkpt) = kptns(1:3,1:nkpt) 853 854 ! In ebands, energies and occupations are stored in a matrix (mband,nkpt,nsppol). 855 ! put_eneocc_vect is used to reshape the values stored in vectorial form. 856 ABI_MALLOC(ebands%eig , (ebands%mband, nkpt, nsppol)) 857 ABI_MALLOC(ebands%occ , (ebands%mband, nkpt, nsppol)) 858 ABI_MALLOC(ebands%doccde, (ebands%mband, nkpt, nsppol)) 859 860 call put_eneocc_vect(ebands,'eig', eig ) 861 call put_eneocc_vect(ebands,'occ', occ ) 862 call put_eneocc_vect(ebands,'doccde',doccde) 863 864 ABI_MALLOC(ebands%wtk, (nkpt)) 865 ebands%wtk(1:nkpt) = wtk(1:nkpt) 866 867 ebands%kptopt = kptopt 868 ebands%nshiftk_orig = nshiftk_orig 869 ebands%nshiftk = nshiftk 870 ebands%cellcharge = cellcharge 871 ebands%kptrlatt_orig = kptrlatt_orig 872 ebands%kptrlatt = kptrlatt 873 874 call alloc_copy(shiftk_orig, ebands%shiftk_orig) 875 call alloc_copy(shiftk, ebands%shiftk) 876 877 end subroutine ebands_init
m_ebands/ebands_interp_kmesh [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_interp_kmesh
FUNCTION
Interpolate energies on a k-mesh.
INPUTS
ebands<ebands_t> = Object with input energies. cryst<crystal_t> = Crystalline structure. params(:): params(0): interpolation type. 1 for star-functions 2 for star-functions with group velocities if star-functions: params(2): Ratio between star functions and ab-initio k-points. params(3:4): Activate Fourier filtering (Eq 9 of PhysRevB.61.1639) if params(2) > tol6 params(3)=rcut, params(4) = rsigma intp_kptrlatt(3,3) = New k-mesh intp_nshiftk= Number of shifts in new k-mesh. intp_shiftk(3,intp_nshiftk) = Shifts in new k-mesh. band_block(2)=Initial and final band index. If [0,0], all bands are used This is a global variable i.e. all MPI procs must call the routine with the same value. comm=MPI communicator
OUTPUT
New ebands_t object with interpolated energies.
NOTES
Fermi level and occupation factors of the interpolate bands are not recomputed by this routine. This operation is delegated to the caller.
SOURCE
4208 type(ebands_t) function ebands_interp_kmesh(ebands, cryst, params, intp_kptrlatt, intp_nshiftk, intp_shiftk, & 4209 band_block, comm, out_prefix) result(new) 4210 4211 !Arguments ------------------------------------ 4212 !scalars 4213 integer,intent(in) :: intp_nshiftk,comm 4214 type(ebands_t),intent(in) :: ebands 4215 type(crystal_t),intent(in) :: cryst 4216 character(len=*),optional,intent(in) :: out_prefix 4217 !arrays 4218 integer,intent(in) :: intp_kptrlatt(3,3),band_block(2) 4219 real(dp),intent(in) :: params(:) 4220 real(dp),intent(in) :: intp_shiftk(3,intp_nshiftk) 4221 4222 !Local variables------------------------------- 4223 !scalars 4224 integer,parameter :: master = 0 4225 integer :: ik_ibz,spin,new_bantot,new_mband,cplex,itype,nb,ib 4226 integer :: nprocs,my_rank,cnt,ierr,band,new_nkbz,new_nkibz,new_nshiftk 4227 integer :: ncid 4228 type(skw_t) :: skw 4229 !arrays 4230 integer :: new_kptrlatt(3,3),my_bblock(2) 4231 integer,allocatable :: new_istwfk(:),new_nband(:,:),new_npwarr(:) 4232 real(dp),allocatable :: new_shiftk(:,:),new_kibz(:,:),new_kbz(:,:),new_wtk(:) 4233 real(dp),allocatable :: new_doccde(:),new_eig(:),new_occ(:) 4234 4235 ! ********************************************************************* 4236 4237 nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm) 4238 itype = nint(params(1)) 4239 my_bblock = band_block; if (all(band_block == 0)) my_bblock = [1, ebands%mband] 4240 nb = my_bblock(2) - my_bblock(1) + 1 4241 4242 ! Get ibz, new shifts and new kptrlatt. 4243 call kpts_ibz_from_kptrlatt(cryst, intp_kptrlatt, ebands%kptopt, intp_nshiftk, intp_shiftk, & 4244 new_nkibz, new_kibz, new_wtk, new_nkbz, new_kbz, new_kptrlatt=new_kptrlatt, new_shiftk=new_shiftk) 4245 new_nshiftk = size(new_shiftk, dim=2) 4246 4247 ! Initialize new ebands_t in new IBZ 4248 ABI_MALLOC(new_istwfk, (new_nkibz)) 4249 new_istwfk = 1 4250 !do ik_ibz=1,new_nkibz 4251 ! new_istwfk(ik_ibz) = set_istwfk(new%kptns(:, ik_ibz)) 4252 !end do 4253 ABI_MALLOC(new_nband, (new_nkibz, ebands%nsppol)) 4254 new_nband = nb 4255 ABI_MALLOC(new_npwarr, (new_nkibz)) 4256 new_npwarr = maxval(ebands%npwarr) 4257 new_bantot = sum(new_nband); new_mband = maxval(new_nband) 4258 ABI_CALLOC(new_doccde, (new_bantot)) 4259 ABI_CALLOC(new_eig, (new_bantot)) 4260 ABI_CALLOC(new_occ, (new_bantot)) 4261 4262 call ebands_init(new_bantot, new, ebands%nelect, ebands%ne_qFD,ebands%nh_qFD,ebands%ivalence,& 4263 new_doccde, new_eig, new_istwfk, new_kibz,& 4264 new_nband, new_nkibz, new_npwarr, ebands%nsppol, ebands%nspinor, ebands%tphysel, ebands%tsmear,& 4265 ebands%occopt, new_occ, new_wtk, & 4266 ebands%cellcharge, ebands%kptopt, intp_kptrlatt, intp_nshiftk, intp_shiftk, new_kptrlatt, new_nshiftk, new_shiftk) 4267 4268 ! Get fermi level from input ebands. 4269 new%fermie = ebands%fermie 4270 new%fermih = ebands%fermih 4271 4272 ABI_FREE(new_kibz) 4273 ABI_FREE(new_wtk) 4274 ABI_FREE(new_shiftk) 4275 ABI_FREE(new_kbz) 4276 ABI_FREE(new_istwfk) 4277 ABI_FREE(new_nband) 4278 ABI_FREE(new_npwarr) 4279 ABI_FREE(new_doccde) 4280 ABI_FREE(new_eig) 4281 ABI_FREE(new_occ) 4282 4283 ! Build SKW object for all bands. 4284 if (itype == 1 .or. itype == 2) then 4285 cplex = 1; if (kpts_timrev_from_kptopt(ebands%kptopt) == 0) cplex = 2 4286 skw = skw_new(cryst, params(2:), cplex, ebands%mband, ebands%nkpt, ebands%nsppol, ebands%kptns, ebands%eig, my_bblock, comm) 4287 !if (itype == 2) then 4288 ! ABI_CALLOC(new%velocity,(3,new%mband,new%nkpt,new%nsppol)) 4289 !end if 4290 else 4291 ABI_ERROR(sjoin("Wrong einterp params(1):", itoa(itype))) 4292 end if 4293 4294 ! Interpolate eigenvalues and velocities. 4295 new%eig = zero; cnt = 0 4296 do spin=1,new%nsppol 4297 do ik_ibz=1,new%nkpt 4298 do ib=1,nb 4299 cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! Mpi parallelism. 4300 ! Note the difference between band and ib index if band_block. 4301 band = my_bblock(1) + ib - 1 4302 select case (itype) 4303 case (1) 4304 call skw%eval_bks(band, new%kptns(:,ik_ibz), spin, new%eig(ib,ik_ibz,spin)) 4305 !case (2) 4306 ! call skw%eval_bks(band, new%kptns(:,ik_ibz), spin, new%eig(ib,ik_ibz,spin), new%velocity(:,ib,ik_ibz,spin)) 4307 case default 4308 ABI_ERROR(sjoin("Wrong params(1):", itoa(itype))) 4309 end select 4310 end do 4311 end do 4312 end do 4313 call xmpi_sum(new%eig, comm, ierr) 4314 !if (itype == 2) call xmpi_sum(new%velocity, comm, ierr) 4315 4316 ! Sort eigvalues_k in ascending order to be compatible with other ebands routines. 4317 call ebands_sort(new) 4318 !call ebands_update_occ(new, dtset%spinmagntarget, prtvol=dtset%prtvol) 4319 4320 if (my_rank == master .and. itype == 1 .and. present(out_prefix)) then 4321 ! Write ESKW file with crystal and (interpolated) band structure energies. 4322 !call wrtout(ab_out, sjoin("- Writing interpolated bands to file:", strcat(prefix, tag))) 4323 ! Write crystal and (interpolated) band structure energies. 4324 NCF_CHECK(nctk_open_create(ncid, strcat(out_prefix, "_ESKW.nc"), xmpi_comm_self)) 4325 NCF_CHECK(cryst%ncwrite(ncid)) 4326 NCF_CHECK(ebands_ncwrite(new, ncid)) 4327 4328 ! TODO 4329 !NCF_CHECK(skw%ncwrite(ncid)) 4330 ! Define variables specific to SKW algo. 4331 !ncerr = nctk_def_arrays(ncid, [ & 4332 ! nctkarr_t("band_block", "int", "two"), & 4333 ! nctkarr_t("einterp", "dp", "four")], defmode=.True.) 4334 !NCF_CHECK(ncerr) 4335 4336 ! Write data. 4337 !NCF_CHECK(nctk_set_datamode(ncid)) 4338 !NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "band_block"), band_block)) 4339 !NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "einterp"), params)) 4340 NCF_CHECK(nf90_close(ncid)) 4341 end if 4342 4343 call skw%free() 4344 4345 end function ebands_interp_kmesh
m_ebands/ebands_interp_kpath [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_interp_kpath
FUNCTION
Interpolate energies on a k-path
INPUTS
ebands<ebands_t> = Object with input energies. cryst<crystal_t> = Crystalline structure. kpath<kpath_t> = Object describing the k-path params(:): params(1): 1 for SKW. band_block(2)=Initial and final band index to be interpolated. [0,0] if all bands are used. This is a global variable i.e. all MPI procs must call the routine with the same value. comm=MPI communicator
OUTPUT
New ebands_t object with interpolated energies.
SOURCE
4372 type(ebands_t) function ebands_interp_kpath(ebands, cryst, kpath, params, band_block, comm) result(new) 4373 4374 !Arguments ------------------------------------ 4375 !scalars 4376 integer,intent(in) :: comm 4377 type(ebands_t),intent(in) :: ebands 4378 type(crystal_t),intent(in) :: cryst 4379 type(kpath_t),intent(in) :: kpath 4380 !arrays 4381 integer,intent(in) :: band_block(2) 4382 real(dp),intent(in) :: params(:) 4383 4384 !Local variables------------------------------- 4385 !scalars 4386 integer,parameter :: new_nshiftk=1 4387 integer :: ik_ibz,spin,new_bantot,new_mband,cplex 4388 integer :: nprocs,my_rank,cnt,ierr,band,new_nkibz,itype,nb,ib, new_kptopt 4389 type(skw_t) :: skw 4390 !arrays 4391 integer,parameter :: new_kptrlatt(3,3)=0 4392 integer :: my_bblock(2) 4393 integer,allocatable :: new_istwfk(:),new_nband(:,:),new_npwarr(:) 4394 real(dp),parameter :: new_shiftk(3,1) = zero 4395 real(dp),allocatable :: new_wtk(:),new_doccde(:),new_eig(:),new_occ(:) 4396 4397 ! ********************************************************************* 4398 4399 nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm) 4400 itype = nint(params(1)) 4401 my_bblock = band_block; if (all(band_block == 0)) my_bblock = [1, ebands%mband] 4402 nb = my_bblock(2) - my_bblock(1) + 1 4403 4404 if (ebands%nkpt == 1) then 4405 ABI_WARNING("Cannot interpolate band energies when nkpt = 1. Returning") 4406 return 4407 end if 4408 4409 ! Initialize new ebands_t. 4410 new_nkibz = kpath%npts 4411 ABI_MALLOC(new_istwfk, (new_nkibz)) 4412 new_istwfk = 1 4413 ABI_MALLOC(new_nband, (new_nkibz, ebands%nsppol)) 4414 new_nband = nb 4415 ABI_MALLOC(new_npwarr, (new_nkibz)) 4416 new_npwarr = maxval(ebands%npwarr) 4417 new_bantot = sum(new_nband); new_mband = maxval(new_nband) 4418 ABI_CALLOC(new_eig, (new_bantot)) 4419 ABI_CALLOC(new_doccde, (new_bantot)) 4420 ABI_CALLOC(new_occ, (new_bantot)) 4421 ABI_CALLOC(new_wtk, (new_nkibz)) 4422 4423 ! Needed by AbiPy to understand that we have a k-path instead of a mesh. 4424 new_kptopt = -kpath%nbounds 4425 4426 call ebands_init(new_bantot, new, ebands%nelect, ebands%ne_qFD,ebands%nh_qFD,ebands%ivalence, & 4427 new_doccde, new_eig, new_istwfk, kpath%points, & 4428 new_nband, new_nkibz, new_npwarr, ebands%nsppol, ebands%nspinor, ebands%tphysel, ebands%tsmear, & 4429 ebands%occopt, new_occ, new_wtk,& 4430 ebands%cellcharge, new_kptopt, new_kptrlatt, new_nshiftk, new_shiftk, new_kptrlatt, new_nshiftk, new_shiftk) 4431 4432 new%fermie = ebands%fermie 4433 new%fermih = ebands%fermih 4434 4435 ABI_FREE(new_wtk) 4436 ABI_FREE(new_istwfk) 4437 ABI_FREE(new_nband) 4438 ABI_FREE(new_npwarr) 4439 ABI_FREE(new_doccde) 4440 ABI_FREE(new_eig) 4441 ABI_FREE(new_occ) 4442 4443 ! Build SKW object for all bands. 4444 select case (itype) 4445 case (1) 4446 cplex = 1; if (kpts_timrev_from_kptopt(ebands%kptopt) == 0) cplex = 2 4447 skw = skw_new(cryst, params(2:), cplex, ebands%mband, ebands%nkpt, ebands%nsppol, ebands%kptns, ebands%eig, & 4448 my_bblock, comm) 4449 4450 case default 4451 ABI_ERROR(sjoin("Wrong einterp params(1):", itoa(itype))) 4452 end select 4453 4454 ! Interpolate eigenvalues. 4455 new%eig = zero; cnt = 0 4456 do spin=1,new%nsppol 4457 do ik_ibz=1,new%nkpt 4458 do ib=1,nb 4459 cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! Mpi parallelism. 4460 ! Note the difference between band and ib index if band_block. 4461 band = my_bblock(1) + ib - 1 4462 select case (itype) 4463 case (1) 4464 call skw%eval_bks(band, new%kptns(:,ik_ibz), spin, new%eig(ib,ik_ibz,spin)) 4465 case default 4466 ABI_ERROR(sjoin("Wrong einterp params(1):", itoa(itype))) 4467 end select 4468 end do 4469 end do 4470 end do 4471 call xmpi_sum(new%eig, comm, ierr) 4472 4473 ! Sort eigvalues_k in ascending order to be compatible with other ebands routines. 4474 call ebands_sort(new) 4475 4476 call skw%free() 4477 4478 end function ebands_interp_kpath
m_ebands/ebands_interpolate_kpath [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_interpolate_kpath
FUNCTION
INPUTS
dtset<dataset_type>=Abinit dataset band_block(2)=Initial and final band index to be interpolated. [0,0] if all bands are used. This is a global variable i.e. all MPI procs must call the routine with the same value.
OUTPUT
SOURCE
5824 subroutine ebands_interpolate_kpath(ebands, dtset, cryst, band_block, prefix, comm) 5825 5826 !Arguments ------------------------------------ 5827 !scalars 5828 type(ebands_t),intent(in) :: ebands 5829 type(dataset_type),intent(in) :: dtset 5830 type(crystal_t),intent(in) :: cryst 5831 integer,intent(in) :: comm 5832 character(len=*),intent(in) :: prefix 5833 !arrays 5834 integer,intent(in) :: band_block(2) 5835 5836 !Local variables------------------------------- 5837 !scalars 5838 integer,parameter :: master = 0, intp_nshiftk1 = 1 5839 integer :: my_rank, ndivsm, nbounds, itype !, spin, ik, ib, ii, jj, ierr 5840 type(ebands_t) :: ebands_kpath 5841 type(kpath_t) :: kpath 5842 character(len=500) :: tag !msg 5843 !arrays 5844 real(dp),allocatable :: bounds(:,:) 5845 5846 ! ********************************************************************* 5847 5848 my_rank = xmpi_comm_rank(comm) 5849 5850 itype = nint(dtset%einterp(1)); tag = "_SKW" 5851 tag = "_INTERP" 5852 5853 ! Generate k-path 5854 ndivsm = dtset%ndivsm 5855 if (ndivsm <= 0) then 5856 ABI_COMMENT("Setting ndivsm to 20 because variable is not given in input file") 5857 ndivsm = 20 5858 end if 5859 nbounds = dtset%nkpath 5860 if (nbounds <= 0) then 5861 ABI_COMMENT("Using hard-coded k-path because nkpath not present in input file.") 5862 nbounds = 5 5863 ABI_MALLOC(bounds, (3, 5)) 5864 bounds = reshape([zero, zero, zero, half, zero, zero, zero, half, zero, zero, zero, zero, zero, zero, half], [3,5]) 5865 else 5866 call alloc_copy(dtset%kptbounds, bounds) 5867 end if 5868 5869 kpath = kpath_new(bounds, cryst%gprimd, ndivsm) 5870 call kpath%print(header="Interpolating energies on k-path", unit=std_out) 5871 ABI_FREE(bounds) 5872 5873 ! Interpolate bands on k-path. 5874 ebands_kpath = ebands_interp_kpath(ebands, cryst, kpath, dtset%einterp, band_block, comm) 5875 5876 if (my_rank == master) then 5877 call wrtout(ab_out, sjoin("- Writing interpolated bands to file:", strcat(prefix, tag))) 5878 call ebands_write(ebands_kpath, dtset%prtebands, strcat(prefix, tag), kptbounds=kpath%bounds) 5879 end if 5880 5881 call ebands_free(ebands_kpath) 5882 call kpath%free() 5883 5884 end subroutine ebands_interpolate_kpath
m_ebands/ebands_move_alloc [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_move_alloc
FUNCTION
Transfer allocate from `from_ebands` to `to_ebands`. `from_ebands` is destroyed when the routine returns.
SOURCE
1131 subroutine ebands_move_alloc(from_ebands, to_ebands) 1132 1133 !Arguments ------------------------------------ 1134 class(ebands_t),intent(inout) :: from_ebands 1135 class(ebands_t),intent(inout) :: to_ebands 1136 1137 ! ********************************************************************* 1138 1139 call ebands_free(to_ebands) 1140 call ebands_copy(from_ebands, to_ebands) 1141 call ebands_free(from_ebands) 1142 1143 end subroutine ebands_move_alloc
m_ebands/ebands_ncwrite [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_ncwrite
FUNCTION
Writes the content of an ebands_t object to a NETCDF file according to the ETSF-IO specifications. Return nf90_noerr if success.
INPUTS
ncid =NC file handle
SOURCE
2908 integer function ebands_ncwrite(ebands, ncid) result(ncerr) 2909 2910 !Arguments ------------------------------------ 2911 !scalars 2912 integer,intent(in) :: ncid 2913 class(ebands_t),intent(in) :: ebands 2914 2915 !Local variables------------------------------- 2916 !scalars 2917 integer :: ii,nelect_int 2918 logical :: write_ngkpt 2919 character(len=etsfio_charlen) :: smearing,k_dependent 2920 !arrays 2921 integer :: ngkpt(3) 2922 2923 ! ************************************************************************* 2924 2925 smearing = nctk_string_from_occopt(ebands%occopt) 2926 2927 ! ============================================== 2928 ! === Write the dimensions specified by ETSF === 2929 ! ============================================== 2930 ncerr = nctk_def_dims(ncid, [ & 2931 nctkdim_t("max_number_of_states", ebands%mband), & 2932 nctkdim_t("number_of_spinor_components", ebands%nspinor), & 2933 nctkdim_t("number_of_spins", ebands%nsppol), & 2934 nctkdim_t("number_of_kpoints", ebands%nkpt), & 2935 nctkdim_t("nshiftk_orig", ebands%nshiftk_orig), & 2936 nctkdim_t("nshiftk", ebands%nshiftk)], & 2937 defmode=.True.) 2938 NCF_CHECK(ncerr) 2939 2940 ! FIXME 2941 ! Unofficial variables. Notes: 2942 ! 1) ETSF-IO does not support nshifts > 1 2943 ! 2) shiftk_orig, nshiftk_orig refers to the values specified in the input (most useful ones). 2944 ! 3) shiftk, kptrlatt refers to the values computed in inkpts. 2945 ! 4) Should define a protocol so that abipy understands if we have a path or a mesh. 2946 !write_kptrlatt = (SUM(ABS(ebands%kptrlatt))/=0) 2947 !write_kptrlatt = (ebands%kptopt /= 0) 2948 2949 ngkpt = 0; write_ngkpt = .False. 2950 if (isdiagmat(ebands%kptrlatt) .and. ebands%nshiftk == 1) then 2951 write_ngkpt = .True. 2952 do ii=1,3 2953 ngkpt(ii) = ebands%kptrlatt(ii, ii) 2954 end do 2955 ncerr = nctk_def_dims(ncid, nctkdim_t('ngkpt_nshiftk', ebands%nshiftk_orig)) 2956 NCF_CHECK(ncerr) 2957 end if 2958 2959 ! Define k-points 2960 ncerr = nctk_def_arrays(ncid, [& 2961 nctkarr_t("reduced_coordinates_of_kpoints", "dp", "number_of_reduced_dimensions, number_of_kpoints"), & 2962 nctkarr_t("kpoint_weights", "dp", "number_of_kpoints"), & 2963 nctkarr_t("monkhorst_pack_folding", "int", "number_of_vectors") & 2964 ]) 2965 NCF_CHECK(ncerr) 2966 2967 ! Define states section. 2968 ncerr = nctk_def_arrays(ncid, [& 2969 nctkarr_t("number_of_states", "int", "number_of_kpoints, number_of_spins"), & 2970 nctkarr_t("eigenvalues", "dp", "max_number_of_states, number_of_kpoints, number_of_spins"), & 2971 nctkarr_t("occupations", "dp", "max_number_of_states, number_of_kpoints, number_of_spins"), & 2972 nctkarr_t("smearing_scheme", "char", "character_string_length") & 2973 ]) 2974 NCF_CHECK(ncerr) 2975 2976 ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: "number_of_electrons"]) 2977 NCF_CHECK(ncerr) 2978 ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: "fermi_energy", "smearing_width"]) 2979 NCF_CHECK(ncerr) 2980 2981 ! Some variables require the specifications of units. 2982 NCF_CHECK(nctk_set_atomic_units(ncid, "eigenvalues")) 2983 NCF_CHECK(nctk_set_atomic_units(ncid, "fermi_energy")) 2984 2985 k_dependent = "no"; if (any(ebands%nband(1) /= ebands%nband)) k_dependent = "yes" 2986 NCF_CHECK(nf90_put_att(ncid, vid("number_of_states"), "k_dependent", k_dependent)) 2987 2988 ! Write data. 2989 ! 1) Electrons. 2990 ! NB: In etsf_io the number of electrons is declared as integer. 2991 ! We use abinit nelect to store the value as real(dp). 2992 nelect_int = nint(ebands%nelect) 2993 2994 NCF_CHECK(nctk_set_datamode(ncid)) 2995 NCF_CHECK(nf90_put_var(ncid, vid("fermi_energy"), ebands%fermie)) 2996 NCF_CHECK(nf90_put_var(ncid, vid("number_of_electrons"), nelect_int)) 2997 NCF_CHECK(nf90_put_var(ncid, vid("smearing_width"), ebands%tsmear)) 2998 NCF_CHECK(nf90_put_var(ncid, vid("number_of_states"), ebands%nband, count=[ebands%nkpt, ebands%nsppol])) 2999 NCF_CHECK(nf90_put_var(ncid, vid("eigenvalues"), ebands%eig)) 3000 NCF_CHECK(nf90_put_var(ncid, vid("occupations"), ebands%occ)) 3001 NCF_CHECK(nf90_put_var(ncid, vid("smearing_scheme"), smearing)) 3002 3003 ! K-points 3004 NCF_CHECK(nf90_put_var(ncid, vid("reduced_coordinates_of_kpoints"), ebands%kptns)) 3005 NCF_CHECK(nf90_put_var(ncid, vid("kpoint_weights"), ebands%wtk)) 3006 3007 if (write_ngkpt) then 3008 NCF_CHECK(nf90_put_var(ncid, vid("monkhorst_pack_folding"), ngkpt)) 3009 end if 3010 3011 ! =========================================================== 3012 ! === Write abinit-related stuff (not covered by ETSF-IO) === 3013 ! =========================================================== 3014 ! Define variables. 3015 NCF_CHECK(nctk_def_iscalars(ncid, [character(len=nctk_slen) :: "occopt", "kptopt"], defmode=.True.)) 3016 NCF_CHECK(nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: "tphysel", "charge", "nelect", "extrael"])) 3017 3018 ncerr = nctk_def_arrays(ncid, nctkarr_t('istwfk', "i", 'number_of_kpoints')) 3019 NCF_CHECK(ncerr) 3020 3021 ! Abinit variables defining the K-point sampling. 3022 ncerr = nctk_def_arrays(ncid, [& 3023 nctkarr_t('kptrlatt_orig', "i", 'number_of_reduced_dimensions, number_of_reduced_dimensions'), & 3024 nctkarr_t('shiftk_orig', "dp", 'number_of_reduced_dimensions, nshiftk_orig'), & 3025 nctkarr_t('kptrlatt', "i", 'number_of_reduced_dimensions, number_of_reduced_dimensions'), & 3026 nctkarr_t('shiftk', "dp", 'number_of_reduced_dimensions, nshiftk') & 3027 ]) 3028 NCF_CHECK(ncerr) 3029 3030 if (write_ngkpt) then 3031 ncerr = nctk_def_arrays(ncid, nctkarr_t('ngkpt_shiftk', "dp", "number_of_reduced_dimensions, ngkpt_nshiftk")) 3032 NCF_CHECK(ncerr) 3033 end if 3034 3035 ! Write Abinit variables 3036 NCF_CHECK(nctk_set_datamode(ncid)) 3037 NCF_CHECK(nf90_put_var(ncid, vid("tphysel"), ebands%tphysel)) 3038 NCF_CHECK(nf90_put_var(ncid, vid("occopt"), ebands%occopt)) 3039 NCF_CHECK(nf90_put_var(ncid, vid("istwfk"), ebands%istwfk)) 3040 NCF_CHECK(nf90_put_var(ncid, vid("kptopt"), ebands%kptopt)) 3041 NCF_CHECK(nf90_put_var(ncid, vid("charge"), ebands%cellcharge)) 3042 NCF_CHECK(nf90_put_var(ncid, vid("extrael"), ebands%extrael)) 3043 NCF_CHECK(nf90_put_var(ncid, vid("nelect"), ebands%nelect)) 3044 NCF_CHECK(nf90_put_var(ncid, vid('kptrlatt_orig'), ebands%kptrlatt_orig)) 3045 NCF_CHECK(nf90_put_var(ncid, vid('shiftk_orig'), ebands%shiftk_orig)) 3046 NCF_CHECK(nf90_put_var(ncid, vid('kptrlatt'),ebands%kptrlatt)) 3047 NCF_CHECK(nf90_put_var(ncid, vid('shiftk'), ebands%shiftk)) 3048 3049 if (write_ngkpt) then 3050 NCF_CHECK(nf90_put_var(ncid, vid('ngkpt_shiftk'), ebands%shiftk_orig)) 3051 end if 3052 3053 !In the case occopt 9 3054 if (ebands%occopt == 9) then 3055 ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: & 3056 "number_of_conduction_electrons", "number_of_valence_holes"]) 3057 NCF_CHECK(ncerr) 3058 ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: "holes_fermi_energy"]) 3059 NCF_CHECK(ncerr) 3060 NCF_CHECK(nctk_set_atomic_units(ncid,"holes_fermi_energy")) 3061 NCF_CHECK(nf90_put_var(ncid, vid("holes_fermi_energy"), ebands%fermih)) 3062 NCF_CHECK(nf90_put_var(ncid, vid("number_of_conduction_electrons"), ebands%ne_qFD)) 3063 NCF_CHECK(nf90_put_var(ncid, vid("number_of_valence_holes"), ebands%nh_qFD)) 3064 endif 3065 3066 contains 3067 integer function vid(vname) 3068 character(len=*),intent(in) :: vname 3069 vid = nctk_idname(ncid, vname) 3070 end function vid 3071 3072 end function ebands_ncwrite
m_ebands/ebands_ncwrite_path [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_ncwrite_path
FUNCTION
Writes the content of an ebands_t object to a NETCDF file
INPUTS
cryst=Crystal structure path=File name
OUTPUT
SOURCE
3092 integer function ebands_ncwrite_path(ebands, cryst, path) result(ncerr) 3093 3094 !Arguments ------------------------------------ 3095 !scalars 3096 class(ebands_t),intent(in) :: ebands 3097 type(crystal_t),intent(in) :: cryst 3098 character(len=*),intent(in) :: path 3099 3100 !Local variables------------------------------- 3101 !scalars 3102 integer :: ncid 3103 3104 ! ************************************************************************* 3105 3106 ncerr = nf90_noerr 3107 if (file_exists(path)) then 3108 NCF_CHECK(nctk_open_modify(ncid, path, xmpi_comm_self)) 3109 else 3110 ncerr = nctk_open_create(ncid, path, xmpi_comm_self) 3111 NCF_CHECK_MSG(ncerr, sjoin("Creating", path)) 3112 end if 3113 3114 NCF_CHECK(cryst%ncwrite(ncid)) 3115 NCF_CHECK(ebands_ncwrite(ebands, ncid)) 3116 NCF_CHECK(nf90_close(ncid)) 3117 3118 end function ebands_ncwrite_path
m_ebands/ebands_nelect_per_spin [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_nelect_per_spin
FUNCTION
Return number of electrons in each spin channel (computed from occoputation factors if nsppol=2)
INPUTS
ebands<ebands_t>=The object describing the band structure.
OUTPUT
nelect_per_spin(ebands%nsppol)=For each spin the number of electrons (eventually fractional)
SOURCE
2068 pure function ebands_nelect_per_spin(ebands) result(nelect_per_spin) 2069 2070 !Arguments ------------------------------------ 2071 !scalars 2072 class(ebands_t),intent(in) :: ebands 2073 !arrays 2074 real(dp) :: nelect_per_spin(ebands%nsppol) 2075 2076 !Local variables------------------------------- 2077 !scalars 2078 integer :: iband,ikpt,spin 2079 2080 ! ************************************************************************* 2081 2082 nelect_per_spin = ebands%nelect 2083 if (ebands%nsppol > 1) then 2084 nelect_per_spin = zero 2085 do spin=1,ebands%nsppol 2086 do ikpt=1,ebands%nkpt 2087 do iband=1,ebands%nband(ikpt+ebands%nkpt*(spin-1)) 2088 nelect_per_spin(spin) = nelect_per_spin(spin) + ebands%wtk(ikpt) * ebands%occ(iband, ikpt, spin) 2089 end do 2090 end do 2091 end do 2092 end if 2093 2094 end function ebands_nelect_per_spin
m_ebands/ebands_print [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_print
FUNCTION
Print the content of the object.
INPUTS
ebands<ebands_t>The type containing the data. [unit]=Unit number (default: std_out) [header]=title for info [prtvol]=Verbosity level (default: 0)
OUTPUT
Only writing
SOURCE
1166 subroutine ebands_print(ebands, header, unit, prtvol) 1167 1168 !Arguments ------------------------------------ 1169 class(ebands_t),intent(in) :: ebands 1170 integer,optional,intent(in) :: prtvol, unit 1171 character(len=*),optional,intent(in) :: header 1172 1173 !Local variables------------------------------- 1174 integer :: spin, ikpt, unt, my_prtvol, ii 1175 character(len=500) :: msg 1176 ! ************************************************************************* 1177 1178 unt = std_out; if (present(unit)) unt =unit 1179 my_prtvol = 0; if (present(prtvol)) my_prtvol = prtvol 1180 1181 msg = ' ==== Info on the ebands_t ==== ' 1182 if (present(header)) msg=' ==== '//trim(adjustl(header))//' ==== ' 1183 call wrtout(unt, msg) 1184 1185 write(msg,'(6(a,i0,a))')& 1186 ' Number of spinorial components ...... ',ebands%nspinor,ch10,& 1187 ' Number of spin polarizations ........ ',ebands%nsppol,ch10,& 1188 ' Number of k-points in the IBZ ....... ',ebands%nkpt,ch10,& 1189 ' kptopt .............................. ',ebands%kptopt,ch10,& 1190 ' Maximum number of bands ............. ',ebands%mband,ch10,& 1191 ' Occupation option ................... ',ebands%occopt,ch10 1192 call wrtout(unt, msg) 1193 1194 write(msg,"(2a)")" kptrlatt .............. ",trim(ltoa(reshape(ebands%kptrlatt, [9]))) 1195 call wrtout(unt, msg) 1196 write(msg,"(2a)")" shiftk ................ ",trim(ltoa(reshape(ebands%shiftk, [3 * ebands%nshiftk]))) 1197 call wrtout(unt, msg) 1198 1199 write(msg,'(3(a,f14.2,a),4(a,f14.6,a))')& 1200 ' Number of valence electrons ......... ',ebands%nelect,ch10,& 1201 ' Extra cell charge (from GS run)...... ',ebands%cellcharge,ch10,& 1202 ' Extra electrons (after GS run)....... ',ebands%extrael,ch10,& 1203 ' Fermi level ........................ ',ebands%fermie,ch10,& 1204 ' Entropy ............................. ',ebands%entropy,ch10,& 1205 ' Tsmear value ........................ ',ebands%tsmear,ch10,& 1206 ' Tphysel value ....................... ',ebands%tphysel,ch10 1207 call wrtout(unt, msg) 1208 1209 if (my_prtvol > 10) then 1210 if (ebands%nsppol == 1)then 1211 call wrtout(unt, sjoin(' New occ. numbers for occopt= ', itoa(ebands%occopt),' , spin-unpolarized case.')) 1212 end if 1213 1214 do spin=1,ebands%nsppol 1215 if (ebands%nsppol == 2) then 1216 write(msg,'(a,i9,a,i0)')' New occ. numbers for occopt= ',ebands%occopt,', spin ',spin 1217 call wrtout(unt, msg) 1218 end if 1219 1220 do ikpt=1,ebands%nkpt 1221 write(msg,'(2a,i4,3a,f6.3,2a)')ch10,& 1222 ' k-point number ',ikpt,') ',trim(ktoa(ebands%kptns(:,ikpt))),'; weight: ',ebands%wtk(ikpt), ch10, & 1223 " eig (Ha), eig (eV), occ, doccde" 1224 call wrtout(unt, msg) 1225 do ii=1,ebands%nband(ikpt+(spin-1)*ebands%nkpt) 1226 write(msg,'(4(f7.3,1x))')ebands%eig(ii,ikpt,spin), ebands%eig(ii,ikpt,spin) * Ha_eV, & 1227 ebands%occ(ii,ikpt,spin), ebands%doccde(ii,ikpt,spin) 1228 call wrtout(unt, msg) 1229 end do 1230 end do !ikpt 1231 1232 end do !spin 1233 1234 end if !my_prtvol 1235 1236 end subroutine ebands_print
m_ebands/ebands_print_gaps [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_print_gaps
FUNCTION
Helper function to print gaps directly from ebands.
INPUTS
ebands<ebands_t>=Info on the band structure, the smearing technique and the physical temperature used.
OUTPUT
SOURCE
386 subroutine ebands_print_gaps(ebands, unit, header) 387 388 !Arguments ------------------------------------ 389 class(ebands_t),intent(in) :: ebands 390 integer,intent(in) :: unit 391 character(len=*),optional,intent(in) :: header 392 393 !Local variables------------------------------- 394 integer :: ierr, spin 395 type(gaps_t) :: gaps 396 397 ! ********************************************************************* 398 399 if (unit == dev_null) return 400 401 gaps = ebands_get_gaps(ebands, ierr) 402 if (ierr /= 0) then 403 do spin=1, ebands%nsppol 404 write(unit, "(a)")trim(gaps%errmsg_spin(spin)) 405 end do 406 end if 407 408 if (present(header)) then 409 call gaps%print(unit=unit, header=header) 410 else 411 call gaps%print(unit=unit) 412 end if 413 call gaps%free() 414 415 end subroutine ebands_print_gaps
m_ebands/ebands_prtbltztrp [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_prtbltztrp
FUNCTION
Output files for BoltzTraP code, which integrates Boltzmann transport quantities over the Fermi surface for different T and chemical potentials. Abinit provides all necessary input files: struct, energy, input file, and def file for the unit definitions of fortran files in BT. See http://www.icams.de/content/departments/ams/madsen/boltztrap.html
INPUTS
ebands<ebands_t>=Band structure object. cryst<cryst_t>=Info on the crystalline structure. fname_radix = radix of file names for output
OUTPUT
(only writing, printing)
SOURCE
5114 subroutine ebands_prtbltztrp(ebands, crystal, fname_radix, tau_k) 5115 5116 !Arguments ------------------------------------ 5117 !scalars 5118 type(ebands_t),intent(in) :: ebands 5119 type(crystal_t),intent(in) :: crystal 5120 character(len=fnlen), intent(in) :: fname_radix 5121 !arrays 5122 real(dp), intent(in), optional :: tau_k(ebands%nsppol,ebands%nkpt,ebands%mband) 5123 5124 !Local variables------------------------------- 5125 !scalars 5126 integer :: iout, isym, iband, isppol, ikpt, nsppol, nband 5127 real(dp),parameter :: ha2ryd=two 5128 real(dp) :: ewindow 5129 character(len=fnlen) :: filename 5130 character(len=2) :: so_suffix 5131 character(len=500) :: msg 5132 !arrays 5133 real(dp) :: nelec(ebands%nsppol) 5134 character(len=3) :: spinsuffix(ebands%nsppol) 5135 5136 ! ************************************************************************* 5137 5138 !MG FIXME The number of electrons is wrong if the file is produced in a NSCF run. 5139 ! See https://forum.abinit.org/viewtopic.php?f=19&t=3339 5140 5141 ! CP test to prevent use in case occopt = 9 5142 if (ebands%occopt==9) then 5143 write(msg,'(a)') "Boltztrap outputting not possible with occopt = 9 at the moment" 5144 ABI_ERROR(msg) 5145 end if 5146 5147 nelec = ebands_nelect_per_spin(ebands) 5148 nsppol = ebands%nsppol 5149 nband = ebands%nband(1) 5150 5151 so_suffix="" 5152 if (nsppol > 1 .or. ebands%nspinor > 1) so_suffix="so" 5153 5154 if (nsppol == 1) then 5155 spinsuffix(1) = "ns_" 5156 else 5157 spinsuffix = ["up_", "dn_"] 5158 end if 5159 5160 do isppol=1,nsppol 5161 5162 !input file for boltztrap: general info, Ef, Nelec, etc... 5163 filename= trim(fname_radix)//"_"//trim(spinsuffix(isppol))//"BLZTRP.intrans" 5164 if (open_file(filename, msg, newunit=iout, form='formatted') /= 0) then 5165 ABI_ERROR(msg) 5166 end if 5167 5168 ewindow = 1.1_dp * (ebands%fermie-minval(ebands%eig(1, :, isppol))) 5169 write (iout, '(a)') "GENE # Format of input: generic format, with Symmetries" 5170 write (iout, '(a)') "0 0 0 0.0 # iskip (not presently used) idebug setgap shiftgap" 5171 write (iout, '(E15.5,a,2F10.4,a)') ebands%fermie*ha2ryd, " 0.0005 ", ewindow*ha2ryd, nelec(isppol), & 5172 & " # Fermilevel (Ry), energy grid spacing, energy span around Fermilevel, number of electrons for this spin" 5173 write (iout, '(a)') "CALC # CALC (calculate expansion coeff), NOCALC read from file" 5174 write (iout, '(a)') "3 # lpfac, number of latt-points per k-point" 5175 write (iout, '(a)') "BOLTZ # run mode (only BOLTZ is supported)" 5176 write (iout, '(a)') ".15 # (efcut) energy range of chemical potential" 5177 write (iout, '(a)') "300. 10. # Tmax, temperature grid spacing" 5178 write (iout, '(2a)') "-1 # energyrange of bands given ",& 5179 & "individual DOS output sig_xxx and dos_xxx (xxx is band number)" 5180 write (iout, '(a)') "HISTO # DOS calculation method. Other possibility is TETRA" 5181 write (iout, '(a)') "No # not using model for relaxation time" 5182 write (iout, '(a)') "3 # Number of doping levels coefficients will be output for" 5183 write (iout, '(a)') "-1.e16 0.0d0 1.e16 # Values of doping levels (in carriers / cm^3" 5184 close(iout) 5185 5186 !files file, with association of all units for Boltztrap 5187 filename= trim(fname_radix)//"_"//trim(spinsuffix(isppol))//"BLZTRP.def" 5188 if (open_file(filename, msg, newunit=iout, form='formatted') /= 0) then 5189 ABI_ERROR(msg) 5190 end if 5191 5192 write (iout, '(3a)') "5, '", trim(fname_radix)//"_"//trim(spinsuffix(isppol))//"BLZTRP.intrans', 'old', 'formatted',0" 5193 write (iout, '(3a)') "6, '", trim(fname_radix)//"_BLZTRP", ".outputtrans', 'unknown', 'formatted',0" 5194 write (iout, '(3a)') "20,'", trim(fname_radix)//"_BLZTRP", ".struct', 'old', 'formatted',0" 5195 write (iout, '(3a)') "10,'", trim(fname_radix)//"_BLZTRP."//trim(spinsuffix(isppol))//"energy"//trim(so_suffix),& 5196 & "', 'old', 'formatted',0" 5197 if (present (tau_k)) then 5198 write (iout, '(3a)') "11,'", trim(fname_radix)//"_BLZTRP", ".tau_k', 'old', 'formatted',0" 5199 end if 5200 write (iout, '(3a)') "48,'", trim(fname_radix)//"_BLZTRP", ".engre', 'unknown', 'unformatted',0" 5201 write (iout, '(3a)') "49,'", trim(fname_radix)//"_BLZTRP", ".transdos', 'unknown', 'formatted',0" 5202 write (iout, '(3a)') "50,'", trim(fname_radix)//"_BLZTRP", ".sigxx', 'unknown', 'formatted',0" 5203 write (iout, '(3a)') "51,'", trim(fname_radix)//"_BLZTRP", ".sigxxx', 'unknown', 'formatted',0" 5204 write (iout, '(3a)') "21,'", trim(fname_radix)//"_BLZTRP", ".trace', 'unknown', 'formatted',0" 5205 write (iout, '(3a)') "22,'", trim(fname_radix)//"_BLZTRP", ".condtens', 'unknown', 'formatted',0" 5206 write (iout, '(3a)') "24,'", trim(fname_radix)//"_BLZTRP", ".halltens', 'unknown', 'formatted',0" 5207 write (iout, '(3a)') "25,'", trim(fname_radix)//"_BLZTRP", ".trace_fixdoping', 'unknown', 'formatted',0" 5208 write (iout, '(3a)') "26,'", trim(fname_radix)//"_BLZTRP", ".condtens_fixdoping', 'unknown', 'formatted',0" 5209 write (iout, '(3a)') "27,'", trim(fname_radix)//"_BLZTRP", ".halltens_fixdoping', 'unknown', 'formatted',0" 5210 write (iout, '(3a)') "30,'", trim(fname_radix)//"_BLZTRP", "_BZ.dx', 'unknown', 'formatted',0" 5211 write (iout, '(3a)') "31,'", trim(fname_radix)//"_BLZTRP", "_fermi.dx', 'unknown', 'formatted',0" 5212 write (iout, '(3a)') "32,'", trim(fname_radix)//"_BLZTRP", "_sigxx.dx', 'unknown', 'formatted',0" 5213 write (iout, '(3a)') "33,'", trim(fname_radix)//"_BLZTRP", "_sigyy.dx', 'unknown', 'formatted',0" 5214 write (iout, '(3a)') "34,'", trim(fname_radix)//"_BLZTRP", "_sigzz.dx', 'unknown', 'formatted',0" 5215 write (iout, '(3a)') "35,'", trim(fname_radix)//"_BLZTRP", "_band.dat', 'unknown', 'formatted',0" 5216 write (iout, '(3a)') "36,'", trim(fname_radix)//"_BLZTRP", "_band.gpl', 'unknown', 'formatted',0" 5217 write (iout, '(3a)') "37,'", trim(fname_radix)//"_BLZTRP", "_deriv.dat', 'unknown', 'formatted',0" 5218 write (iout, '(3a)') "38,'", trim(fname_radix)//"_BLZTRP", "_mass.dat', 'unknown', 'formatted',0" 5219 5220 close(iout) 5221 end do !isppol 5222 5223 !file is for geometry symmetries etc 5224 filename= trim(fname_radix)//"_BLZTRP.struct" 5225 if (open_file(filename, msg, newunit=iout, form='formatted') /= 0) then 5226 ABI_ERROR(msg) 5227 end if 5228 5229 write (iout, '(a)') "BoltzTraP geometry file generated by ABINIT." 5230 5231 !here we need to print out the unit cell vectors 5232 write (iout, '(3E20.10)') crystal%rprimd(:,1) 5233 write (iout, '(3E20.10)') crystal%rprimd(:,2) 5234 write (iout, '(3E20.10)') crystal%rprimd(:,3) 5235 write (iout, '(I7)') crystal%nsym 5236 5237 do isym=1,crystal%nsym 5238 write (iout,'(3(3I5,2x), a, I5)') & 5239 & crystal%symrel(1,:,isym), & 5240 & crystal%symrel(2,:,isym), & 5241 & crystal%symrel(3,:,isym), & 5242 & ' ! symmetry rotation matrix isym = ', isym 5243 end do 5244 5245 close (iout) 5246 5247 ! second file is for eigenvalues 5248 ! two file names for each spin, if necessary 5249 do isppol=1,nsppol 5250 filename=trim(fname_radix)//"_BLZTRP."//spinsuffix(isppol)//"energy"//trim(so_suffix) 5251 5252 if (open_file (filename, msg, newunit=iout, form='formatted') /= 0) then 5253 ABI_ERROR(msg) 5254 end if 5255 5256 write (iout, '(a,I5)') "BoltzTraP eigen-energies file generated by ABINIT. ispin = ", isppol 5257 write (iout, '(I7, I7, E20.10, a)') & 5258 & ebands%nkpt, nsppol, ha2ryd*ebands%fermie, ' ! nk, nspin, Fermi level(Ry) : energies below in Ry' 5259 5260 do ikpt=1,ebands%nkpt 5261 ! these need to be in reduced coordinates 5262 write (iout, '(3E20.10, I7, a)') & 5263 & ebands%kptns(1,ikpt), ebands%kptns(2,ikpt), ebands%kptns(3,ikpt), nband, ' ! kpt nband' 5264 do iband=1,nband 5265 ! output in Rydberg 5266 write (iout, '(E20.10)') ha2ryd*ebands%eig(iband, ikpt, isppol) 5267 end do 5268 end do 5269 5270 close (iout) 5271 end do 5272 5273 !this file is for tau_k 5274 if (present (tau_k)) then 5275 do isppol = 1, nsppol 5276 filename= trim(fname_radix)//"_"//spinsuffix(isppol)//"BLZTRP.tau_k" 5277 if (open_file(filename, msg, newunit=iout, form='formatted') /= 0) then 5278 ABI_ERROR(msg) 5279 end if 5280 5281 write (iout, '(a)') "BoltzTraP tau_k file generated by ANADDB." 5282 write (iout, '(I7, I7, E20.10, a)')& 5283 & ebands%nkpt, nsppol, ha2ryd*ebands%fermie, ' ! nk, nspin, Fermi level(Ry) : energies below in Ry' 5284 5285 do ikpt=1,ebands%nkpt 5286 ! these need to be in reduced coordinates 5287 write (iout, '(3E20.10, I7, a)') & 5288 & ebands%kptns(1,ikpt), ebands%kptns(2,ikpt), ebands%kptns(3,ikpt), nband, ' ! kpt nband' 5289 do iband=1,nband 5290 ! output in eV 5291 write (iout, '(E20.10)') tau_k(isppol,ikpt,iband) 5292 end do 5293 end do 5294 close (iout) 5295 end do 5296 5297 end if 5298 5299 end subroutine ebands_prtbltztrp
m_ebands/ebands_prtbltztrp_tau_out [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_prtbltztrp_tau_out
FUNCTION
output files for BoltzTraP code, which integrates Boltzmann transport quantities over the Fermi surface for different T and chemical potentials. Abinit provides all necessary input files: struct, energy, input file, and def file for the unit definitions of fortran files in BT. See http://www.icams.de/content/departments/ams/madsen/boltztrap.html Output T-depedent tau_k, modified from ebands_prtbltztrp
INPUTS
eigen(mband*nkpt*nsppol) = array for holding eigenvalues (hartree) fermie = Fermi level fname_radix = radix of file names for output nband = number of bands nkpt = number of k points. nsppol = 1 for unpolarized, 2 for spin-polarized nsym = number of symmetries in space group rprimd(3,3) = dimensional primitive translations for real space (bohr) symrel = symmetry operations in reduced coordinates, real space to be used in future xred(3,natom) = reduced dimensionless atomic coordinates
OUTPUT
(only writing, printing)
SOURCE
5331 subroutine ebands_prtbltztrp_tau_out (eigen, tempermin, temperinc, ntemper, fermie, fname_radix, kpt, & 5332 nband, nelec, nkpt, nspinor, nsppol, nsym, rprimd, symrel, tau_k) 5333 5334 !Arguments ------------------------------------ 5335 !scalars 5336 integer, intent(in) :: nsym, nband, nkpt, nsppol, nspinor, ntemper 5337 real(dp), intent(in) :: tempermin, temperinc 5338 real(dp), intent(in) :: nelec 5339 character(len=fnlen), intent(in) :: fname_radix 5340 !arrays 5341 real(dp), intent(in) :: fermie(ntemper) 5342 integer, intent(in) :: symrel(3,3,nsym) 5343 real(dp), intent(in) :: kpt(3,nkpt) 5344 real(dp), intent(in) :: eigen(nband, nkpt, nsppol) 5345 real(dp), intent(in) :: rprimd(3,3) 5346 real(dp), intent(in) :: tau_k(ntemper,nsppol,nkpt,nband) 5347 5348 !Local variables------------------------------- 5349 !scalars 5350 integer :: iout, isym, iband, isppol, ikpt, itemp 5351 real(dp) :: Temp 5352 real(dp),parameter :: ha2ryd = two 5353 character(len=500) :: msg 5354 character(len=fnlen) :: filename,appendix 5355 5356 ! ************************************************************************* 5357 5358 !input file for boltztrap: general info, Ef, Nelec, etc... 5359 do itemp = 1, ntemper 5360 write(appendix,"(i0)") itemp 5361 filename= trim(fname_radix)//"_BLZTRP.intrans_"//trim(appendix) 5362 if (open_file(filename, msg, newunit=iout, form="formatted", action="write") /= 0) then 5363 ABI_ERROR(msg) 5364 end if 5365 5366 write (iout, '(a)') "GENE # Format of input: generic format, with Symmetries" 5367 write (iout, '(a)') "0 0 0 0.0 # iskip (not presently used) idebug setgap shiftgap" 5368 write (iout, '(E15.5,a,F10.4,a)') fermie(itemp)*two, " 0.0005 0.4 ", nelec, & 5369 " # Fermilevel (Ry), energy grid spacing, energy span around Fermilevel, number of electrons" 5370 write (iout, '(a)') "CALC # CALC (calculate expansion coeff), NOCALC read from file" 5371 write (iout, '(a)') "3 # lpfac, number of latt-points per k-point" 5372 write (iout, '(a)') "BOLTZ # run mode (only BOLTZ is supported)" 5373 write (iout, '(a)') ".15 # (efcut) energy range of chemical potential" 5374 write (iout, '(2f8.2,a)')& 5375 tempermin+temperinc*dble(itemp),tempermin+temperinc*dble(itemp), " # Tmax, temperature grid spacing" 5376 write (iout, '(2a)') "-1 # energyrange of bands given ",& 5377 "individual DOS output sig_xxx and dos_xxx (xxx is band number)" 5378 write (iout, '(a)') "TETRA # DOS calculation method. Other possibility is TETRA" 5379 write (iout, '(a)') "No # not using model for relaxation time" 5380 write (iout, '(a)') "3 # Number of doping levels coefficients will be output for" 5381 write (iout, '(a)') "-1.e16 0.0d0 1.e16 # Values of doping levels (in carriers / cm^3" 5382 close(iout) 5383 end do 5384 5385 !files file, with association of all units for Boltztrap 5386 filename= trim(fname_radix)//"_BLZTRP.def" 5387 if (open_file(filename, msg, newunit=iout, form="formatted", action="write") /= 0) then 5388 ABI_ERROR(msg) 5389 end if 5390 write (iout, '(3a)') "5, '", trim(fname_radix)//"_BLZTRP", ".intrans', 'old', 'formatted',0" 5391 write (iout, '(3a)') "6, '", trim(fname_radix)//"_BLZTRP", ".outputtrans', 'unknown', 'formatted',0" 5392 write (iout, '(3a)') "20,'", trim(fname_radix)//"_BLZTRP", ".struct', 'old', 'formatted',0" 5393 if (nspinor == 1) then 5394 write (iout, '(3a)') "10,'", trim(fname_radix)//"_BLZTRP", ".energy', 'old', 'formatted',0" 5395 else if (nspinor == 2) then 5396 write (iout, '(3a)') "10,'", trim(fname_radix)//"_BLZTRP", ".energyso', 'old', 'formatted',0" 5397 end if 5398 write (iout, '(3a)') "10,'", trim(fname_radix)//"_BLZTRP", ".energy', 'old', 'formatted',0" 5399 write (iout, '(3a)') "11,'", trim(fname_radix)//"_BLZTRP", ".tau_k', 'old', 'formatted',0" 5400 write (iout, '(3a)') "48,'", trim(fname_radix)//"_BLZTRP", ".engre', 'unknown', 'unformatted',0" 5401 write (iout, '(3a)') "49,'", trim(fname_radix)//"_BLZTRP", ".transdos', 'unknown', 'formatted',0" 5402 write (iout, '(3a)') "50,'", trim(fname_radix)//"_BLZTRP", ".sigxx', 'unknown', 'formatted',0" 5403 write (iout, '(3a)') "51,'", trim(fname_radix)//"_BLZTRP", ".sigxxx', 'unknown', 'formatted',0" 5404 write (iout, '(3a)') "21,'", trim(fname_radix)//"_BLZTRP", ".trace', 'unknown', 'formatted',0" 5405 write (iout, '(3a)') "22,'", trim(fname_radix)//"_BLZTRP", ".condtens', 'unknown', 'formatted',0" 5406 write (iout, '(3a)') "24,'", trim(fname_radix)//"_BLZTRP", ".halltens', 'unknown', 'formatted',0" 5407 write (iout, '(3a)') "25,'", trim(fname_radix)//"_BLZTRP", ".trace_fixdoping', 'unknown', 'formatted',0" 5408 write (iout, '(3a)') "26,'", trim(fname_radix)//"_BLZTRP", ".condtens_fixdoping', 'unknown', 'formatted',0" 5409 write (iout, '(3a)') "27,'", trim(fname_radix)//"_BLZTRP", ".halltens_fixdoping', 'unknown', 'formatted',0" 5410 write (iout, '(3a)') "30,'", trim(fname_radix)//"_BLZTRP", "_BZ.dx', 'unknown', 'formatted',0" 5411 write (iout, '(3a)') "31,'", trim(fname_radix)//"_BLZTRP", "_fermi.dx', 'unknown', 'formatted',0" 5412 write (iout, '(3a)') "32,'", trim(fname_radix)//"_BLZTRP", "_sigxx.dx', 'unknown', 'formatted',0" 5413 write (iout, '(3a)') "33,'", trim(fname_radix)//"_BLZTRP", "_sigyy.dx', 'unknown', 'formatted',0" 5414 write (iout, '(3a)') "34,'", trim(fname_radix)//"_BLZTRP", "_sigzz.dx', 'unknown', 'formatted',0" 5415 write (iout, '(3a)') "35,'", trim(fname_radix)//"_BLZTRP", "_band.dat', 'unknown', 'formatted',0" 5416 write (iout, '(3a)') "36,'", trim(fname_radix)//"_BLZTRP", "_band.gpl', 'unknown', 'formatted',0" 5417 write (iout, '(3a)') "37,'", trim(fname_radix)//"_BLZTRP", "_deriv.dat', 'unknown', 'formatted',0" 5418 write (iout, '(3a)') "38,'", trim(fname_radix)//"_BLZTRP", "_mass.dat', 'unknown', 'formatted',0" 5419 close(iout) 5420 5421 !file is for geometry symmetries etc 5422 filename= trim(fname_radix)//"_BLZTRP.struct" 5423 if (open_file(filename, msg, newunit=iout, form="formatted", action="write") /= 0) then 5424 ABI_ERROR(msg) 5425 end if 5426 write (iout, '(a)') "BoltzTraP geometry file generated by ABINIT." 5427 5428 !here we need to print out the unit cell vectors 5429 write (iout, '(3E20.10)') rprimd(:,1) 5430 write (iout, '(3E20.10)') rprimd(:,2) 5431 write (iout, '(3E20.10)') rprimd(:,3) 5432 write (iout, '(I7)') nsym 5433 5434 do isym=1, nsym 5435 write (iout,'(3(3I5,2x), a, I5)') & 5436 symrel(1,:,isym), symrel(2,:,isym), symrel(3,:,isym), ' ! symmetry rotation matrix isym = ', isym 5437 end do 5438 close (iout) 5439 5440 !second file is for eigenvalues 5441 if (nspinor == 1) then 5442 filename= trim(fname_radix)//"_BLZTRP.energy" 5443 else if (nspinor == 2) then 5444 filename= trim(fname_radix)//"_BLZTRP.energyso" 5445 end if 5446 5447 if (open_file(filename, msg, newunit=iout, form="formatted", action="write") /= 0) then 5448 ABI_ERROR(msg) 5449 end if 5450 write (iout, '(a)') "BoltzTraP eigen-energies file generated by ABINIT." 5451 write (iout, '(I7, I7, E20.10, a)') nkpt, nsppol, ha2ryd*fermie(1), ' ! nk, nspin, Fermi level(Ry) : energies below in Ry' 5452 do isppol = 1, nsppol 5453 do ikpt = 1, nkpt 5454 ! these need to be in reduced coordinates 5455 write (iout, '(3E20.10, I7, a)') kpt(1,ikpt), kpt(2,ikpt), kpt(3,ikpt), nband, ' ! kpt nband' 5456 do iband = 1, nband 5457 ! output in eV 5458 write (iout, '(E20.10)') ha2ryd*eigen(iband, ikpt, isppol) 5459 end do 5460 end do 5461 end do 5462 close (iout) 5463 5464 !this file is for tau_k 5465 do itemp = 1, ntemper 5466 Temp=tempermin+temperinc*dble(itemp) 5467 5468 write(appendix,"(i0)") itemp 5469 filename= trim(fname_radix)//"_BLZTRP.tau_k_"//trim(appendix) 5470 if (open_file(filename, msg, newunit=iout, form="formatted", action="write") /= 0) then 5471 ABI_ERROR(msg) 5472 end if 5473 write (iout, '(a,f12.6)') "BoltzTraP tau_k file generated by ANADDB for T= ", Temp 5474 write (iout, '(I7, I7, E20.10, a)') nkpt, nsppol, ha2ryd*fermie(itemp), & 5475 ' ! nk, nspin, Fermi level(Ry) : energies below in Ry' 5476 do isppol = 1, nsppol 5477 do ikpt = 1, nkpt 5478 ! these need to be in reduced coordinates 5479 write (iout, '(3E20.10, I7, a)') kpt(1,ikpt), kpt(2,ikpt), kpt(3,ikpt), nband, ' ! kpt nband' 5480 do iband = 1, nband 5481 ! output in sec 5482 write (iout, '(E20.10)') tau_k(itemp,isppol,ikpt,iband) 5483 end do 5484 end do 5485 end do 5486 close (iout) 5487 end do 5488 5489 end subroutine ebands_prtbltztrp_tau_out
m_ebands/ebands_report_gap [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_report_gap
FUNCTION
Print info on the fundamental and direct gap.
INPUTS
ebands<ebands_t>=Info on the band structure, the smearing technique and the physical temperature used. [header]=Optional title. [unit]=Optional unit for output (std_out if not specified) [mode_paral]=Either "COLL" or "PERS", former is default.
OUTPUT
writing. [gaps(3,nsppol)]=Fundamental and direct gaps. The third index corresponds to a "status": 0.0dp if gaps were not computed (because there are only valence bands); -1.0dp if the system (or spin-channel) is metallic; 1.0dp if the gap has been computed.
SOURCE
2800 subroutine ebands_report_gap(ebands, header, unit, mode_paral, gaps) 2801 2802 !Arguments ------------------------------------ 2803 !scalars 2804 integer,intent(in),optional :: unit 2805 character(len=4),intent(in),optional :: mode_paral 2806 character(len=*),intent(in),optional :: header 2807 class(ebands_t),intent(in) :: ebands 2808 !arrays 2809 real(dp),optional,intent(out) :: gaps(3,ebands%nsppol) 2810 2811 !Local variables------------------------------- 2812 !scalars 2813 integer :: ikibz,nband_k,spin,nsppol,ikopt,ivk,ick,ivb,icb,unt,first 2814 real(dp),parameter :: tol_fermi = tol6 2815 real(dp) :: fun_gap,opt_gap 2816 logical :: ismetal 2817 character(len=4) :: my_mode 2818 character(len=500) :: msg 2819 !arrays 2820 integer :: val_idx(ebands%nkpt,ebands%nsppol) 2821 real(dp) :: top_valence(ebands%nkpt),bot_conduct(ebands%nkpt) 2822 2823 ! ********************************************************************* 2824 2825 nsppol = ebands%nsppol 2826 2827 unt =std_out; if (PRESENT(unit )) unt =unit 2828 my_mode='COLL' ; if (PRESENT(mode_paral)) my_mode=mode_paral 2829 2830 if (PRESENT(gaps)) gaps=zero 2831 2832 val_idx(:,:) = ebands_get_valence_idx(ebands, tol_fermi) 2833 first = 0 2834 2835 ! Initialize the return status for the gaps 2836 if (PRESENT(gaps)) gaps(1:3,1:nsppol)=zero 2837 2838 do spin=1,nsppol 2839 2840 ! No output if system i metallic 2841 ismetal=ANY(val_idx(:,spin)/=val_idx(1,spin)) 2842 if (ismetal .or. (ebands%occopt==9)) then 2843 if (PRESENT(gaps)) gaps(3,nsppol)=-one 2844 cycle 2845 endif 2846 2847 first=first+1 2848 if (first==1) then 2849 msg=ch10 2850 if (PRESENT(header)) msg=ch10//' === '//TRIM(ADJUSTL(header))//' === ' 2851 call wrtout(unt,msg,my_mode) 2852 end if 2853 2854 ivb=val_idx(1,spin) 2855 icb=ivb+1 2856 2857 do ikibz=1,ebands%nkpt 2858 nband_k = ebands%nband(ikibz+(spin-1)*ebands%nkpt) 2859 top_valence(ikibz) = ebands%eig(ivb,ikibz,spin) 2860 if (icb>nband_k) then 2861 GOTO 10 ! Only occupied states are present, no output! 2862 end if 2863 bot_conduct(ikibz) = ebands%eig(icb,ikibz,spin) 2864 end do 2865 2866 ! Get minimum of the direct Gap 2867 ikopt= imin_loc(bot_conduct-top_valence) 2868 opt_gap=bot_conduct(ikopt)-top_valence(ikopt) 2869 2870 ! Get fundamental Gap 2871 ick = imin_loc(bot_conduct) 2872 ivk = imax_loc(top_valence) 2873 fun_gap = ebands%eig(icb,ick,spin)-ebands%eig(ivb,ivk,spin) 2874 2875 write(msg,'(a,i2,a,2(a,f8.4,a,3f8.4,a),33x,a,3f8.4)')& 2876 ' >>>> For spin ',spin,ch10,& 2877 ' Minimum direct gap = ',opt_gap*Ha_eV,' [eV], located at k-point : ',ebands%kptns(:,ikopt),ch10,& 2878 ' Fundamental gap = ',fun_gap*Ha_eV,' [eV], Top of valence bands at : ',ebands%kptns(:,ivk),ch10, & 2879 ' Bottom of conduction at : ',ebands%kptns(:,ick) 2880 call wrtout(unt,msg,my_mode) 2881 2882 if (present(gaps)) gaps(:,spin) = [fun_gap, opt_gap, one] 2883 end do !spin 2884 2885 return 2886 2887 10 continue 2888 call wrtout(std_out, "Not enough states to calculate the band gap.", "COLL") 2889 2890 end subroutine ebands_report_gap
m_ebands/ebands_set_extrael [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_set_extrael
FUNCTION
Add extrael to ebands%nelect. Set value of ebands%extrael Recompute Fermi level from eigenenergies and new occupation numbers according to the smearing scheme defined by occopt (and smearing width tsmear or tphysel) as well as entropy and derivative of occupancies wrt the energy for each band and k point.
INPUTS
nelect=New number of electrons nholes=New number of excited holes extrael=Number of electrons be added in units. Negative to add holes spinmagntarget=if differ from -99.99d0, fix the spin polarization (in Bohr magneton) [prtvol]=Verbosity level
OUTPUT
msg=String describing the changes in fermie and nelect.
NOTES
The routine assumes metallic occupation scheme and will abort it this condition is not satisfied. Use ebands_set_scheme before calling this routine, if you have a semiconductor.
SOURCE
2595 subroutine ebands_set_extrael(ebands, nelect, nholes, spinmagntarget, msg, prtvol) 2596 2597 !Arguments ------------------------------------ 2598 !scalars 2599 class(ebands_t),intent(inout) :: ebands 2600 integer,optional,intent(in) :: prtvol 2601 real(dp),intent(in) :: nelect,nholes,spinmagntarget 2602 character(len=*),intent(out) :: msg 2603 2604 !Local variables------------------------------- 2605 !scalars 2606 integer :: my_prtvol 2607 real(dp) :: prev_fermie,prev_fermih,prev_nelect,prev_nholes 2608 2609 ! ************************************************************************* 2610 2611 my_prtvol = 0; if (present(prtvol)) my_prtvol = prtvol 2612 2613 if (.not. ebands_has_metal_scheme(ebands)) then 2614 ABI_ERROR("set_extrael assumes a metallic occupation scheme. Use ebands_set_scheme!") 2615 end if 2616 2617 prev_fermie = ebands%fermie; prev_nelect = ebands%nelect 2618 prev_fermih = ebands%fermie; prev_nholes = zero 2619 ! Here we set the value of extrael 2620 ebands%extrael = nelect-nholes 2621 ebands%nelect = ebands%nelect + ebands%extrael 2622 if (ebands%occopt /= 9) then 2623 ebands%ne_qFD = zero 2624 ebands%nh_qFD = zero 2625 else 2626 prev_fermie = ebands%fermie; prev_nelect = ebands%ne_qFD 2627 prev_fermih = ebands%fermih; prev_nholes = ebands%nh_qFD 2628 ebands%ne_qFD = nelect 2629 ebands%nh_qFD = nholes 2630 end if 2631 2632 call ebands_update_occ(ebands, spinmagntarget, prtvol=my_prtvol) 2633 2634 if (ebands%occopt/=9) then 2635 write(msg,"(2(a,es16.6),a,2(a,es16.6))")& 2636 " Old fermi level: ",prev_fermie,", with nelect: ",prev_nelect,ch10,& 2637 " New fermi level: ",ebands%fermie,", with nelect: ",ebands%nelect 2638 call wrtout(std_out, msg) 2639 else 2640 write(msg,"(2(a,es16.6),a,2(a,es16.6))")& 2641 " Old electron fermi level: ",prev_fermie,", with nelect: ",prev_nelect,ch10,& 2642 " New electron fermi level: ",ebands%fermie,", with nelect: ",ebands%ne_qFD 2643 call wrtout(std_out, msg) 2644 write(msg,"(2(a,es16.6),a,2(a,es16.6))")& 2645 " Old holes fermi level: ",prev_fermih,", with nelect: ",prev_nelect-prev_nholes,ch10,& 2646 " New holes fermi level: ",ebands%fermih,", with nholes: ",ebands%nelect-ebands%nh_qFD 2647 call wrtout(std_out, msg) 2648 end if 2649 2650 end subroutine ebands_set_extrael
m_ebands/ebands_set_fermie [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_set_fermie
FUNCTION
Set the new Fermi level from eigenenergies eigen and change the number of electrons Compute also new occupation numbers at each k point, from eigenenergies eigen, according to the smearing scheme defined by occopt (and smearing width tsmear or tphysel) as well as entropy and derivative of occupancies wrt the energy for each band and k point.
INPUTS
fermie=New fermi level
OUTPUT
msg=String describing the changes in fermie and nelect.
NOTES
The routine assumes metallic occupation scheme and will abort it this condition is not satisfied. Use ebands_set_scheme before calling this routine, if you have a semiconductor.
SOURCE
2507 subroutine ebands_set_fermie(ebands, fermie, msg) 2508 2509 !Arguments ------------------------------------ 2510 !scalars 2511 class(ebands_t),intent(inout) :: ebands 2512 real(dp),intent(in) :: fermie 2513 character(len=*),intent(out) :: msg 2514 2515 !Local variables------------------------------- 2516 !scalars 2517 integer,parameter :: option1=1, unitdos0 = 0 2518 integer :: mband, nkpt, nsppol 2519 real(dp),parameter :: dosdeltae0 = zero 2520 real(dp) :: prev_fermie, prev_nelect, maxocc 2521 !arrays 2522 real(dp),allocatable :: doccde(:),occ(:),eigen(:) 2523 2524 ! ************************************************************************* 2525 2526 if (ebands%occopt == 9) then 2527 ABI_ERROR("set_fermie unavailable when occopt 9") 2528 end if 2529 if (.not. ebands_has_metal_scheme(ebands)) then 2530 ABI_ERROR("set_fermie assumes a metallic occupation scheme. Use ebands_set_scheme before calling ebands_set_fermie!") 2531 end if 2532 2533 prev_fermie = ebands%fermie; prev_nelect = ebands%nelect 2534 2535 ! newocc assumes eigenvalues and occupations packed in 1d-vector!! 2536 mband = ebands%mband 2537 nkpt = ebands%nkpt 2538 nsppol = ebands%nsppol 2539 maxocc = two / (nsppol*ebands%nspinor) 2540 2541 ABI_MALLOC(eigen, (mband*nkpt*nsppol)) 2542 call get_eneocc_vect(ebands, 'eig', eigen) 2543 ABI_MALLOC(occ, (mband*nkpt*nsppol)) 2544 ABI_MALLOC(doccde, (mband*nkpt*nsppol)) 2545 2546 ! Get the total number of electrons nelect, given the new fermi energy. 2547 call getnel(doccde,dosdeltae0,eigen,ebands%entropy,fermie,fermie,maxocc,mband,ebands%nband,& 2548 ebands%nelect,nkpt,nsppol,occ,ebands%occopt,option1,ebands%tphysel,ebands%tsmear,unitdos0,& 2549 ebands%wtk,1,ebands%nband(1)) 2550 2551 ! Save changes in ebands%. 2552 ebands%fermie = fermie 2553 call put_eneocc_vect(ebands,'occ' ,occ) 2554 call put_eneocc_vect(ebands,'doccde',doccde) 2555 2556 ABI_FREE(eigen) 2557 ABI_FREE(occ) 2558 ABI_FREE(doccde) 2559 2560 write(msg,"(2(a,es16.6),a,2(a,es16.6))") & 2561 " Old fermi level: ",prev_fermie,", with nelect: ",prev_nelect,ch10, & 2562 " New fermi level: ",ebands%fermie,", with nelect: ",ebands%nelect 2563 2564 end subroutine ebands_set_fermie
m_ebands/ebands_set_scheme [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_set_scheme
FUNCTION
Set the occupation scheme and re-calculate new occupation numbers, the Fermi level and the Max occupied band index for each spin channel starting from the the knowledge of eigenvalues. See ebands_update_occ for more info.
INPUTS
occopt=Occupation options (see input variable) tsmear=Temperature of smearing. spinmagntarget=if differ from -99.99d0, fix the spin polarization (in Bohr magneton) prtvol=Verbosity level (0 for lowest level) [update_occ]=False to avoid recomputing occupation factors (mainly used when a call to set_scheme is followed by another call to set_extrael (update_occ is expensive for large k-meshes). Default: True.
SOURCE
2449 subroutine ebands_set_scheme(ebands, occopt, tsmear, spinmagntarget, prtvol, update_occ) 2450 2451 !Arguments ------------------------------------ 2452 !scalars 2453 class(ebands_t),intent(inout) :: ebands 2454 integer,intent(in) :: occopt 2455 integer,intent(in) :: prtvol 2456 real(dp),intent(in) :: tsmear, spinmagntarget 2457 logical,optional,intent(in) :: update_occ 2458 2459 !Local variables------------------------------- 2460 !scalars 2461 logical :: my_update_occ 2462 2463 ! ************************************************************************* 2464 2465 my_update_occ = .True.; if (present(update_occ)) my_update_occ = update_occ 2466 2467 if (prtvol > 10) then 2468 call wrtout(std_out, " Changing occupation scheme in electron bands") 2469 call wrtout(std_out, sjoin(" occopt:", itoa(ebands%occopt), " ==> ", itoa(occopt))) 2470 call wrtout(std_out, sjoin(" tsmear:", ftoa(ebands%tsmear), " ==> ", ftoa(tsmear))) 2471 end if 2472 2473 ebands%occopt = occopt; ebands%tsmear = tsmear 2474 2475 if (my_update_occ) then 2476 call ebands_update_occ(ebands, spinmagntarget, prtvol=prtvol) 2477 if (prtvol > 10) call wrtout(std_out, sjoin(' Fermi level is now:', ftoa(ebands%fermie))) 2478 end if 2479 2480 end subroutine ebands_set_scheme
m_ebands/ebands_sort [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_sort
FUNCTION
Sort eigvalues_k in ascending order and reorder arrays depending on nband_k Mainly used when interpolating band energies as the interpolator may not produce ordered eigenvalues and there are routines whose implementation assumes eig(b) <= eig(b+1)
SIDE EFFECTS
ebands<ebands_t> = Object with input energies sorted in output.
SOURCE
4140 subroutine ebands_sort(self) 4141 4142 !Arguments ------------------------------------ 4143 !scalars 4144 class(ebands_t),intent(inout) :: self 4145 4146 !Local variables------------------------------- 4147 !scalars 4148 integer :: spin, ik_ibz, band, nband_k 4149 !arrays 4150 integer :: iperm_k(self%mband) 4151 4152 ! ********************************************************************* 4153 4154 do spin=1,self%nsppol 4155 do ik_ibz=1,self%nkpt 4156 nband_k = self%nband(ik_ibz + (spin - 1) * self%nkpt) 4157 iperm_k = [(band, band=1, nband_k)] 4158 call sort_dp(nband_k, self%eig(:, ik_ibz, spin), iperm_k, tol12) 4159 4160 ! Shuffle other arrays depending on nband_k 4161 self%occ(1:nband_k, ik_ibz, spin) = self%occ(iperm_k(1:nband_k), ik_ibz, spin) 4162 self%doccde(1:nband_k, ik_ibz, spin) = self%doccde(iperm_k(1:nband_k), ik_ibz, spin) 4163 !if (allocated(self%velocity)) then 4164 ! self%velocity(:, 1:nband_k, ik_ibz, spin) = self%velocity(:, iperm_k(1:nband_k), ik_ibz, spin) 4165 !end if 4166 end do 4167 end do 4168 4169 end subroutine ebands_sort
m_ebands/ebands_update_occ [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_update_occ
FUNCTION
Calculate new occupation numbers, the Fermi level and the Max occupied band index for each spin channel starting from the the knowledge of eigenvalues.
INPUTS
ebands<ebands_t>=Info on the band structure, the smearing technique and the physical temperature used. spinmagntarget=if differ from -99.99d0, fix the spin polarization (in Bohr magneton) [stmbias]= [prtvol]=Verbosity level (0 for lowest level) [fermie_to_zero]=If True, fermie is set to zero and energies are shifted accordingly. Default: False
OUTPUT
see also SIDE EFFECTS.
SIDE EFFECTS
=== For metallic occupation the following quantites are recalculated === %fermie=the new Fermi energy %entropy=the new entropy associated with the smearing. %occ(mband,nkpt,nsppol)=occupation numbers %doccde(mband,nkpt,nsppol)=derivative of occupancies wrt the energy for each band and k point === In case of semiconductors === All the quantitities in ebands are left unchanged with the exception of: %fermie=Redefined so that it is in the middle of the gap %entropy=Set to zero
SOURCE
2278 subroutine ebands_update_occ(ebands, spinmagntarget, stmbias, prtvol, fermie_to_zero) 2279 2280 !Arguments ------------------------------------ 2281 !scalars 2282 class(ebands_t),intent(inout) :: ebands 2283 integer,optional,intent(in) :: prtvol 2284 real(dp),intent(in) :: spinmagntarget 2285 real(dp),optional,intent(in) :: stmbias 2286 logical,optional,intent(in) :: fermie_to_zero 2287 2288 !Local variables------------------------------- 2289 !scalars 2290 integer :: band,mband,ikibz,nkpt,spin,nsppol,my_prtvol,nband_k 2291 real(dp) :: entropy,fermie,fermih,stmbias_local,ndiff,cbot,vtop,maxocc 2292 character(len=500) :: msg 2293 !arrays 2294 real(dp) :: nelect_spin(ebands%nsppol),condbottom(ebands%nsppol),valencetop(ebands%nsppol) 2295 real(dp),allocatable :: doccde(:),occ(:),eigen(:) 2296 2297 ! ************************************************************************* 2298 2299 my_prtvol = 0; if (PRESENT(prtvol )) my_prtvol = prtvol 2300 stmbias_local = zero; if (PRESENT(stmbias)) stmbias_local = stmbias 2301 2302 if (ebands_has_metal_scheme(ebands)) then 2303 ! Compute new occupation numbers if metallic occupation. 2304 if (my_prtvol > 10) then 2305 call wrtout(std_out, sjoin(' metallic scheme: calling newocc with spinmagntarget:', ftoa(spinmagntarget, fmt="f9.5"))) 2306 end if 2307 2308 ! newocc assumes eigenvalues and occupations packed in 1d-vector!! 2309 mband = ebands%mband; nkpt = ebands%nkpt; nsppol = ebands%nsppol 2310 2311 ABI_MALLOC(eigen, (mband*nkpt*nsppol)) 2312 call get_eneocc_vect(ebands, 'eig', eigen) 2313 2314 ABI_MALLOC(occ, (mband*nkpt*nsppol)) 2315 ABI_MALLOC(doccde, (mband*nkpt*nsppol)) 2316 2317 call newocc(doccde,eigen,entropy,fermie,fermih,ebands%ivalence,spinmagntarget,mband,ebands%nband,& 2318 ebands%nelect,ebands%ne_qFD,ebands%nh_qFD,ebands%nkpt,ebands%nspinor,ebands%nsppol,occ,ebands%occopt,& 2319 my_prtvol,ebands%tphysel,ebands%tsmear,ebands%wtk,stmbias=stmbias_local) 2320 2321 ! Save output in ebands%. 2322 ebands%entropy = entropy 2323 ebands%fermie = fermie 2324 ebands%fermih = fermih 2325 call put_eneocc_vect(ebands, 'occ', occ) 2326 call put_eneocc_vect(ebands, 'doccde', doccde) 2327 ABI_FREE(eigen) 2328 ABI_FREE(occ) 2329 ABI_FREE(doccde) 2330 2331 else 2332 ! Semiconductor (non magnetic case) 2333 maxocc = two / (ebands%nsppol*ebands%nspinor) 2334 ! 2335 ! FIXME here there is an inconsistency btw the GW code and Abinit 2336 ! In ABINIT, Fermi is set to the HOMO level while in GW fermi is at midgap 2337 ! In case of crystal systems, the later convention should be preferable. 2338 ! Anyway we have to decide and follow a unique convention to avoid problems. 2339 ! 2340 ! Occupation factors MUST be initialized 2341 !if (ALL(ABS(ebands%occ) < tol6)) then 2342 if (ebands%occopt /= 2) then 2343 ABI_CHECK(ebands%nelect == nint(ebands%nelect), "nelect should be integer") 2344 mband = nint((ebands%nelect * ebands%nspinor) / 2) 2345 ebands%occ = zero 2346 ebands%occ(1:mband,:,:) = maxocc 2347 !ABI_ERROR("Occupation factors are not initialized, likely due to scf = -2") 2348 end if 2349 2350 ! Calculate the valence index for each spin channel. 2351 do spin=1,ebands%nsppol 2352 valencetop(spin) = smallest_real 2353 condbottom(spin) = greatest_real 2354 do ikibz=1,ebands%nkpt 2355 nband_k = ebands%nband(ikibz + (spin-1)*ebands%nkpt) 2356 do band=1,nband_k 2357 if (ebands%occ(band,ikibz,spin) / maxocc > one-tol6 .and. valencetop(spin) < ebands%eig(band,ikibz,spin)) then 2358 valencetop(spin) = ebands%eig(band,ikibz,spin) 2359 end if 2360 if (ebands%occ(band,ikibz,spin) / maxocc < tol6 .and. condbottom(spin) > ebands%eig(band,ikibz,spin)) then 2361 condbottom(spin) = ebands%eig(band,ikibz,spin) 2362 end if 2363 end do 2364 end do 2365 end do 2366 2367 vtop = MAXVAL(valencetop) 2368 cbot = MINVAL(condbottom) 2369 2370 write(msg,'(3(a,f8.4,2a))') & 2371 " Top of valence: ", vtop * Ha_eV," (eV)", ch10, & 2372 " Bottom of conduction: ", cbot * Ha_eV, " (eV)", ch10, & 2373 " Fundamental gap:", (cbot - vtop) * Ha_eV, " (eV)", ch10 2374 call wrtout(std_out, msg) 2375 2376 if (ebands%nsppol == 2) then 2377 if (ABS(vtop - MINVAL(valencetop)) > tol6) then 2378 call wrtout(std_out, sjoin(' Top of valence is spin: ', itoa(imax_loc(valencetop)))) 2379 end if 2380 if (ABS(cbot - MAXVAL(condbottom)) > tol6) then 2381 call wrtout(std_out, ' Bottom of conduction is spin: ', itoa(imin_loc(condbottom))) 2382 end if 2383 end if 2384 2385 ! Save results. Here I dont know if it is better to be consistent with the abinit convention i.e fermi = vtop 2386 ebands%entropy = zero 2387 ebands%fermie = (vtop + cbot) / 2 2388 if (ABS(cbot - vtop) < tol4) ebands%fermie = vtop ! To avoid error on the last digit 2389 end if 2390 2391 call wrtout(std_out, sjoin(' Fermi level: ', ftoa(ebands%fermie * Ha_eV, fmt="f8.4"), " (eV)", ch10)) 2392 2393 ! Compute number of electrons for each spin channel. 2394 nelect_spin(:)=zero 2395 do spin=1,ebands%nsppol 2396 do ikibz=1,ebands%nkpt 2397 nband_k = ebands%nband(ikibz+(spin-1)*ebands%nkpt) 2398 nelect_spin(spin)= nelect_spin(spin) + ebands%wtk(ikibz) * sum(ebands%occ(1:nband_k,ikibz,spin)) 2399 end do 2400 end do 2401 2402 ndiff = ebands%nelect - SUM(nelect_spin) 2403 if (my_prtvol > 0) then 2404 write(msg,'(2a,f6.2,2a,f7.4)')ch10,& 2405 ' Total number of electrons: ', sum(nelect_spin),ch10,& 2406 ' Input and calculated no. of electrons differ by ',ndiff 2407 call wrtout(std_out, msg) 2408 end if 2409 2410 if (ABS(ndiff) > 5.d-2*ebands%nelect) then 2411 write(msg,'(2a,2(a,es12.4))') & 2412 'Too large difference in number of electrons:,',ch10,& 2413 'Expected = ',ebands%nelect,' Calculated = ',sum(nelect_spin) 2414 ABI_ERROR(msg) 2415 end if 2416 2417 if (present(fermie_to_zero)) then 2418 if (fermie_to_zero) then 2419 ebands%eig = ebands%eig - ebands%fermie 2420 ebands%fermih = ebands%fermih - ebands%fermie 2421 ebands%fermie = zero 2422 end if 2423 end if 2424 2425 end subroutine ebands_update_occ
m_ebands/ebands_vcbm_range_from_gaps [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_vcbm_range_from_gaps
FUNCTION
Find band and energy range for states close to the CBM/VBM given input energies in ebands and gaps. Return exit status and error message in msg.
INPUTS
gaps<gaps_t>=Object with info on the gaps. erange(2)=Energy range for holes and electrons. Only those states whose relative position wrt to the VBM/CBM is <= than erange are icluded. Note that relative positions are always positive (even for holes). Use a negative value to exclude either holes or electrons.
OUTPUT
e_lowhigh(2)=min and Max energy. band_lowhigh=min and Max band index. [ks_range]: For each spin and k-point, the min and max band index included in the output set. if (ik, spin) is not included then ib_work(1, ik, spin) > ib_work(2, ik, spin) = -huge(1)
SOURCE
1630 integer function ebands_vcbm_range_from_gaps(ebands, gaps, erange, e_lowhigh, band_lowhigh, ks_range, msg) result(ierr) 1631 1632 !Arguments ------------------------------------ 1633 !scalars 1634 class(ebands_t),intent(in) :: ebands 1635 class(gaps_t),intent(in) :: gaps 1636 real(dp),intent(in) :: erange(2) 1637 real(dp),intent(out) :: e_lowhigh(2) 1638 integer,intent(out) :: band_lowhigh(2) 1639 integer,optional,intent(out) :: ks_range(2, ebands%nkpt, ebands%nsppol) 1640 character(len=*),intent(out) :: msg 1641 1642 !Local variables------------------------------- 1643 integer :: band, ik, spin, band_low, band_high 1644 real(dp) :: cmin, vmax, ee, elow, ehigh 1645 integer,allocatable :: ib_work(:,:,:) 1646 1647 ! ************************************************************************* 1648 1649 ABI_MALLOC(ib_work, (2, ebands%nkpt, ebands%nsppol)) 1650 elow = huge(one); ehigh = -huge(one) 1651 band_low = huge(1); band_high = -huge(1) 1652 1653 ierr = 1 1654 do spin=1,ebands%nsppol 1655 ! Get cmb and vbm with some tolerance 1656 vmax = gaps%vb_max(spin) + tol2 * eV_Ha 1657 cmin = gaps%cb_min(spin) - tol2 * eV_Ha 1658 do ik=1,ebands%nkpt 1659 ib_work(1, ik, spin) = huge(1) 1660 ib_work(2, ik, spin) = -huge(1) 1661 do band=1,ebands%nband(ik+(spin-1)*ebands%nkpt) 1662 ee = ebands%eig(band, ik, spin) 1663 if (erange(1) > zero) then 1664 if (ee <= vmax .and. vmax - ee <= erange(1)) then 1665 ib_work(1, ik, spin) = min(ib_work(1, ik, spin), band) 1666 ib_work(2, ik, spin) = max(ib_work(2, ik, spin), band) 1667 elow = min(elow, ee); ehigh = max(ehigh, ee) 1668 band_low = min(band_low, band); band_high = max(band_high, band) 1669 !write(std_out, *), "Adding valence", band 1670 end if 1671 end if 1672 if (erange(2) > zero) then 1673 if (ee >= cmin .and. ee - cmin <= erange(2)) then 1674 ib_work(1, ik, spin) = min(ib_work(1, ik, spin), band) 1675 ib_work(2, ik, spin) = max(ib_work(2, ik, spin), band) 1676 elow = min(elow, ee); ehigh = max(ehigh, ee) 1677 band_low = min(band_low, band); band_high = max(band_high, band) 1678 !write(std_out, *)"Adding conduction", band 1679 end if 1680 end if 1681 end do 1682 end do 1683 end do 1684 1685 e_lowhigh = [elow, ehigh] 1686 band_lowhigh = [band_low, band_high] 1687 1688 if (present(ks_range)) ks_range = ib_work 1689 ABI_FREE(ib_work) 1690 1691 ! Set exit status and msg. Caller will handle it. 1692 ierr = 0; msg = "" 1693 if (elow > ehigh) then 1694 ierr = 1 1695 write(msg, *)"Cannot find states close to the band edges with erange: ", erange 1696 end if 1697 1698 end function ebands_vcbm_range_from_gaps
m_ebands/ebands_write [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_write
FUNCTION
Driver routine to write bands in different (txt) formats. This routine should be called by a single processor.
INPUTS
prtebands=Flag selecting the output format: 0 --> None 1 --> xmgrace 2 --> gnuplot (not coded yet) 3 --> EIG format (not coded yet) prefix=Prefix for output filename. [kptbounds(:,:)]=Optional argument giving the extrema of the k-path.
OUTPUT
Only writing.
SOURCE
5516 subroutine ebands_write(ebands, prtebands, prefix, kptbounds) 5517 5518 !Arguments ------------------------------------ 5519 !scalars 5520 integer,intent(in) :: prtebands 5521 type(ebands_t),intent(in) :: ebands 5522 character(len=*),intent(in) :: prefix 5523 real(dp),optional,intent(in) :: kptbounds(:,:) 5524 5525 ! ********************************************************************* 5526 5527 select case (prtebands) 5528 case (0) 5529 return 5530 case (1) 5531 !call wrtout(std_out, sjoin(" Writing interpolated bands to:", path) 5532 if (present(kptbounds)) then 5533 call ebands_write_xmgrace(ebands, strcat(prefix, "_EBANDS.agr"), kptbounds=kptbounds) 5534 else 5535 call ebands_write_xmgrace(ebands, strcat(prefix, "_EBANDS.agr")) 5536 end if 5537 case (2) 5538 !call wrtout(std_out, sjoin(" Writing interpolated bands to:", path) 5539 if (present(kptbounds)) then 5540 call ebands_write_gnuplot(ebands, prefix, kptbounds=kptbounds) 5541 else 5542 call ebands_write_gnuplot(ebands, prefix) 5543 end if 5544 case default 5545 ABI_WARNING(sjoin("Unsupported value for prtebands:", itoa(prtebands))) 5546 end select 5547 5548 end subroutine ebands_write
m_ebands/ebands_write_bxsf [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_write_bxsf
FUNCTION
Write 3D energies for Fermi surface visualization (XSF format)
INPUTS
ebands<ebands_t>=The object describing the band structure. crystal<crystal_t>=Info on unit cell and symmetries. fname=File name for output.
OUTPUT
ierr=Status error.
SIDE EFFECTS
Produce BXSF file.
SOURCE
2212 integer function ebands_write_bxsf(ebands, crystal, fname) result(ierr) 2213 2214 !Arguments ------------------------------------ 2215 !scalars 2216 character(len=*),intent(in) :: fname 2217 class(ebands_t),intent(in) :: ebands 2218 class(crystal_t),intent(in) :: crystal 2219 2220 !Local variables------------------------------- 2221 logical :: use_timrev 2222 2223 ! ************************************************************************* 2224 2225 use_timrev = (crystal%timrev==2) 2226 2227 if (ebands%occopt /= 9) then 2228 call printbxsf(ebands%eig,zero,ebands%fermie,crystal%gprimd,ebands%kptrlatt,ebands%mband,& 2229 ebands%nkpt,ebands%kptns,crystal%nsym,crystal%use_antiferro,crystal%symrec,crystal%symafm,& 2230 use_timrev,ebands%nsppol,ebands%shiftk,ebands%nshiftk,fname,ierr) 2231 else 2232 call printbxsf(ebands%eig,zero,ebands%fermie,crystal%gprimd,ebands%kptrlatt,ebands%mband,& 2233 ebands%nkpt,ebands%kptns,crystal%nsym,crystal%use_antiferro,crystal%symrec,crystal%symafm,& 2234 use_timrev,ebands%nsppol,ebands%shiftk,ebands%nshiftk,trim(fname)//"-e",ierr) 2235 2236 call printbxsf(ebands%eig,zero,ebands%fermih,crystal%gprimd,ebands%kptrlatt,ebands%mband,& 2237 ebands%nkpt,ebands%kptns,crystal%nsym,crystal%use_antiferro,crystal%symrec,crystal%symafm,& 2238 use_timrev,ebands%nsppol,ebands%shiftk,ebands%nshiftk,trim(fname)//"-h",ierr) 2239 end if 2240 2241 end function ebands_write_bxsf
m_ebands/ebands_write_gnuplot [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_write_gnuplot
FUNCTION
Write bands in gnuplot format. This routine should be called by a single processor. Use the driver `ebands_write` to support different formats.
INPUTS
prefix=prefix for files (.data, .gnuplot) [kptbounds(:,:)]=Optional argument giving the extrema of the k-path.
OUTPUT
Only writing
SOURCE
5695 subroutine ebands_write_gnuplot(ebands, prefix, kptbounds) 5696 5697 !Arguments ------------------------------------ 5698 !scalars 5699 type(ebands_t),intent(in) :: ebands 5700 character(len=*),intent(in) :: prefix 5701 real(dp),optional,intent(in) :: kptbounds(:,:) 5702 5703 !Local variables------------------------------- 5704 !scalars 5705 integer :: unt,gpl_unt,ik,spin,ii,start,nkbounds 5706 character(len=500) :: msg,fmt 5707 character(len=fnlen) :: datafile,basefile 5708 !arrays 5709 integer :: g0(3) 5710 integer,allocatable :: bounds2kpt(:) 5711 5712 ! ********************************************************************* 5713 5714 nkbounds = 0 5715 if (present(kptbounds)) then 5716 if (product(shape(kptbounds)) > 0 ) then 5717 ! Find correspondence between kptbounds and k-points in ebands. 5718 nkbounds = size(kptbounds, dim=2) 5719 ABI_MALLOC(bounds2kpt, (nkbounds)) 5720 bounds2kpt = 1; start = 1 5721 do ii=1,nkbounds 5722 do ik=start,ebands%nkpt 5723 if (isamek(ebands%kptns(:, ik), kptbounds(:, ii), g0)) then 5724 bounds2kpt(ii) = ik; start = ik + 1; exit 5725 end if 5726 end do 5727 end do 5728 end if 5729 end if 5730 5731 datafile = strcat(prefix, "_EBANDS.data") 5732 if (open_file(datafile, msg, newunit=unt, form="formatted", action="write") /= 0) then 5733 ABI_ERROR(msg) 5734 end if 5735 if (open_file(strcat(prefix, "_EBANDS.gnuplot"), msg, newunit=gpl_unt, form="formatted", action="write") /= 0) then 5736 ABI_ERROR(msg) 5737 end if 5738 basefile = basename(datafile) 5739 5740 write(unt,'(a)') "# Electron band structure data file" 5741 write(unt,'(a)') "# Generated by Abinit" 5742 write(unt,'(4(a,i0))') & 5743 "# mband: ",ebands%mband,", nkpt: ",ebands%nkpt,", nsppol: ",ebands%nsppol,", nspinor: ",ebands%nspinor 5744 write(unt,'(a,f8.2,a,i0,2(a,f8.2))') & 5745 "# nelect: ",ebands%nelect,", occopt: ",ebands%occopt,", tsmear: ",ebands%tsmear,", tphysel: ",ebands%tphysel 5746 write(unt,'(a,f8.2,a)') "# Energies are in eV. Zero set to efermi, Previously it was at: ",ebands%fermie * Ha_eV, " [eV]" 5747 write(unt,'(a)')"# List of k-points and their index (C notation i.e. count from 0)" 5748 do ik=1,ebands%nkpt 5749 write(unt, "(a)")sjoin("#", itoa(ik-1), ktoa(ebands%kptns(:,ik))) 5750 end do 5751 5752 fmt = sjoin("(i0,1x,", itoa(ebands%mband), "(es16.8,1x))") 5753 write(unt,'(a)') ' ' 5754 do spin=1,ebands%nsppol 5755 write(unt,'(a,i0)') '# [kpt-index, band_1, band_2 ...] for spin: ',spin 5756 do ik=1,ebands%nkpt 5757 write(unt,fmt) ik-1, (ebands%eig(:, ik, spin) - ebands%fermie) * Ha_eV 5758 end do 5759 write(unt,'(a)') ' ' 5760 end do 5761 5762 ! gnuplot script file 5763 write(gpl_unt,'(a)') '# File to plot phonon bandstructure with gnuplot' 5764 write(gpl_unt,'(a)') "#set terminal postscript eps enhanced color font 'Times-Roman,26' lw 2" 5765 write(gpl_unt,'(a)') '#use the next lines to make a nice figure for a paper' 5766 write(gpl_unt,'(a)') '#set term postscript enhanced eps color lw 0.5 dl 0.5' 5767 write(gpl_unt,'(a)') '#set pointsize 0.275' 5768 write(gpl_unt,'(a)') 'set palette defined ( 0 "blue", 3 "green", 6 "yellow", 10 "red" )' 5769 write(gpl_unt,'(a)') 'unset key' 5770 write(gpl_unt,'(a)') '# can make pointsize smaller (~0.5). Too small and nothing is printed' 5771 write(gpl_unt,'(a)') 'set pointsize 0.8' 5772 write(gpl_unt,'(a)') 'set view 0,0' 5773 write(gpl_unt,'(a,i0,a)') 'set xrange [0:',ebands%nkpt-1,']' 5774 write(gpl_unt,'(2(a,es16.8),a)')& 5775 'set yrange [',minval((ebands%eig - ebands%fermie) * Ha_eV),':',maxval((ebands%eig - ebands%fermie) * Ha_eV),']' 5776 write(gpl_unt,'(a)') 'set xlabel "Momentum"' 5777 write(gpl_unt,'(a)') 'set ylabel "Energy [eV]"' 5778 write(gpl_unt,'(a)') strcat('set title "', replace(basefile, "_", "\\_"), '"') 5779 if (nkbounds == 0) then 5780 write(gpl_unt,'(a)') 'set grid xtics' 5781 else 5782 write(gpl_unt,"(a)")"# Add vertical lines in correspondence of high-symmetry points." 5783 write(gpl_unt,'(a)') 'unset xtics' 5784 do ii=1,nkbounds 5785 write(gpl_unt,"(a,2(i0,a))") & 5786 "set arrow from ",bounds2kpt(ii)-1,",graph(0,0) to ",bounds2kpt(ii)-1,",graph(1,1) nohead ls 'dashed'" 5787 !write(gpl_unt,"(a)")sjoin("set xtics add('kname'", itoa(bounds2kpt(ii)-1), ")") 5788 end do 5789 5790 end if 5791 write(gpl_unt,"(a)")sjoin("mband =", itoa(ebands%mband)) 5792 write(gpl_unt,"(a)")strcat('plot for [i=2:mband] "', basefile, '" u 1:i every :1 with lines linetype -1') 5793 if (ebands%nsppol == 2) then 5794 write(gpl_unt,"(a)")strcat('replot for [i=2:mband] "', basefile, '" u 1:i every :2 with lines linetype 4') 5795 end if 5796 write(gpl_unt, "(a)")"pause -1" 5797 5798 close(unt) 5799 close(gpl_unt) 5800 5801 ABI_SFREE(bounds2kpt) 5802 5803 end subroutine ebands_write_gnuplot
m_ebands/ebands_write_nesting [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_write_nesting
FUNCTION
Calculate the nesting function and output data to file.
INPUTS
ebands<ebands_t>=the ebands_t datatype cryst<crystal_t>=Info on unit cell and symmetries. filepath=File name for output data. prtnest = flags governing the format of the output file. see mknesting. 1 for X-Y format, 2 for XCrysden format (XSF) tsmear=Broadening used to approximation the delta function. fermie_nest qpath_vertices = vertices of the reciprocal space trajectory
OUTPUT
Return non-zero exist status if netsting factor cannot be produced. The errmsg string gives information on the error.
SIDE EFFECTS
Write data to file.
SOURCE
3704 integer function ebands_write_nesting(ebands,cryst,filepath,prtnest,tsmear,fermie_nest,qpath_vertices,errmsg) result(skip) 3705 3706 !Arguments ------------------------------------ 3707 class(ebands_t),intent(in) :: ebands 3708 type(crystal_t),intent(in) :: cryst 3709 integer,intent(in) :: prtnest 3710 real(dp),intent(in) :: tsmear,fermie_nest 3711 character(len=*),intent(in) :: filepath 3712 character(len=*),intent(out) :: errmsg 3713 !arrays 3714 real(dp),intent(in) :: qpath_vertices(:,:) 3715 3716 !Local variables------------------------------- 3717 !scalaras 3718 integer :: ikpt,spin,iband,nqpath 3719 real(dp) :: invgauwidth,prefact,fermie 3720 !arrays 3721 real(dp), allocatable :: fs_weights(:,:,:) 3722 3723 ! ********************************************************************* 3724 3725 skip = 0; errmsg = "" 3726 if (any(ebands%nband /= ebands%nband(1))) then 3727 errmsg = 'mknesting can not handle variable nband(1:nkpt). Skipped.'//& 3728 ch10//' Correct input file to get nesting output' 3729 skip = 1; return 3730 end if 3731 3732 if (ebands%nshiftk /= 1) then 3733 errmsg = 'mknesting does not support nshiftk > 1. Change ngkpt and shiftk to have only one shift after inkpts' 3734 skip = 1; return 3735 end if 3736 3737 ! FIXME: needs to be generalized to complete the k grid for one of the arguments to mknesting 3738 fermie = ebands%fermie 3739 nqpath = size(qpath_vertices, dim=2) 3740 3741 ! Compute weights. Set sigma to 0.1 eV is tsmear is zero 3742 invgauwidth = one / (0.1_dp * eV_Ha); if (tsmear > tol10) invgauwidth = one / tsmear 3743 prefact = one / sqrt(pi) * invgauwidth 3744 3745 ABI_MALLOC(fs_weights, (ebands%nband(1), ebands%nkpt, ebands%nsppol)) 3746 3747 do spin=1,ebands%nsppol 3748 do ikpt=1,ebands%nkpt 3749 do iband=1,ebands%nband(1) 3750 fs_weights(iband, ikpt, spin) = prefact * & 3751 exp(-(invgauwidth*(ebands%eig(iband,ikpt,spin)-(fermie + fermie_nest)))**2) 3752 end do 3753 end do 3754 end do 3755 3756 if (any(ebands%kptopt == [3, 4])) then ! no symmetry 3757 call mknesting(ebands%nkpt,ebands%kptns,ebands%kptrlatt,ebands%nband(1),fs_weights,nqpath,& 3758 qpath_vertices,1,[zero, zero, zero],filepath,cryst%gprimd,cryst%gmet,prtnest,identity_3d) 3759 else 3760 call mknesting(ebands%nkpt,ebands%kptns,ebands%kptrlatt,ebands%nband(1),fs_weights,nqpath,& 3761 qpath_vertices,1, [zero, zero, zero], filepath,cryst%gprimd,cryst%gmet,prtnest,identity_3d,& 3762 nsym=cryst%nsym, symrec=cryst%symrec) 3763 end if 3764 3765 ABI_FREE(fs_weights) 3766 3767 end function ebands_write_nesting
m_ebands/ebands_write_xmgrace [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
ebands_write_xmgrace
FUNCTION
Write bands in Xmgrace format. This routine should be called by a single processor. Use the driver `ebands_write` to support different formats.
INPUTS
filename=Filename [kptbounds(:,:)]=Optional argument giving the extrema of the k-path.
OUTPUT
Only writing
SOURCE
5570 subroutine ebands_write_xmgrace(ebands, filename, kptbounds) 5571 5572 !Arguments ------------------------------------ 5573 !scalars 5574 type(ebands_t),intent(in) :: ebands 5575 character(len=*),intent(in) :: filename 5576 real(dp),optional,intent(in) :: kptbounds(:,:) 5577 5578 !Local variables------------------------------- 5579 !scalars 5580 integer :: unt,ik,spin,band,ii,start,nkbounds 5581 character(len=500) :: msg 5582 !arrays 5583 integer :: g0(3) 5584 integer,allocatable :: bounds2kpt(:) 5585 5586 ! ********************************************************************* 5587 5588 nkbounds = 0 5589 if (present(kptbounds)) then 5590 if (product(shape(kptbounds)) > 0 ) then 5591 ! Find correspondence between kptbounds and k-points in ebands. 5592 nkbounds = size(kptbounds, dim=2) 5593 ABI_MALLOC(bounds2kpt, (nkbounds)) 5594 bounds2kpt = 1; start = 1 5595 do ii=1,nkbounds 5596 do ik=start,ebands%nkpt 5597 if (isamek(ebands%kptns(:, ik), kptbounds(:, ii), g0)) then 5598 bounds2kpt(ii) = ik; start = ik + 1; exit 5599 end if 5600 end do 5601 end do 5602 end if 5603 end if 5604 5605 if (open_file(filename, msg, newunit=unt, form="formatted", action="write") /= 0) then 5606 ABI_ERROR(msg) 5607 end if 5608 5609 write(unt,'(a)') "# Grace project file" 5610 write(unt,'(a)') "# Generated by Abinit" 5611 write(unt,'(4(a,i0))') & 5612 "# mband: ",ebands%mband,", nkpt: ",ebands%nkpt,", nsppol: ",ebands%nsppol,", nspinor: ",ebands%nspinor 5613 write(unt,'(a,f8.2,a,i0,2(a,f8.2))') & 5614 "# nelect: ",ebands%nelect,", occopt: ",ebands%occopt,", tsmear: ",ebands%tsmear,", tphysel: ",ebands%tphysel 5615 write(unt,'(a,f8.2,a)') "# Energies are in eV. Zero set to efermi, previously it was at: ",ebands%fermie * Ha_eV, " [eV]" 5616 write(unt,'(a)')"# List of k-points and their index (C notation i.e. count from 0)" 5617 do ik=1,ebands%nkpt 5618 write(unt, "(a)")sjoin("#", itoa(ik-1), ktoa(ebands%kptns(:,ik))) 5619 end do 5620 write(unt,'(a)') "@page size 792, 612" 5621 write(unt,'(a)') "@page scroll 5%" 5622 write(unt,'(a)') "@page inout 5%" 5623 write(unt,'(a)') "@link page off" 5624 write(unt,'(a)') "@with g0" 5625 write(unt,'(a)') "@world xmin 0.00" 5626 write(unt,'(a,i0)') '@world xmax ',ebands%nkpt 5627 write(unt,'(a,es16.8)') '@world ymin ',minval((ebands%eig - ebands%fermie) * Ha_eV) 5628 write(unt,'(a,es16.8)') '@world ymax ',maxval((ebands%eig - ebands%fermie) * Ha_eV) 5629 write(unt,'(a)') '@default linewidth 1.5' 5630 write(unt,'(a)') '@xaxis tick on' 5631 write(unt,'(a)') '@xaxis tick major 1' 5632 write(unt,'(a)') '@xaxis tick major color 1' 5633 write(unt,'(a)') '@xaxis tick major linestyle 3' 5634 write(unt,'(a)') '@xaxis tick major grid on' 5635 write(unt,'(a)') '@xaxis tick spec type both' 5636 write(unt,'(a)') '@xaxis tick major 0, 0' 5637 if (nkbounds /= 0) then 5638 write(unt,'(a,i0)') '@xaxis tick spec ',nkbounds 5639 do ik=1,nkbounds 5640 !write(unt,'(a,i0,a,a)') '@xaxis ticklabel ',ik-1,',', "foo" 5641 write(unt,'(a,i0,a,i0)') '@xaxis tick major ',ik-1,' , ',bounds2kpt(ik) - 1 5642 end do 5643 end if 5644 write(unt,'(a)') '@xaxis ticklabel char size 1.500000' 5645 write(unt,'(a)') '@yaxis tick major 10' 5646 write(unt,'(a)') '@yaxis label "Band Energy [eV]"' 5647 write(unt,'(a)') '@yaxis label char size 1.500000' 5648 write(unt,'(a)') '@yaxis ticklabel char size 1.500000' 5649 ii = -1 5650 do spin=1,ebands%nsppol 5651 do band=1,ebands%mband 5652 ii = ii + 1 5653 write(unt,'(a,i0,a,i0)') '@ s',ii,' line color ',spin 5654 end do 5655 end do 5656 ii = -1 5657 do spin=1,ebands%nsppol 5658 do band=1,ebands%mband 5659 ii = ii + 1 5660 write(unt,'(a,i0)') '@target G0.S',ii 5661 write(unt,'(a)') '@type xy' 5662 do ik=1,ebands%nkpt 5663 write(unt,'(i0,1x,es16.8)') ik-1, (ebands%eig(band, ik, spin) - ebands%fermie) * Ha_eV 5664 end do 5665 write(unt,'(a)') '&' 5666 end do 5667 end do 5668 5669 close(unt) 5670 5671 ABI_SFREE(bounds2kpt) 5672 5673 end subroutine ebands_write_xmgrace
m_ebands/edos_free [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
edos_free
FUNCTION
Free the memory allocated in edos_t
SOURCE
3331 subroutine edos_free(edos) 3332 3333 !Arguments ------------------------------------ 3334 class(edos_t),intent(inout) :: edos 3335 3336 ! ********************************************************************* 3337 3338 !real 3339 ABI_SFREE(edos%mesh) 3340 ABI_SFREE(edos%dos) 3341 ABI_SFREE(edos%idos) 3342 ABI_SFREE(edos%gef) 3343 ABI_SFREE(edos%ghf) 3344 3345 end subroutine edos_free
m_ebands/edos_get_carriers [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
edos_get_carriers
FUNCTION
Compute number of holes (nh) and electrons (ne) per unit cell from a given list of `ntemp` temperatures `kTmesh` and chemical potentials `mu_e`. Return n_ehst(2, nsppol, ntemp) where the first dimension if for electrons/holes. If nsppol == 2, the second dimension is the number of e/h for spin else the total number of e/h summed over spins.!! To discern between electrons and holes in semiconductors we assume that ef is inside the gap.
INPUTS
OUTPUT
SOURCE
3623 subroutine edos_get_carriers(edos, ntemp, kTmesh, mu_e, n_ehst) 3624 3625 !Arguments ------------------------------------ 3626 class(edos_t),intent(in) :: edos 3627 integer,intent(in) :: ntemp 3628 !arrays 3629 real(dp),intent(in) :: kTmesh(ntemp), mu_e(ntemp) 3630 real(dp),intent(out) :: n_ehst(2, edos%nsppol, ntemp) 3631 3632 !Local variables------------------------------- 3633 integer :: itemp, iw, spin 3634 real(dp),allocatable :: values(:) 3635 3636 ! ************************************************************************* 3637 3638 ! Copy important dimensions 3639 n_ehst = zero 3640 ABI_MALLOC(values, (edos%nw)) 3641 3642 do itemp=1,ntemp 3643 3644 ! For electrons (assuming ef inside the gap if semiconductor) 3645 do spin=1,edos%nsppol 3646 do iw=1,edos%nw 3647 if (edos%mesh(iw) >= mu_e(itemp)) then 3648 values(iw) = edos%dos(iw, spin) * occ_fd(edos%mesh(iw), kTmesh(itemp), mu_e(itemp)) 3649 else 3650 values(iw) = zero 3651 end if 3652 end do 3653 n_ehst(1, spin, itemp) = simpson(edos%step, values) 3654 end do ! spin 3655 3656 ! For holes 3657 do spin=1,edos%nsppol 3658 do iw=1,edos%nw 3659 if (edos%mesh(iw) < mu_e(itemp)) then 3660 values(iw) = edos%dos(iw, spin) * (one - occ_fd(edos%mesh(iw), kTmesh(itemp), mu_e(itemp))) 3661 else 3662 values(iw) = zero 3663 end if 3664 end do 3665 n_ehst(2, spin, itemp) = simpson(edos%step, values) 3666 end do ! spin 3667 3668 end do ! itemp 3669 3670 if (edos%nsppol == 1 .and. edos%nspinor == 1) n_ehst = two * n_ehst 3671 ABI_FREE(values) 3672 3673 end subroutine edos_get_carriers
m_ebands/edos_ncwrite [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
edos_ncwrite
FUNCTION
Write results to netcdf file.
INPUTS
edos<edos_t>=DOS container ncid=NC file handle. [prefix]=String prepended to netcdf dimensions/variables (HDF5 poor-man groups) Empty string if not specified.
OUTPUT
ncerr= netcdf exit status.
SOURCE
3463 integer function edos_ncwrite(edos, ncid, prefix) result(ncerr) 3464 3465 !Arguments ------------------------------------ 3466 integer,intent(in) :: ncid 3467 class(edos_t),intent(in) :: edos 3468 character(len=*),optional,intent(in) :: prefix 3469 3470 !Local variables------------------------------- 3471 character(len=500) :: prefix_ 3472 3473 ! ************************************************************************* 3474 3475 prefix_ = ""; if (present(prefix)) prefix_ = trim(prefix) 3476 3477 ! Define dimensions. 3478 ncerr = nctk_def_dims(ncid, [ & 3479 nctkdim_t("nsppol_plus1", edos%nsppol + 1), nctkdim_t("edos_nw", edos%nw)], defmode=.True., prefix=prefix_) 3480 NCF_CHECK(ncerr) 3481 3482 ! Define variables 3483 NCF_CHECK(nctk_def_iscalars(ncid, [character(len=nctk_slen) :: "edos_intmeth", "edos_nkibz"], prefix=prefix_)) 3484 NCF_CHECK(nctk_def_iscalars(ncid, [character(len=nctk_slen) :: "edos_ief", "edos_ihf"], prefix=prefix_)) 3485 NCF_CHECK(nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: "edos_broad"], prefix=prefix_)) 3486 3487 ncerr = nctk_def_arrays(ncid, [ & 3488 nctkarr_t("edos_mesh", "dp", "edos_nw"), & 3489 nctkarr_t("edos_dos", "dp", "edos_nw, nsppol_plus1"), & 3490 nctkarr_t("edos_idos", "dp", "edos_nw, nsppol_plus1"), & 3491 nctkarr_t("edos_gef", "dp", "nsppol_plus1"), & 3492 nctkarr_t("edos_ghf", "dp", "nsppol_plus1") & 3493 ], prefix=prefix_) 3494 NCF_CHECK(ncerr) 3495 3496 ! Write data. 3497 NCF_CHECK(nctk_set_datamode(ncid)) 3498 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("edos_intmeth")), edos%intmeth)) 3499 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("edos_nkibz")), edos%nkibz)) 3500 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("edos_ief")), edos%ief)) 3501 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("edos_ihf")), edos%ihf)) 3502 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("edos_broad")), edos%broad)) 3503 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("edos_mesh")), edos%mesh)) 3504 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("edos_dos")), edos%dos)) 3505 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("edos_idos")), edos%idos)) 3506 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("edos_gef")), edos%gef)) 3507 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("edos_ghf")), edos%ghf)) 3508 3509 contains 3510 pure function pre(istr) result(ostr) 3511 character(len=*),intent(in) :: istr 3512 character(len=len_trim(prefix_) + len_trim(istr)+1) :: ostr 3513 ostr = trim(prefix_) // trim(istr) 3514 end function pre 3515 3516 end function edos_ncwrite
m_ebands/edos_print [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
edos_print
FUNCTION
Print DOS info to Fortran unit.
INPUTS
edos<edos_t>=DOS container [unit]=Unit number for output. Defaults to std_out
OUTPUT
Only writing.
SOURCE
3535 subroutine edos_print(edos, unit, header) 3536 3537 !Arguments ------------------------------------ 3538 class(edos_t),intent(in) :: edos 3539 integer,optional,intent(in) :: unit 3540 character(len=*),optional,intent(in) :: header 3541 3542 !Local variables------------------------------- 3543 integer :: unt 3544 3545 ! ************************************************************************* 3546 3547 unt = std_out; if (present(unit)) unt = unit 3548 if (unt == dev_null) return 3549 3550 if (present(header)) then 3551 write(unt, "(a)") ch10//' === '//trim(adjustl(header))//' === ' 3552 else 3553 write(unt, "(a)") ch10 3554 end if 3555 3556 select case (edos%intmeth) 3557 case (1) 3558 write(unt, "(a,f5.1,a)") " Gaussian method with broadening: ", edos%broad * Ha_meV, " (meV)" 3559 case (2) 3560 write(unt, "(a)")" Linear tetrahedron method." 3561 case (-2) 3562 write(unt, "(a)")" Linear tetrahedron method with Blochl corrections." 3563 case default 3564 ABI_ERROR(sjoin("Wrong intmeth:", itoa(edos%intmeth))) 3565 end select 3566 3567 write(unt, "(a,f5.1,a, i0)")" Mesh step: ", edos%step * Ha_meV, " (meV) with npts: ", edos%nw 3568 write(unt, "(2(a,f5.1),a)")" From emin: ", edos%mesh(1) * Ha_eV, " to emax: ", edos%mesh(edos%nw) * Ha_eV, " (eV)" 3569 write(unt, "(a, i0)")" Number of k-points in the IBZ: ", edos%nkibz 3570 3571 if (edos%ief == 0) then 3572 write(unt, "(a, /)")" edos%ief == 0 --> Cannot print quantities at the Fermi level." 3573 return 3574 end if 3575 3576 write(unt,'(a,es16.8,a)')' Fermi level: ',edos%mesh(edos%ief) * Ha_eV, " (eV)" 3577 write(unt,"(a,es16.8)")" Total electron DOS at Fermi level in states/eV: ", edos%gef(0) / Ha_eV 3578 if (edos%nsppol == 2) then 3579 write(unt,"(a,es16.8)")" g(eF) for spin up: ", edos%gef(1) / Ha_eV 3580 write(unt,"(a,es16.8)")" g(eF) for spin down:", edos%gef(2) / Ha_eV 3581 end if 3582 write(unt,"(a,f6.1)")" Total number of electrons at eF: ", edos%idos(edos%ief, 0) 3583 if (edos%nsppol == 2) then 3584 write(unt,"(a,es16.8)")" IDOS(eF) for spin up: ", edos%idos(edos%ief, 1) 3585 write(unt,"(a,es16.8)")" IDOS(eF) for spin down:", edos%idos(edos%ief, 2) 3586 end if 3587 if (edos%ihf /= edos%ief) then 3588 write(unt,'(a,es16.8,a)')' Fermi level for excited holes: ',edos%mesh(edos%ihf) * Ha_eV, " (eV)" 3589 write(unt,"(a,es16.8)")" Total hole DOS at Fermi level in states/eV: ", edos%ghf(0) / Ha_eV 3590 if (edos%nsppol == 2) then 3591 write(unt,"(a,es16.8)")" g(hF) for spin up: ", edos%ghf(1) / Ha_eV 3592 write(unt,"(a,es16.8)")" g(hF) for spin down:", edos%ghf(2) / Ha_eV 3593 end if 3594 write(unt,"(a,f6.1)")" Total number of electrons at hF: ", edos%idos(edos%ihf, 0) 3595 if (edos%nsppol == 2) then 3596 write(unt,"(a,es16.8)")" N(hF) for spin up: ", edos%idos(edos%ihf, 1) 3597 write(unt,"(a,es16.8)")" N(hF) for spin down:", edos%idos(edos%ihf, 2) 3598 end if 3599 end if 3600 3601 write(unt, "(a)")"" 3602 3603 end subroutine edos_print
m_ebands/edos_t [ Types ]
[ Top ] [ m_ebands ] [ Types ]
NAME
edos_t
FUNCTION
Store the electronic DOS
SOURCE
133 type,public :: edos_t 134 135 integer :: nsppol = -1 136 ! Number of spins. 137 138 integer :: nspinor = -1 139 ! Number of spinors 140 141 integer :: nkibz = -1 142 ! Number of k-points in the IBZ. 143 144 integer :: nw = -1 145 ! Number of points in the frequency mesh. 146 147 integer :: ief = 0 148 ! Rightmost Index of the energy mesh such as IDOS[mesh[ief]] < nelect. 149 ! 0 if Fermi level could not be computed 150 ! Note the value of gef stored in edos_t is computed by performing 151 ! a linear interpolation between ief and ief + 1 152 153 integer :: ihf = 0 154 ! Like ief (see above) 155 ! But for fermi level of thermalized holes in valence bands 156 ! For occopt 9 purposes 157 158 integer :: intmeth = 0 159 ! 1 for gaussian, 2 tetra 160 161 real(dp) :: broad = zero 162 ! Gaussian broadening 163 164 real(dp) :: step = -one 165 ! Step of the mesh 166 167 real(dp) :: nelect = zero 168 ! Number of electrons taken from ebands. 169 170 real(dp),allocatable :: mesh(:) 171 ! mesh(nw) 172 173 real(dp),allocatable :: dos(:,:) 174 ! dos(nw, 0:nsppol) 175 ! Total DOS, spin up and spin down component. 176 177 real(dp),allocatable :: idos(:,:) 178 ! idos(nw, 0:nsppol) 179 ! Integrated DOS: (total, spin up, spin down) component. 180 181 real(dp),allocatable :: gef(:) 182 ! gef(0:nsppol) 183 ! DOS at the Fermi level. Total, spin up, spin down 184 185 real(dp),allocatable :: ghf(:) 186 ! ghf(0:nsppol) 187 ! DOS at the Fermi level of thermalized holes. Total, spin up, spin down 188 189 contains 190 191 procedure :: free => edos_free 192 ! Free memory 193 194 procedure :: write => edos_write 195 ! Write results to file (formatted mode) 196 197 procedure :: print => edos_print 198 ! Print eDOS info to Fortran unit. 199 200 procedure :: ncwrite => edos_ncwrite 201 ! Write eDOS to netcdf file. 202 203 procedure :: get_carriers => edos_get_carriers 204 ! Compute number of holes (nh) and electrons (ne) per unit cell from a given 205 ! list of `ntemp` temperatures `kTmesh` and chemical potentials `mu_e`. 206 207 end type edos_t
m_ebands/edos_write [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
edos_write
FUNCTION
Write results to file.
INPUTS
edos<edos_t>=DOS container path=File name.
OUTPUT
Only writing.
SOURCE
3366 subroutine edos_write(edos, path) 3367 3368 !Arguments ------------------------------------ 3369 character(len=*),intent(in) :: path 3370 class(edos_t),intent(in) :: edos 3371 3372 !Local variables------------------------------- 3373 integer :: iw,spin,unt 3374 real(dp) :: efermi, gef_tot, gef_up, gef_down 3375 character(len=500) :: msg 3376 type(yamldoc_t) :: ydoc 3377 3378 ! ************************************************************************* 3379 3380 if (open_file(path, msg, newunit=unt, form="formatted", action="write") /= 0) then 3381 ABI_ERROR(msg) 3382 end if 3383 3384 ! Write header (human-readable format) 3385 write(unt,'(a)')'# Electron density of states: Energy in eV, DOS in states/eV per unit cell.' 3386 write(unt,"(a)")"# The zero of energies corresponds to the Fermi level." 3387 3388 ! Add Yaml section with parameters. 3389 ydoc = yamldoc_open("EDOS_PARAMS") 3390 call ydoc%add_ints("nkibz, nsppol, nspinor, intmeth, edos_npts", & 3391 [edos%nkibz, edos%nsppol, edos%nspinor, edos%intmeth, edos%nw]) 3392 call ydoc%add_reals("nelect, edos_mesh_step_eV", & 3393 [edos%nelect, edos%step * Ha_eV]) 3394 3395 select case (edos%intmeth) 3396 case (1) 3397 call ydoc%add_string("method", "Gaussian") 3398 call ydoc%add_real("gaussian_broadening_eV", edos%broad * Ha_eV) 3399 case (2) 3400 call ydoc%add_string("method", "Linear tetrahedron") 3401 case (-2) 3402 call ydoc%add_string("method", "Linear tetrahedron method with Blochl corrections") 3403 case default 3404 ABI_ERROR(sjoin("Wrong method:", itoa(edos%intmeth))) 3405 end select 3406 3407 if (edos%ief == 0) then 3408 call ydoc%set_keys_to_string("Fermi_level_eV, gef, gef_up, gef_down", "null") 3409 efermi = zero 3410 else 3411 efermi = edos%mesh(edos%ief) 3412 call ydoc%add_real("Fermi_level_eV", efermi * Ha_eV) 3413 gef_tot = edos%gef(0) / Ha_eV 3414 gef_up = gef_tot / two; gef_down = gef_tot / two 3415 if (edos%nsppol == 2) then 3416 gef_up = edos%gef(1) / Ha_eV; gef_down = edos%gef(2) / Ha_eV 3417 end if 3418 if (edos%nspinor == 1) then 3419 call ydoc%add_reals("gef, gef_up, gef_down", [gef_tot, gef_up, gef_down]) 3420 else 3421 call ydoc%add_reals("gef", [gef_tot]) 3422 end if 3423 end if 3424 3425 ! Write header in Yaml format but prepend # so that one can still use tools such as gnuplot or xmgrace. 3426 call ydoc%write_and_free(unt, firstchar="#") 3427 3428 ! Write data. 3429 write(unt,"(a)")"# Energy DOS_TOT IDOS_TOT DOS[spin=UP] IDOS[spin=UP] ..." 3430 do iw=1,edos%nw 3431 write(unt,'(es17.8)',advance='no')(edos%mesh(iw) - efermi) * Ha_eV 3432 do spin=0,edos%nsppol 3433 write(unt,'(2es17.8)',advance='no')max(edos%dos(iw,spin) / Ha_eV, tol30), max(edos%idos(iw,spin), tol30) 3434 end do 3435 write(unt,*) 3436 end do 3437 3438 close(unt) 3439 3440 end subroutine edos_write
m_ebands/gaps_free [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
gaps_free
FUNCTION
Free the memory allocated in gaps_t
SOURCE
617 subroutine gaps_free(gaps) 618 619 !Arguments ------------------------------------ 620 class(gaps_t),intent(inout) :: gaps 621 622 ! ********************************************************************* 623 624 !integer 625 ABI_SFREE(gaps%fo_kpos) 626 ABI_SFREE(gaps%ierr) 627 628 !real 629 ABI_SFREE(gaps%fo_values) 630 ABI_SFREE(gaps%vb_max) 631 ABI_SFREE(gaps%cb_min) 632 ABI_SFREE(gaps%optical_kpoints) 633 ABI_SFREE(gaps%fund_kpoints) 634 635 !chars 636 ABI_SFREE(gaps%errmsg_spin) 637 638 end subroutine gaps_free
m_ebands/gaps_print [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
gaps_print
FUNCTION
Print info on the fundamental and direct gap.
INPUTS
gaps<gaps_t>=Object with info on the gaps. [header]=Optional title. [unit]=Optional unit for output (std_out if not specified) [kTmesh]=List of temperatures. If present activates output of (T, mu_e, band_edges) [mu_e]=List of Fermi levels for each T.
OUTPUT
Only writing.
SOURCE
662 subroutine gaps_print(gaps, unit, header, kTmesh, mu_e) 663 664 !Arguments ------------------------------------ 665 !scalars 666 class(gaps_t),intent(in) :: gaps 667 integer,intent(in),optional :: unit 668 character(len=*),intent(in),optional :: header 669 real(dp),optional,intent(in) :: kTmesh(:), mu_e(:) 670 671 !Local variables------------------------------- 672 !scalars 673 integer :: spin, ikopt, ivk, ick, unt, itemp, ntemp 674 real(dp) :: fun_gap, opt_gap, csi_c, csi_v 675 character(len=500) :: msg 676 677 ! ********************************************************************* 678 679 unt = std_out; if (present(unit)) unt = unit 680 if (unt == dev_null) return 681 682 do spin=1,gaps%nsppol 683 if (spin == 1) then 684 msg = ch10 685 if (present(header)) msg = ch10//' === '//trim(adjustl(header))//' === ' 686 call wrtout(unt, msg) 687 end if 688 689 if (gaps%ierr(spin) /= 0) then 690 call wrtout(unt, gaps%errmsg_spin(spin)) 691 continue 692 end if 693 694 ! Get minimum of the direct Gap. 695 fun_gap = gaps%fo_values(1, spin) 696 opt_gap = gaps%fo_values(2, spin) 697 698 if (any(gaps%fo_kpos(:,spin) == 0)) then 699 call wrtout(unt, sjoin(" Cannot detect gap for spin: ", itoa(spin))) 700 cycle 701 end if 702 703 ivk = gaps%fo_kpos(1, spin) 704 ick = gaps%fo_kpos(2, spin) 705 ikopt = gaps%fo_kpos(3, spin) 706 707 ! >>>> For spin 2 708 !Direct band gap semiconductor. 709 !Fundamental gap: 4.48 (eV) 710 ! VBM: 4.47 (eV) at k: [ 0.0000E+00, 0.0000E+00, 0.0000E+00] 711 ! CBM: 8.96 (eV) at k: [ 0.0000E+00, 0.0000E+00, 0.0000E+00] 712 !Optical gap: 4.48 (eV) at k:[ 0.0000E+00, 0.0000E+00, 0.0000E+00] 713 714 if (gaps%nsppol == 2) call wrtout(unt, sjoin(' >>>> For spin ', itoa(spin))) 715 if (ivk == ick) call wrtout(unt, " Direct band gap semiconductor") 716 if (ivk /= ick) call wrtout(unt, " Indirect band gap semiconductor") 717 write(msg, "(a,f9.3,a )")" Fundamental gap: ", fun_gap * Ha_eV, " (eV)" 718 call wrtout(unt, msg) 719 write(msg, "(a,f9.3,2a)")" VBM: ", gaps%vb_max(spin) * Ha_eV, " (eV) at k: ", trim(ktoa(gaps%fund_kpoints(:,1,spin))) 720 call wrtout(unt, msg) 721 write(msg, "(a,f9.3,2a)")" CBM: ", gaps%cb_min(spin) * Ha_eV, " (eV) at k: ", trim(ktoa(gaps%fund_kpoints(:,2,spin))) 722 call wrtout(unt, msg) 723 write(msg, "(a,f9.3,2a)")" Direct gap: ", opt_gap * Ha_eV," (eV) at k: ", trim(ktoa(gaps%optical_kpoints(:,spin))) 724 call wrtout(unt, msg) 725 !write(msg, "((2(a, f9.3)))")" Fermi level:", gaps%fermie * Ha_eV, " (eV) with nelect:", gaps%nelect 726 !call wrtout(unt, msg) 727 728 if (present(mu_e) .and. present(kTmesh) .and. all(gaps%ierr == 0)) then 729 ntemp = size(mu_e) 730 call wrtout(unt, " Position of CBM/VBM with respect to the Fermi level:", pre_newlines=1) 731 call wrtout(unt, " Notations: mu_e = Fermi level, D_v = (mu_e - VBM), D_c = (CBM - mu_e)") 732 call wrtout(unt, " T(K) kT (eV) mu_e (eV) D_v (eV) D_c (eV)", pre_newlines=1) 733 do itemp=1,ntemp 734 csi_c = gaps%cb_min(spin) - mu_e(itemp) 735 csi_v = -gaps%vb_max(spin) + mu_e(itemp) 736 write(msg, "(f6.1, 1x, 4(f9.3, 1x))") & 737 kTmesh(itemp) / kb_HaK, kTmesh(itemp) * Ha_eV, mu_e(itemp) * Ha_eV, csi_v * Ha_eV, csi_c * Ha_eV 738 call wrtout(unt, msg) 739 end do 740 call wrtout(unt, "") 741 end if 742 743 end do ! spin 744 745 if (any(gaps%fo_kpos == 0)) then 746 write(msg, "((2(a, f9.3)))") " Fermi level:", gaps%fermie * Ha_eV, " (eV) with nelect:", gaps%nelect 747 call wrtout(unt, msg) 748 end if 749 750 call wrtout(unt, "") 751 752 end subroutine gaps_print
m_ebands/gaps_t [ Types ]
[ Top ] [ m_ebands ] [ Types ]
NAME
gaps_t
FUNCTION
Structure with information on the fundamental and direct gaps returned by ebands_report_gap.
SOURCE
274 type,public :: gaps_t 275 276 integer :: nsppol 277 ! Number of spins. 278 279 integer,allocatable :: fo_kpos(:,:) 280 ! fo_kpos(3,nsppol) 281 ! fo_kpos(1:2,spin) ==> Indices of the k-points where the homo, lumo states are located (for each spin). 282 ! fo_kpos(3,spin) ==> the index of k-point where the direct gap is located (for each spin). 283 284 real(dp) :: fermie 285 ! Fermi energy taken from ebands. 286 287 real(dp) :: nelect 288 ! Number of electrons taken from ebands. 289 290 integer,allocatable :: ierr(:) 291 ! ierr(nsppol 292 ! 0 if the gap has been computed. 293 ! 1 if the system (or spin-channel) is metallic. 294 ! 2 if gaps were not computed (because there are only valence bands). 295 296 real(dp),allocatable :: fo_values(:,:) 297 ! fo_values(2,nsppol)] 298 ! Fundamental and direct gaps (in Hartree) for each spin. 299 300 real(dp),allocatable :: vb_max(:), cb_min(:) 301 ! vb_max(nsppol) 302 ! valence band max and conduction band min for each spin in Ha. 303 ! Only for Semiconductors, set to (+, -) huge(one) for metals. 304 305 real(dp),allocatable :: optical_kpoints(:,:) 306 ! (3, nsppol) 307 ! kpoint of optical gap for each spin 308 309 real(dp),allocatable :: fund_kpoints(:,:, :) 310 ! (3, 2, nsppol) 311 ! kpoint of the fundamental gap for (val, cond) and each spin 312 313 character(len=500),allocatable :: errmsg_spin(:) 314 ! errmsg_spin(nsppol) 315 ! String with human-readable error messages if ierr(spin) != 0. 316 317 contains 318 319 procedure :: free => gaps_free 320 ! Free memory 321 322 procedure :: print => gaps_print 323 ! Print info on the gaps 324 325 end type gaps_t 326 327 public :: ebands_get_gaps ! Build the gaps object from a bandstructure. 328 public :: ebands_print_gaps ! Helper function to print gaps directrly from ebands.
m_ebands/get_eneocc_vect [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
get_eneocc_vect
FUNCTION
Retrieve energies or occupations from a ebands_t structure accessing by name. Results are reported in a vector to facilitate the interface with other abinit routines.
INPUTS
ebands<ebands_t>The type containing the data. arr_name=The name of the quantity to retrieve. Allowed values are == "eig" == For the eigenvalues. == "occ" == For the occupation numbers. == "doccde" == For the derivative of the occupancies wrt the energy.
OUTPUT
vect(ebands%bantot)=The values required.
SOURCE
1374 subroutine get_eneocc_vect(ebands, arr_name, vect) 1375 1376 !Arguments ------------------------------------ 1377 !scalars 1378 character(len=*),intent(in) :: arr_name 1379 class(ebands_t),intent(in) :: ebands 1380 real(dp),intent(out) :: vect(ebands%bantot) 1381 1382 !Local variables------------------------------- 1383 integer :: nkpt,nsppol,mband,bantot 1384 ! ************************************************************************* 1385 1386 mband = ebands%mband; bantot = ebands%bantot; nkpt = ebands%nkpt; nsppol = ebands%nsppol 1387 1388 select case (arr_name) 1389 case ('occ') 1390 call pack_eneocc(nkpt, nsppol, mband, ebands%nband, bantot, ebands%occ, vect) 1391 case ('eig') 1392 call pack_eneocc(nkpt,nsppol,mband,ebands%nband,bantot,ebands%eig, vect) 1393 case ('doccde') 1394 call pack_eneocc(nkpt,nsppol,mband,ebands%nband,bantot,ebands%doccde,vect) 1395 case default 1396 ABI_BUG(sjoin('Wrong arr_name:', arr_name)) 1397 end select 1398 1399 end subroutine get_eneocc_vect
m_ebands/get_gaps_ [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
get_gaps_
FUNCTION
Private function that returns a gaps_t object with info on the fundamental and direct gap.
INPUTS
ebands<ebands_t>=Info on the band structure, the smearing technique and the physical temperature used.
OUTPUT
ierr=Return code (!=0 signals failure) gaps<gaps_t>=object with info on the gaps (caller is responsible for freeing the object).
SOURCE
500 type(gaps_t) function get_gaps_(ebands, ierr) result(gaps) 501 502 !Arguments ------------------------------------ 503 !scalars 504 class(ebands_t),target,intent(in) :: ebands 505 integer,intent(out) :: ierr 506 507 !Local variables------------------------------- 508 !scalars 509 integer :: ikibz,nband_k,spin,nsppol,ikopt,ivk,ick,ivb,icb 510 real(dp),parameter :: tol_fermi = tol6 511 real(dp) :: fun_gap, opt_gap 512 logical :: ismetal 513 !type(ebands_t) :: tmp_ebands 514 !arrays 515 integer :: val_idx(ebands%nkpt, ebands%nsppol) 516 real(dp) :: top_valence(ebands%nkpt), bot_conduct(ebands%nkpt) 517 518 ! ********************************************************************* 519 520 nsppol = ebands%nsppol 521 522 ! Initialize gaps_t 523 gaps%nsppol = nsppol 524 gaps%nelect = ebands%nelect 525 ABI_MALLOC(gaps%fo_kpos, (3, nsppol)) 526 ABI_MALLOC(gaps%ierr, (nsppol)) 527 ABI_MALLOC(gaps%fo_values, (2, nsppol)) 528 ABI_MALLOC(gaps%vb_max, (nsppol)) 529 ABI_MALLOC(gaps%cb_min, (nsppol)) 530 ABI_MALLOC(gaps%errmsg_spin, (nsppol)) 531 532 ABI_MALLOC(gaps%fund_kpoints, (3, 2, nsppol)) 533 ABI_MALLOC(gaps%optical_kpoints, (3, nsppol)) 534 gaps%fund_kpoints = huge(one) 535 gaps%optical_kpoints = huge(one) 536 537 gaps%fo_kpos = 0 538 gaps%ierr = 0 539 gaps%fo_values = zero 540 gaps%vb_max = huge(one); gaps%cb_min = -huge(one) 541 gaps%errmsg_spin(:) = "" 542 gaps%fermie = ebands%fermie 543 544 ! Compute "valence index" using efermi 545 val_idx(:,:) = ebands_get_valence_idx(ebands, tol_fermi=tol_fermi) 546 547 spin_loop: & 548 & do spin=1,nsppol 549 550 ! No output if system is metallic 551 ismetal = ANY(val_idx(:,spin) /= val_idx(1,spin)) 552 if (ismetal) then 553 gaps%ierr(spin) = 1 554 write(gaps%errmsg_spin(spin), "(a,i0)")" Detected metallic system for spin channel: ", spin 555 cycle 556 endif 557 558 ivb = val_idx(1, spin) 559 icb = ivb + 1 560 561 do ikibz=1,ebands%nkpt 562 nband_k = ebands%nband(ikibz + (spin-1)*ebands%nkpt) 563 top_valence(ikibz) = ebands%eig(ivb, ikibz, spin) 564 if (icb > nband_k) then 565 gaps%ierr(spin) = 2 566 gaps%errmsg_spin(spin) = "Not enough states to calculate the band gap." 567 cycle spin_loop 568 end if 569 bot_conduct(ikibz) = ebands%eig(icb, ikibz, spin) 570 end do 571 572 ! Minimum of the direct Gaps 573 ikopt = imin_loc(bot_conduct - top_valence) 574 opt_gap = bot_conduct(ikopt) - top_valence(ikopt) 575 576 ! Fundamental Gap 577 ick = imin_loc(bot_conduct) 578 ivk = imax_loc(top_valence) 579 580 gaps%vb_max(spin) = ebands%eig(ivb, ivk, spin) 581 gaps%cb_min(spin) = ebands%eig(icb, ick, spin) 582 fun_gap = ebands%eig(icb, ick, spin) - ebands%eig(ivb, ivk, spin) 583 gaps%fo_values(:, spin) = [fun_gap, opt_gap] 584 gaps%fo_kpos(:, spin) = [ivk, ick, ikopt] 585 586 gaps%optical_kpoints(:, spin) = ebands%kptns(:, ikopt) 587 gaps%fund_kpoints(:, 1, spin) = ebands%kptns(:, ivk) 588 gaps%fund_kpoints(:, 2, spin) = ebands%kptns(:, ick) 589 end do spin_loop 590 591 ierr = maxval(gaps%ierr) 592 593 if (ierr /= 0) then 594 ! Set VBM and CBM to fermie if metal. 595 do spin=1,nsppol 596 if (gaps%ierr(spin) /= 0) then 597 gaps%vb_max(spin) = ebands%fermie 598 gaps%cb_min(spin) = ebands%fermie 599 end if 600 end do 601 end if 602 603 end function get_gaps_
m_ebands/jdos_free [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
jdos_free
FUNCTION
Free memory
SOURCE
5078 subroutine jdos_free(jdos) 5079 5080 !Arguments ------------------------------------ 5081 class(jdos_t),intent(inout) :: jdos 5082 5083 ! ********************************************************************* 5084 5085 ABI_SFREE(jdos%mesh) 5086 ABI_SFREE(jdos%values) 5087 5088 end subroutine jdos_free
m_ebands/jdos_ncwrite [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
jdos_ncwrite
FUNCTION
Write JDOS to netcdf file.
INPUTS
ncid=NC file handle. [prefix]=String prepended to netcdf dimensions/variables (HDF5 poor-man groups) Empty string if not specified.
SOURCE
5019 integer function jdos_ncwrite(jdos, ncid, prefix) result(ncerr) 5020 5021 !Arguments ------------------------------------ 5022 !scalars 5023 class(jdos_t),intent(inout) :: jdos 5024 integer,intent(in) :: ncid 5025 character(len=*),optional,intent(in) :: prefix 5026 5027 !Local variables------------------------------- 5028 character(len=500) :: prefix_ 5029 5030 ! ********************************************************************* 5031 5032 prefix_ = ""; if (present(prefix)) prefix_ = trim(prefix) 5033 5034 ! Define dimensions. 5035 ncerr = nctk_def_dims(ncid, [ & 5036 nctkdim_t("nsppol_plus1", jdos%nsppol + 1), nctkdim_t("jdos_nw", jdos%nw)], defmode=.True., prefix=prefix_) 5037 NCF_CHECK(ncerr) 5038 5039 ! Define variables 5040 NCF_CHECK(nctk_def_iscalars(ncid, [character(len=nctk_slen) :: "jdos_intmeth", "jdos_nkibz"], prefix=prefix_)) 5041 NCF_CHECK(nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: "jdos_broad"], prefix=prefix_)) 5042 5043 ncerr = nctk_def_arrays(ncid, [ & 5044 nctkarr_t("jdos_mesh", "dp", "jdos_nw"), & 5045 nctkarr_t("jdos_values", "dp", "jdos_nw, nsppol_plus1") & 5046 ], prefix=prefix_) 5047 NCF_CHECK(ncerr) 5048 5049 ! Write data. 5050 NCF_CHECK(nctk_set_datamode(ncid)) 5051 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("jdos_intmeth")), jdos%intmeth)) 5052 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("jdos_nkibz")), jdos%nkibz)) 5053 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("jdos_broad")), jdos%broad)) 5054 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("jdos_mesh")), jdos%mesh)) 5055 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("edos_values")), jdos%values)) 5056 5057 contains 5058 pure function pre(istr) result(ostr) 5059 character(len=*),intent(in) :: istr 5060 character(len=len_trim(prefix_) + len_trim(istr)+1) :: ostr 5061 ostr = trim(prefix_) // trim(istr) 5062 end function pre 5063 5064 end function jdos_ncwrite
m_ebands/jdos_t [ Types ]
[ Top ] [ m_ebands ] [ Types ]
NAME
jdos_t
FUNCTION
Store the electron joint DOS
SOURCE
219 type,public :: jdos_t 220 221 integer :: nsppol 222 ! Number of spins. 223 224 integer :: nkibz 225 ! Number of k-points in the IBZ. 226 227 integer :: nw 228 ! Number of points in the frequency mesh. 229 230 integer :: intmeth 231 ! 1 for gaussian, 2 tetra 232 233 real(dp) :: broad = zero 234 ! Gaussian broadening 235 236 real(dp) :: step 237 ! Step of the mesh 238 239 real(dp),allocatable :: mesh(:) 240 ! mesh(nw) 241 242 real(dp),allocatable :: values(:,:) 243 ! dos(nw,0:nsppol) 244 ! Total jDOS, spin up and spin down component. 245 246 contains 247 248 procedure :: free => jdos_free 249 ! Free memory 250 251 !procedure :: write => jdos_write 252 ! Write results to file (formatted mode) 253 254 !procedure :: print => jdos_print 255 ! Print jDOS info to Fortran unit. 256 257 procedure :: ncwrite => jdos_ncwrite 258 ! Write jDOS to netcdf file. 259 260 end type jdos_t
m_ebands/klinterp_eval_bsd [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
klinterp_eval_bsd
FUNCTION
INPUTS
OUTPUT
SOURCE
6047 subroutine klinterp_eval_bsd(self, kpt, vals_bsd) 6048 6049 !Arguments ------------------------------------ 6050 !scalars 6051 class(klinterp_t),intent(in) :: self 6052 real(dp),intent(in) :: kpt(3) 6053 real(dp),intent(out) :: vals_bsd(self%bsize, self%nsppol, self%ndat) 6054 6055 !Local variables------------------------------- 6056 integer :: spin, idat, band 6057 !integer :: ir1, ir2, ir3, pr1, pr2, pr3 6058 real(dp) :: val !, vv(8) 6059 real(dp) :: kwrap(3), shift(3) 6060 6061 ! ********************************************************************* 6062 6063 call wrap2_zero_one(kpt, kwrap, shift) 6064 !write(std_out, *)"kwrap:", kwrap 6065 6066 ! ir1,ir2,ir3 = bottom left neighbor 6067 ! pr1,pr2,pr3 = top right neighbor 6068 !call interpol3d_indices(kwrap, self%nkx, self%nky, self%nkz, ir1, ir2, ir3, pr1, pr2, pr3) 6069 6070 do idat=1,self%ndat 6071 do spin=1,self%nsppol 6072 do band=1,self%bsize 6073 val = interpol3d_0d(kwrap, self%nkx, self%nky, self%nkz, self%data_uk_bsd(:,:,:,band, spin, idat)) 6074 6075 !if (val <= zero) then 6076 ! vv(1) = self%data_uk_bsd(ir1, ir2, ir3, band, spin, idat) 6077 ! vv(2) = self%data_uk_bsd(pr1, ir2, ir3, band, spin, idat) 6078 ! vv(3) = self%data_uk_bsd(ir1, pr2, ir3, band, spin, idat) 6079 ! vv(4) = self%data_uk_bsd(ir1, ir2, pr3, band, spin, idat) 6080 ! vv(5) = self%data_uk_bsd(pr1, pr2, ir3, band, spin, idat) 6081 ! vv(6) = self%data_uk_bsd(ir1, pr2, pr3, band, spin, idat) 6082 ! vv(7) = self%data_uk_bsd(pr1, ir2, pr3, band, spin, idat) 6083 ! vv(8) = self%data_uk_bsd(pr1, pr2, pr3, band, spin, idat) 6084 ! val = maxval(vv) 6085 !end if 6086 6087 vals_bsd(band, spin, idat) = val 6088 end do 6089 end do 6090 end do 6091 6092 end subroutine klinterp_eval_bsd
m_ebands/klinterp_free [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
klinterp_free
FUNCTION
Free dynamic memory.
INPUTS
OUTPUT
SOURCE
6020 subroutine klinterp_free(self) 6021 6022 !Arguments ------------------------------------ 6023 !scalars 6024 class(klinterp_t),intent(inout) :: self 6025 6026 ! ********************************************************************* 6027 6028 ABI_SFREE(self%data_uk_bsd) 6029 6030 end subroutine klinterp_free
m_ebands/klinterp_new [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
klinterp_new
FUNCTION
INPUTS
OUTPUT
SOURCE
5901 type(klinterp_t) function klinterp_new(cryst, kptrlatt, nshiftk, shiftk, kptopt, kibz, & 5902 bsize, nkibz, nsppol, ndat, values_bksd, comm) result(new) 5903 5904 !Arguments ------------------------------------ 5905 !scalars 5906 type(crystal_t),intent(in) :: cryst 5907 integer,intent(in) :: nshiftk, kptopt, bsize, nkibz, nsppol, ndat, comm 5908 !arrays 5909 integer,intent(in) :: kptrlatt(3,3) 5910 real(dp),intent(in) :: kibz(3, nkibz), shiftk(3,nshiftk), values_bksd(bsize, nkibz, nsppol, ndat) 5911 5912 !Local variables------------------------------- 5913 !scalars 5914 integer,parameter :: sppoldbl1 = 1 5915 integer :: ierr, nkfull, ikf, ik_ibz, timrev, ix, iy, iz, nkx, nky, nkz !spin, band, idat 5916 real(dp) :: dksqmax 5917 character(len=500) :: msg 5918 !arrays 5919 integer,allocatable :: bz2ibz(:,:) 5920 real(dp) :: kpt(3) 5921 real(dp),allocatable :: kfull(:,:) 5922 5923 ! ********************************************************************* 5924 5925 ! Check input parameters 5926 ierr = 0 5927 if (nkibz == 1) then 5928 ABI_ERROR_NOSTOP("Cannot interpolate with a single k-point", ierr) 5929 end if 5930 if (.not. isdiagmat(kptrlatt)) then 5931 ABI_ERROR_NOSTOP('kptrlatt is not diagonal. Multiple shifts are not allowed', ierr) 5932 end if 5933 if (nshiftk /= 1) then 5934 ABI_ERROR_NOSTOP('Multiple shifts not allowed', ierr) 5935 end if 5936 if (any(abs(shiftk(:, 1)) > tol8)) then 5937 ABI_ERROR_NOSTOP("shifted k-mesh not implented", ierr) 5938 end if 5939 5940 if (ierr /= 0) then 5941 ABI_ERROR("Linear interpolation cannot be performed. See messages above.") 5942 end if 5943 5944 nkx = kptrlatt(1, 1) 5945 nky = kptrlatt(2, 2) 5946 nkz = kptrlatt(3, 3) 5947 5948 new%nkx = nkx; new%nky = nky; new%nkz = nkz 5949 new%bsize = bsize; new%nsppol = nsppol; new%ndat = ndat 5950 5951 ! Build list of k-points in the conventional unit cell. 5952 ! (x,y,z) ordered as required by interpolation routine 5953 nkfull = nkx * nky * nkz 5954 ABI_MALLOC(kfull, (3, nkfull)) 5955 ikf = 0 5956 do iz=1,nkz 5957 kpt(3) = (iz - 1 + shiftk(3, 1)) / nkz 5958 do iy=1,nky 5959 kpt(2) = (iy - 1 + shiftk(2, 1)) / nky 5960 do ix=1,nkx 5961 kpt(1) = (ix - 1 + shiftk(1, 1)) / nkx 5962 ikf = ikf + 1 5963 kfull(:, ikf) = kpt 5964 end do 5965 end do 5966 end do 5967 5968 ! Build mapping kfull --> IBZ 5969 timrev = kpts_timrev_from_kptopt(kptopt) 5970 ABI_MALLOC(bz2ibz, (nkfull*sppoldbl1, 6)) 5971 5972 call listkk(dksqmax, cryst%gmet, bz2ibz, kibz, kfull, nkibz, nkfull, cryst%nsym,& 5973 sppoldbl1, cryst%symafm, cryst%symrec, timrev, comm, use_symrec=.True.) 5974 5975 ABI_FREE(kfull) 5976 5977 if (dksqmax > tol12) then 5978 write(msg, '(3a,es16.6,4a)' )& 5979 'At least one of the k points could not be generated from a symmetrical one.',ch10,& 5980 'dksqmax: ',dksqmax,ch10,& 5981 'Action: check k-point input variables',ch10,& 5982 ' e.g. kptopt or shiftk might be wrong in the present dataset or the preparatory one.' 5983 ABI_ERROR(msg) 5984 end if 5985 5986 ABI_CALLOC(new%data_uk_bsd, (nkx, nky, nkz, bsize, nsppol, ndat)) 5987 5988 ! Build array in the full BZ to prepare call to interpol3d_0d. 5989 ikf = 0 5990 do iz=1,nkz 5991 do iy=1,nky 5992 do ix=1,nkx 5993 ikf = ikf + 1 5994 ik_ibz = bz2ibz(ikf, 1) 5995 new%data_uk_bsd(ix, iy, iz, 1:bsize, 1:nsppol, 1:ndat) = values_bksd(1:bsize, ik_ibz, 1:nsppol, 1:ndat) 5996 end do 5997 end do 5998 end do 5999 6000 ABI_FREE(bz2ibz) 6001 6002 end function klinterp_new
m_ebands/klinterp_t [ Types ]
[ Top ] [ m_ebands ] [ Types ]
NAME
klinterp_t
FUNCTION
Linear interpolation of eigenvalue-like quantities (scalars with the same symmetry as the KS eigenvalues) Used, for instance, to interpolate electron or phonon lifetimes.
SOURCE
341 type,public :: klinterp_t 342 343 integer :: bsize, nsppol, ndat 344 ! Max number of bands, number of independent spin polarization, size of "extra" dimension. 345 346 integer :: nkx, nky, nkz 347 ! Number of divisions of the grid enclosing the first unit cell 348 349 real(dp),allocatable :: data_uk_bsd(:,:,:,:,:,:) 350 ! (nkx*nky*nkz, mband, nsppol, ndat) 351 352 contains 353 354 procedure :: free => klinterp_free 355 ! Free dynamic memory 356 357 procedure :: eval_bsd => klinterp_eval_bsd 358 ! Interpolate values at an arbitrary k-point. 359 360 end type klinterp_t 361 362 public :: klinterp_new ! Build interpolator. 363 364 365 !---------------------------------------------------------------------- 366 367 CONTAINS !=====================================================================================
m_ebands/pack_eneocc [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
pack_eneocc
FUNCTION
Helper function to do a reshape of (energies|occupancies|derivate of occupancies) initially stored in a 3D arrays returning a vector.
INPUTS
nkpt=number of k-points nsppol=number of spin polarizations mband=Max number of bands over k-points (just to dimension the output) nbands(nkpt*nsppol)=Number of bands at eack k and spin bantot=Total number of bands array3d(mband,nkpt,nsppol)=Arrays containing the values to reshape.
OUTPUT
vect(bantot)=The input values stored in vector mode. Only the values really considered at each k-point and spin are copied.
SOURCE
1323 subroutine pack_eneocc(nkpt, nsppol, mband, nband, bantot, array3d, vect) 1324 1325 !Arguments ------------------------------------ 1326 !scalars 1327 integer,intent(in) :: nkpt,nsppol,mband,bantot 1328 !arrays 1329 integer,intent(in) :: nband(nkpt*nsppol) 1330 real(dp),intent(in) :: array3d(mband,nkpt,nsppol) 1331 real(dp),intent(out) :: vect(bantot) 1332 1333 !Local variables------------------------------- 1334 integer :: spin,ikpt,band,idx 1335 1336 ! ************************************************************************* 1337 1338 vect(:)=zero 1339 idx=0 1340 do spin=1,nsppol 1341 do ikpt=1,nkpt 1342 do band=1,nband(ikpt+(spin-1)*nkpt) 1343 idx=idx+1 1344 vect(idx)=array3d(band,ikpt,spin) 1345 end do 1346 end do 1347 end do 1348 1349 end subroutine pack_eneocc
m_ebands/put_eneocc_vect [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
put_eneocc_vect
FUNCTION
Update the energies or the occupations stored in a ebands_t structure. The input values are stored in a vector according to the abinit convention In the data type, on the contrary, we use 3D arrays (mband,nkpt,nsspol) which are much easier to use inside loops.
INPUTS
vect(ebands%bantot)=The new values to be stored in the structure. arr_name=The name of the quantity to be saved (CASE insensitive). Allowed values are == "eig" == For the eigenvalues. == "occ" == For the occupation numbers. == "doccde" == For the derivative of the occupancies wrt the energy.
OUTPUT
See SIDE EFFECTS
SIDE EFFECTS
ebands<ebands_t>=The object with updated values depending on the value of arr_name
SOURCE
1430 subroutine put_eneocc_vect(ebands,arr_name,vect) 1431 1432 !Arguments ------------------------------------ 1433 !scalars 1434 character(len=*),intent(in) :: arr_name 1435 class(ebands_t),intent(inout) :: ebands 1436 real(dp),intent(in) :: vect(:) 1437 1438 !Local variables------------------------------- 1439 integer :: nkpt,nsppol,mband,bantot 1440 real(dp) :: val 1441 ! ************************************************************************* 1442 1443 mband =ebands%mband; bantot=ebands%bantot; nkpt =ebands%nkpt; nsppol=ebands%nsppol 1444 1445 select case (tolower(arr_name)) 1446 case ('occ') 1447 call unpack_eneocc(nkpt,nsppol,mband,ebands%nband,vect,ebands%occ, val=zero) 1448 case ('eig') 1449 ! DFPT routines call ebands_init with the wrong bantot. Using maxval(vect) causes SEGFAULT 1450 ! so I have to recompute the correct bantot here 1451 !ABI_CHECK(sum(ebands%nband) == ebands%bantot, "bantot and nband are incosistent") 1452 val = maxval(vect(1:sum(ebands%nband))) 1453 call unpack_eneocc(nkpt,nsppol,mband,ebands%nband,vect,ebands%eig, val=val) 1454 case ('doccde') 1455 call unpack_eneocc(nkpt,nsppol,mband,ebands%nband,vect,ebands%doccde, val=zero) 1456 case default 1457 ABI_BUG(sjoin('Wrong arr_name= ', arr_name)) 1458 end select 1459 1460 end subroutine put_eneocc_vect
m_ebands/unpack_eneocc [ Functions ]
[ Top ] [ m_ebands ] [ Functions ]
NAME
unpack_eneocc
FUNCTION
Helper function to do a reshape of (energies|occupancies|derivate of occupancies) initially stored in a vector. Return a 3D array index by (band,ikpt,spin)
INPUTS
nkpt=number of k-points nsppol=number of spin polarizations mband=Max number of bands over k-points (just to dimension the output) nbands(nkpt*nsppol)=Number of bands at eack k and spin vect(:)=The input values to reshape [val]=Optional value used to initialize the array.
OUTPUT
array3d(mband,nkpt,nsppol)=Arrays containing the values of vect. Note that the first dimension is usually larger than the number of bands really used for a particular k-point and spin.
SOURCE
1264 subroutine unpack_eneocc(nkpt,nsppol,mband,nband,vect,array3d,val) 1265 1266 !Arguments ------------------------------------ 1267 !scalars 1268 integer,intent(in) :: nkpt,nsppol,mband 1269 real(dp),optional,intent(in) :: val 1270 !arrays 1271 integer,intent(in) :: nband(nkpt*nsppol) 1272 real(dp),intent(in) :: vect(:) 1273 real(dp),intent(out) :: array3d(mband,nkpt,nsppol) 1274 1275 !Local variables------------------------------- 1276 integer :: spin,ikpt,band,idx 1277 ! ************************************************************************* 1278 1279 if (present(val)) then 1280 array3d = val 1281 else 1282 array3d = huge(one) 1283 end if 1284 1285 idx=0 1286 ! elements in vect are packed in the first positions. 1287 do spin=1,nsppol 1288 do ikpt=1,nkpt 1289 do band=1,nband(ikpt + (spin-1)*nkpt) 1290 idx = idx + 1 1291 array3d(band, ikpt, spin) = vect(idx) 1292 end do 1293 end do 1294 end do 1295 1296 end subroutine unpack_eneocc