Điều kiện trực giao chuẩn hóa giữa các quĩ đạo nguyên tử có dạng:
' '( j) m( i mm m r R r R (3.6) ( ) n n mi m i m i r R '( ') ˆ ( ) '( ') ( ) n n n mi m i m i mi m i m i m i m i r R H r R E r R r R
Từ đó, phương trình (3.5) trở thành:
(3.7) với M là số các quĩ đạo được sử dụng còn N là số nguyên tử trong tinh thể.
Như vậy, phương trình Schrodinger qui về bài toán tìm trị riêng của ma trận có kích thước (M.N)x(M.N):
(3.8)
ở đây các yếu tố ma trận chính là các tích phân phủ, ví dụ tương tác giữa quĩ đạo của nguyên tử i và quĩ đạo p của nguyên tử j là:
i m i s p S r R H r R h i sj ( ) ( (3.9) với Ri,Rjlà các vector tọa độ của nguyên tử thứ i, j.
Số lượng các tích phân phủ sẽ giảm đi đáng kể nếu ta tính đến tính chất đối xứng của tinh thể và áp dụng các gần đúng lân cận gần nhất và gần đúng hai tâm. Gần đúng lân cận gần nhất có nghĩa là phần tử ma trận
(3.10) '( ') ˆ ( ) ' ' M N n n n mi m i m i m i m i r R H r R E 1 2 , ... , ... , ... , ... 1 2 i xj x y x y x y x y x x s p x x
atom atom atom i atom N
s p p s p p s p p s p p s p atom s p atom H s h p atom j s p atom N '( ) ˆ ( ) 0 m r R Hj m r Ri
nếu i và j không phải là hai nguyên tử lân cận gần nhất của nhau. Gần đúng hai tâm có nghĩa là
(3.11) nếu k đồng thời khác cả i và j.
Để chéo hóa ma trận Hamilton, một số thuật toán đã được phát triển, trong đó hai thuật toán thông dụng nhất là Conjugate Gradient (CG) và Jack- Davidson (JD). Đây cũng chính là hai thuật toán được sử dụng trong bài này. Tùy vào việc chọn các hệ cơ sở khác nhau mà ta có các mô hình Tight - binding khác nhau. Thông thường người ta thường chọn một trong các mô hình Tight - binding sau đây :
• Tight - binding sp3: gồm một quĩ đạo s và ba quĩ đạo p. Đây là mô hình Tight - binding đơn giản nhất, tuy nhiên mô hình này chưa đủ để nghiên cứu các bán dẫn có vùng cấm xiên (như Si).
• Tight - binding sp3s*: cho phép nhận được vùng cấm xiên nhưng chưa cho giá trị đủ độ chính xác của khối lượng ngang của điện tử.
• Tight - binding sp3d5: hệ cơ sở bao gồm chín quĩ đạo nên cho kết quả tương đối chính xác trong vùng dẫn. Đây là mô hình phù hợp nhất vì khối lượng tính toán vừa phải và cũng đạt độ chính xác cần thiết trong kết quả.
• Tight - binding sp3d5s*: đây là mô hình mô tả tốt nhất cấu trúc vùng của các chất bán dẫn, tuy nhiên ta phải làm việc với các ma trận có kích thước rất lớn, và như vậy sẽ không thuận lợi cho các tính toán.
3.5 Xây dựng tinh thể dây nanô Ge.
Trong tinh thể nanô của Ge thì xung quanh nguyên tử Ge trung tâm có bốn nguyên tử lân cận gần nhất chiếm vị trí của các nút mạng tạo thành tứ diện đều có cấu trúc mạng tinh thể của kim cương. Các vector nối nguyên tử trung tâm (là nguyên tử đang xét) với bốn nguyên tử lân cận gần nhất này có dạng :
'( ) ( ) 0
m r R Vj k m r Ri
(3.12)
với a là kích thước của khối lập phương. Trên Hình 3.1 mô tả cấu trúc hình học không gian của mạng tinh thể dạng kim cương mô phỏng cho cấu trúc hình học không gian của mạng tinh thể Ge.
Hình 3.1 Cấu trúc kim cương
Quá trình xây dựng tinh thể nanô Gecmani như sau: xuất phát từ nguyên tử trung tâm Ge (giả thiết nằm ở gốc tọa độ), ta phát triển bằng cách thêm dần các nguyên tử lân cận gần nhất cho đến khi tinh thể đạt kích thước mong muốn. Trong quá trình phát triển, ta phải điền các liên kết còn trống của nguyên tử Ge bằng một nguyên tử Ge. Quá trình này được lặp lại cho đến khi vị trí của các nguyên tử Ge vượt ra ngoài kích thước mong muốn của tinh thể (được thay thế bởi nguyên tử Hidro) nghĩa là khoảng cách từ nguyên tử Ge vừa thay thế đến trục của dây lớn hơn R (R là bán kính của dây đang xét) và toạ độ theo phương oz lớn hơn l (l là chiều dài của dây đang xét) khi đó quá trình xây dựng kết thúc ta thu được tinh thể hoàn chỉnh cần xây dựng. Chương trình sử dụng trong phương pháp TB của chúng tôi chủ yếu dựa trên
1 2 3 4 1 1 1 1 1 ; 1 ; 1 ; 1 4 4 4 4 1 1 1 1 a a a a d d d d
0 5 10 15 20 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 E(e V) d(nm)
chương trình máy tính được viết bởi nhóm nghiên cứu mô phỏng của Yann Michel Niquet (CEA, Grenoble, France). Tất nhiên, để có thể tính toán cho các hệ cỡ vài nanomet, chúng ta cũng cần phải có những hệ máy tính đủ mạnh.
3.6. So sánh kết quả và thảo luận về hai phƣơng pháp tính trong sự phụ thuộc vào bán kính của dây.
Trong phần này chúng tôi nghiên cứu và thảo luận kết quả từ hai phương pháp tính cho dây Ge: kết quả tính bằng phương pháp khối lượng hiệu dụng và bằng phương pháp tight binding.
Lập trình tính từ kết quả của phương pháp tight bindingvới các tham số đầu vào: hằng số mạng a = 5.65800 A0; TB model = sp3d5t; tên nguyên tử là Ge; ES1 = -2.72617 eV; EP1 = 4.53970 eV; ED1 = 12.81060 eV; ET1= 18.52600 eV; SO1 = 0.10132 eV; Các tham số đối với nguyên tử Hidro: EH2 = 0.20505 eV; VHSS2 = -3.61897 eV ; VHPS2 = 4.08147 eV.
Hình 3.2 Sự phụ thuộc của năng lượng vào đường kính dây được tính bằng phương pháp Tight-Binding.
H×nh 3.2 nªu lªn mèi liªn hÖ gi÷a ®-êng kÝnh
4 6 8 10 12 14 16 18 20 22 0 2 4 6 8 10 12 TB EMA E (e V ) d(nm)
l-îng nhá vµ ng-îc l¹i khi đường kÝnh nhá th× n¨ng
l-îng lín.
Lập trình tính từ kết quả của phương pháp khối lượng hiệu dụng với các tham số đầu vào V0 = ; =6,625.10-34J.s; m= 0.7462x10-31kg ; m//= 14.9287462x10-31kg ; d = 10A0-200A0 ta thu được sự phụ thuộc của năng lượng vào đường kính d và so sánh với kết quả tính bằng phương pháp Tight- Bingding biểu diễn trên hình 3.3.
Hình 3.3. Sự phụ thuộc của năng lượng vào đường kính tính theo hai phương pháp EMA và TB
Sử dụng hai phương pháp EMA và TB cho kết quả gần giống nhau khi bán kính của dây khá lớn và cùng tiệm cận tới giá trị năng lượng trong bán dẫn khối. Khi đường kính dây giảm thì hai phương pháp này có sự sai khác đáng kể và mô hình TB cho kết quả phù hợp hơn .
KẾT LUẬN
1. Chúng tôi đã sử dụng phương pháp Gần đúng khối lượng hiệu dụng (EMA) để tính mức năng lượng đơn điện tử ở trạng thái cơ bản của dây lượng tử bán dẫn, trong đó tập trung khảo sát dây lượng tử Ge. Kết quả cho thấy rõ hiệu ứng giam giữ lượng tử trong dây lượng tử Ge đối với các mức năng lượng ở trạng thái cơ bản. Kết quả này được biểu diễn trên hình 2.1.
2. Chúng tôi cũng đã sử dụng phương pháp Tight - binding với mô hình sp3d5. Ở đây chúng tôi sử dụng bộ tham số của J. M. Jancu và các cộng sự [7] khi đưa vào tính toán trên hệ máy tính của Viện Vật lí và Điện tử – Viện Khoa học và Công nghệ Việt Nam. Kết quả cũng cho thấy rõ các hiệu ứng giam giữ lượng tử của điện tử trong các tinh thể nanô. Hiệu ứng Blue Shift được thể hiện rõ nét: năng lượng trạng thái cơ bản của điện tử tăng khi đường kính dây giảm. Kết quả này được biểu diễn trên hình 3.2.
3. Chúng tôi đã tiến hành so sánh kết quả thu được từ phương pháp EMA với kết quả đã thu được từ phương pháp Tight - binding. Kết quả cho thấy có sự sai khác giữa hai phương pháp khi bán kính của dây là bé. Ngược lại, khi bán kính dây tăng lên thì các giá trị năng lượng thu được từ hai phương pháp trên ngày càng phù hợp hơn và cùng tiệm cận tới giá trị năng lượng trong bán dẫn khối. Kết quả này được biểu diễn trên hình 3.3.
Những nghiên cứu sâu hơn về các tinh thể nanô bán dẫn và về phương pháp Tight - binding cũng như phương pháp EMA sẽ được chúng tôi thực hiện tiếp ở các đề tài sau.
PHỤ LỤC
Phụ lục 1
Chương trình máy tính sử dụng trong phương pháp Tight - binding (chương trình chính).
Ngôn ngữ lập trình: Fortran f90.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Interface for the geometry builder.
! Homogeneous nanowire oriented along an arbitrary direction.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! module interface_geometry
use defs
use geometry_defs implicit none
real(dp) :: lwire ! Length of the supercell. real(dp) :: rwire2 ! Square radius of the wire.
real(dp) :: rwireeff2 ! Effective square radius of the wire. real(dp) :: uwire(3) ! Normalized orientation of the wire. logical :: anioncentered
type (neighborhoodtype) :: neighborhood integer :: nbsc, nbhy, nper, ntot
integer, pointer :: ipos(:,:), ityp(:) real(dp), pointer :: dpos(:,:)
end module interface_geometry
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Interface for the Jacobi-Davidson eigensolver.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! module interface_jdeig use defs use linalg use sparsematrix use linsys use preconditioners_defs use preconditioners_bond use interface_geometry use hamilt_so implicit none
logical :: withSO = .true. ! Take spin-orbit into account. ! Jacobi-Davidson parameters.
integer :: itnew_JD = 64 integer :: itmax_JD = 20 integer :: nkeep_JD = 24
real(dp) :: epsilon_JD = 1.d-6 ! Linear systems solver parameters. integer :: itinmax_pGMRES = 32 integer :: itoutmax_pGMRES = 1 real(dp) :: epsilon_pGMRES = 1.d-9 ! Public variables.
integer :: norbs, range
type (zdsparsematrixtype) :: h type (zdsparsematrixtype) :: hp
real(dp), pointer :: esh(:), esp3(:), bsp3(:,:), e0(:,:) ! Private variables.
real(dp), private :: shift complex(dp), private :: vrvl
complex(dp), allocatable, private :: tmp(:) complex(dp), pointer, private :: vl(:), vr(:) end module interface_jdeig
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Interface for the search of band extrema.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! module interface_bandext use defs use linalg use sparsematrix use hamilt_defs use hamilt_sp3d5t_2c use preconditioners_defs use preconditioners_bond use jdeig use interface_geometry use interface_jdeig implicit none integer :: idir_bandext real(dp) :: sigma_bandext
complex(dp), allocatable :: evec_bandext(:,:) integer :: nval_bandext = 4
real(dp) :: epsilon_kred = 1.d-3
real(dp) :: epsilon_JD_bandext = 1.d-9 logical :: precdt_bandext = .false. contains
end module interface_bandext
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Main program. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! program wireZB use defs use utils use linalg use sparsematrix use geometry use geometry_defs use geometry_utils use interface_geometry use hamilt_defs use hamilt_sp3d5t_2c use preconditioners_defs use preconditioners_bond use jdeig use wavefunctions use interface_bandext implicit none ! Local variables. integer :: i integer :: it integer :: iat
integer :: idir integer :: ilh0 integer :: nwfn integer :: ierr integer :: idx, jdx integer :: ival, nval integer :: ikpt, nkpt integer :: ixc, iyc, izc integer :: ixp, iyp, izp
integer, allocatable :: nbtyp(:)
integer, allocatable :: nvalk(:), idirk(:) logical :: todo, found
real(dp) :: ek,ek1,ek2 real(dp) :: vso2
real(dp) :: sigma real(dp) :: x, y, z
real(dp) :: radius, radiuseff
real(dp) :: kred, dkred, kred1, kred2, kred3 real(dp) :: vbmax, kvbmax, cbmin, kcbmin, eg real(dp) :: k(3)
real(dp), allocatable :: kpt(:) real(dp), allocatable :: sigmak(:) real(dp), allocatable :: eval(:,:) complex(dp), allocatable :: evec(:,:) character(len = 7) :: nbtypstr
character(len = 80) :: id
character(len = 80) :: paramTBfile
character(len = 10), allocatable :: optk(:) ! Main code.
call startglobaltimer
! Set parameters for the calculation. anioncentered = .true.
removeXH3 = .true. withSO = .true. ! Read the input file.
open (untfree, file = 'wireZB.input', form = 'formatted', status = 'old')
! Read the radius of the nanowire and the orientation vector.
read (untfree, '(/9x,f10.5,/27x,sp,3(i2),ss)') radius, ixc, iyc, izc write (stdout, '( "Homogeneous ZB nanowire.", &
& /"Radius = ",f10.5," nm.", &
& /"Orientation (cubic axes) : ",sp,3(i2),ss,".")') radius, ixc, iyc, izc
write (id, '(sp,3(i2),ss,"_")') ixc, iyc, izc ! The ID of the nanowire. ! Transform the orientation vector from cubic to primitive axes.
ixp = -ixc+iyc+izc iyp = ixc-iyc+izc izp = ixc+iyc-izc
! Try to skrink the unit cell. found = .true.
do while (found) found = .false.
do i = 2, maxval((/ixp,iyp,izp/))
if ((mod(ixp, i) == 0).and.(mod(iyp, i) == 0).and.(mod(izp, i) == 0)) then
ixp = ixp/i iyp = iyp/i izp = izp/i
found = .true. exit
endif enddo enddo
! Transform the orientation vector back to the cubic axes. x = (iyp+izp)/2.d0
y = (ixp+izp)/2.d0 z = (ixp+iyp)/2.d0
write (stdout, '("Primitive cell vector (cubic axes) : (",sp,f5.2,", ",f5.2,", ",f5.2,ss,").")') &
& x, y, z
uwire = (/x, y, z/)
! Read the TB model and parameters file. read (untfree, '(21x,a80)') paramTBfile
write (stdout, '("TB parameters file : ",a,".")') trim(paramTBfile) ! Read the number and list of k-points.
read (untfree, '(21x,i3)') nkpt
write (stdout, '("Number of k points = ",i3,".")') nkpt
allocate(kpt(nkpt), sigmak(nkpt), idirk(nkpt), nvalk(nkpt), optk(nkpt)) read (untfree,'(/)')
write (stdout, '(a,/a)') "List of k points :", &
& " k (2pi/a) # sigma (eV) # dir # nval # options"
do ikpt = 1, nkpt
read (untfree, '(f10.5,3x,f10.5,3x,i3,3x,i4,2x,a10)') &
& kpt(ikpt), sigmak(ikpt), idirk(ikpt), nvalk(ikpt), optk(ikpt) write (stdout, '(f10.5," # ",f10.5," # ",sp,i3,ss," # ",i4," # ",a10)') &
& kpt(ikpt), sigmak(ikpt), idirk(ikpt), nvalk(ikpt), optk(ikpt) enddo
close (untfree)
! Read the tight-binding parameters. write (stdout, *)
dbg_hamilt = 2
call readparams_sp3d5t_2c(paramTBfile) norbs = norbs_sp3d5t
range = range_sp3d5t
acell = readacell(paramTBfile, 'acell = ')
if (acell <= 0.d0) stop "readacell : Error reading acell." write (stdout, '("readacell : acell = ",f10.5," A.")') acell acell = acell/ual
write (stdout, *)
call readbondprecdtparams('bondprecdt.par', norbs, esh, esp3, bsp3, e0) ! Build the nanowire structure.
lwire = sqrt(uwire(1)**2+uwire(2)**2+uwire(3)**2) uwire = uwire/lwire
lwire = lwire*acell
rwire2 = (10.d0*radius/ual)**2
call alloc_neighborhood(neighborhood, range)
call structureZB(itypat, ipos, dpos, ityp, neighborhood, nbsc, nbhy, nper, ntot, acell, 0.325d0*acell*(/1.d0,1.d0/))
call supercell
! Count the number of atoms and set-up the id. allocate(nbtyp(maxtyp))
nbtyp(1:maxtyp) = 0 do iat = 1, nbsc
enddo
do it = 1, maxtyp
write (nbtypstr, '(i7)') nbtyp(it)
write (id, '(a,a,a)') trim(id), trim(TBmodel(it)%name), trim(adjustl(nbtypstr))
enddo
write (nbtypstr, '(i7)') nbhy
write (id, '(a,a,a)') trim(id), trim(TBmodel(0)%name), trim(adjustl(nbtypstr))
radiuseff = sqrt((nbsc*acell**3)/(8.d0*pi*lwire))*ual/10.d0 write (stdout, '(/"Nanowire ID : ",a,".", &
& /"Number of semiconductor atoms = ",i6,".", & & /"Number of Hydrogen atoms = ",i6,".", & & /"Number of supercell atoms = ",i6,".", &
& /"Total number of atoms (incl. PBC images) = ",i6,".", &
& /"Effective nanowire radius = ",f10.5," nm.")') & & trim(id), nbsc, nbhy, nper, ntot, radiuseff
! Export the nanowire structure in xyz format and write the wavefunction file header.
call exportxyz('wireZB_'//trim(id)//'.xyz', dpos, ityp, nper)
call writewfnfileheader('wireZB_'//trim(id)//'.out', nbsc, nbhy, nper, dpos, ityp)
! Look for the second and (if appropriate) third nearest neighbors. ! call neighborhood_connect("ZB", ipos, ityp, neighborhood, nbsc) call neighborhood_direct("ZB", ipos, neighborhood, nbsc, nper, ntot) call checkneighborhood(ityp, neighborhood, nbsc, nper)
! Compute ndim. ndim = norbs*nbsc+nbhy if (withSO) then ndimeff = 2*ndim else ndimeff = ndim endif
! Loop over the k points. kvbmax = 0.d0
vbmax = -1.d10 kcbmin = 0.d0 cbmin = 1.d10
open (untfree, file = 'wireZB_'//trim(id)//'.bs', form = 'formatted', status = 'replace') close (untfree) do ikpt = 1, nkpt kred = kpt(ikpt) sigma = sigmak(ikpt) idir = idirk(ikpt) nval = nvalk(ikpt)
todo = ((nval > 0).and.(scan(optk(ikpt), "-") == 0)).or.(scan(optk(ikpt), "Ee") /= 0)
if (.not.todo) cycle
k = twopi*kred*uwire/lwire
write (stdout, '(/"ikpt = ",i2," : k = ",f10.5," ; sigma = ",f10.5," ; idir = ",sp,i3,ss," ; nval = ",i4,".")') &
& ikpt, kred, sigma, idir, nval write (stdout, '(75("*"))')
! Compute the hamiltonian and JD preconditioner. write (stdout, *)
call zdhamilt_sp3d5t_2c(k, .true., h, dpos, ityp, neighborhood, nbsc, nbhy, nper, ntot)
write (stdout, *)
call zdbondprecdt_sp3xx(k, 0.d0, .true., hp, dpos, ityp, neighborhood%neighbors(1)%ineigh, &
& nbsc, nbhy, nper, ntot, norbs, esh, esp3, bsp3, e0)
! Check the hermiticity of the hamiltonian and JD preconditioner.
if (.not.zchecksymmetry_sparse(1.d-6, h%aij, h%jmax, h%icol, ndim)) & & stop "Error, hamiltonian is not hermitian."
if (.not.zchecksymmetry_sparse(1.d-6, hp%aij, hp%jmax, hp%icol, ndim)) &
& stop "Error, bond preconditioner is not hermitian." ! Compute the wavefunctions.
if ((nval > 0).and.(scan(optk(ikpt), "-") == 0)) then ! Allocate memory for the wavefunctions.
allocate(eval(2,nval), evec(ndimeff,nval)) do ival = 1, nval
call zrand(evec(1,ival), ndimeff) call znormalize(evec(1,ival), ndimeff) enddo
! dbg_jdeig = 3 write (stdout, *)
call zjdeigin_ortho_sym(ndimeff, prodhv, solve, nodegeneracy, & & sigma, idir, epsilon_JD, &
& itnew_JD, itmax_JD, nkeep_JD, & & nval, eval, ndimeff, evec, & & ierr)
if (ierr /= 0) &
& write (stdout, '(/"Warning, JD failed and returned ierr = ",i3, & & " (",i4," wavefunctions were computed).")') ierr, nval
! Compute the conduction band minium and the valence band maximum. if (idir < 0) then
if (eval(1,1) > vbmax) then vbmax = eval(1,1)
kvbmax = kred endif
else
if (eval(1,1) < cbmin) then cbmin = eval(1,1)
kcbmin = kred endif
endif
! Analyze the wavefunctions.
write (stdout, '(/"Results for ikpt = ",i2," : k = ",f10.5,".")') ikpt, kred
call zanalyzewfn_ortho(nval, ndim, 2*ndimeff/ndim, eval, evec, nper, ityp)
! Write the wavefunctions to disk. idx = scan(optk(ikpt), "Ss") if (idx /= 0) then do jdx = idx, len_trim(optk(ikpt))-1 if (scan(optk(ikpt)(jdx+1:jdx+1), "0123456789") == 0) exit enddo if (jdx > idx) then read (optk(ikpt)(idx+1:jdx), *) nwfn else
nwfn = nval endif
nwfn = min(nwfn, nval)
call zwritewfnblock('wireZB_'//trim(id)//'.out', nwfn, ndim, 2*ndimeff/ndim, k, eval, evec)
endif
! Write the band structure to disk.
open (untfree, file = 'wireZB_'//trim(id)//'.bs', form = 'formatted', position = 'append')
do ival = 1, nval
write (untfree, '(f10.5,1x,f10.5)') kred, eval(1, ival) enddo
close (untfree) endif
! Free memory.
call free_zdsparsematrix(h)
if (precdt_bandext) call free_zdsparsematrix(hp) ! Search for band extremum, if appropriate.
idx = scan(optk(ikpt), "Ee") if (idx /= 0) then
read (optk(ikpt)(idx+1:),'(1x,f4.2,1x)') dkred idir_bandext = idir
sigma_bandext = sigma kred1 = kred-dkred kred2 = kred
kred3 = kred+dkred
write (stdout, '(/"Looking for band extremum in [",f10.5,",",f10.5,"].")') kred1, kred3
if (nval > 0) then
allocate(evec_bandext(ndimeff,nval_bandext)) call zcopy(evec(1,1), evec_bandext(1,1), ndimeff) endif
call brent(kred1, kred2, kred3, bandenergy, epsilon_kred, kred, ek, ierr)
if (ierr /= 0) then
write (stdout, '("Error, brent failed and returned ierr =