[ Home ] [ News ] [ Contact ] [ Search ]

 ==> Download Software
 nextnano³ documentation

 Copyright notice
 About us
 Useful Links
 Publications
 
 * password protected

 

 
 

Calculate eigenstates

The subroutine calculate_eigenstates calculates the new eigenstates for the given potential phiV [given on Stefan's grid on input].

 DO num_qr=1,num_qr_regions                          !  loops through all quantum regions

  call get_which_kp(num_qr,kpL,kind_kpC,chargeC)      ! checks, if kp is done

  !------------------------
  ! electrons
  !------------------------

  !---- kp - el ------------

   if ((kpL).and.((chargeC=='el').or.(chargeC=='bo'))) then ! if kp is done for electrons,
                                                                                                                    !  update kp states

      call update_kp(num_qr,phiV,'el')
   end if

  !-- sg - 1b --------------

   num_sg_el=sgChargeV(1)%qcV(num_qr)%num_sg_diff_en      ! now check single band Schrödinger
                                                                                          ! equation

   if (num_sg_el>0) then

   dim_qr=dim_qrV(num_qr)
 

   do num_sg=1,num_sg_el                                        !  loop through all Schrödinger equations

     call prepare_det_edge('el',num_sg)           !  get band edge corresponding to 
                                                                                          !  num_sg --> pot_condM for edge model

     num_deg=sgChargeV(1)%qcV(num_qr)%data_deg_sgM(num_sg)%num_deg
     chargeC='el'
     num_ev=sgChargeV(1)%qcV(num_qr)%data_deg_sgM(num_sg)%number_of_ev
     num_k_z=sgChargeV(1)%qcV(num_qr)%data_deg_sgM(num_sg)%num_K_z
     allocate(eigenvaluesV(num_ev),eigenfunctionsM(num_ev,dim_qr),  &
                                                        STAT=istatus)
     if (istatus/=0) stop 'error calculate_eigenstates: alloc. failed'

     do n_deg=1,num_deg                                ! loop through all degeneracies
                                                                                ! and (only 1D)superlattice-vectors

     do n_K_z=1,num_K_z
 
      K_z=sgChargeV(1)%qcV(num_qr)%data_deg_sgM(num_sg)%K_zV(n_K_z)
      call calculate_sg1D(num_qr,num_sg,n_deg,chargeC,phiV,K_z,     &
                                     num_ev,dim_qr,eigenvaluesV,eigenfunctionsM)
  ! calculate Schrödinger equation
      sgChargeV(1)%qcV(num_qr)%data_deg_sgM(num_sg)%                       &
                               eigenvaluesV(n_deg,n_K_z,1:num_ev)=eigenvaluesV
      sgChargeV(1)%qcV(num_qr)%data_deg_sgM(num_sg)%                       &
           eigenfunctionsM(n_deg,n_K_z,1:num_ev,1:dim_qr)=eigenfunctionsM
 
      SeparationModelC=sgChargeV(1)%qcV(num_qr)%data_deg_sgM(num_sg)%SeparationModelC

                                                                        ! determine new energy edge according to edge model

      call prepare_det_edge('el',num_sg)                ! get band edge corresponding to num_sg
      SeparationEnergyEdgeV = sgChargeV(1)%qcV(num_qr)%data_deg_sgM(num_sg)%energy_edge_input
                                                                                                                     ! get SeparationEnergyEdgeV from input

      call determine_edge_qm(dim_qr,pot_condM,hV,num_ev,          &
                             eigenvaluesV,'el',SeparationEnergyEdgeV,SeparationModelC)               ! returns new energy edge

      if ((n_deg==1).and.(n_K_z==1)) then
        sgChargeV(1)%qcV(num_qr)%data_deg_sgM(num_sg)%energy_edge=minval(SeparationEnergyEdgeV)
                                                                             ! note: only energy edge different for different num_sg
      else
          sgChargeV(1)%qcV(num_qr)%data_deg_sgM(num_sg)%energy_edge=             &
          min(minval(SeparationEnergyEdgeV),sgChargeV(1)%qcV(num_qr)%data_deg_sgM(num_sg)%energy_edge)
                                                                                    ! so take minimum for different degenerate bands

      end if

      end do
     end do

     deallocate(eigenvaluesV,eigenfunctionsM)
     deallocate(pot_condM,hV,SeparationEnergyEdgeV)

   end do

   end if

 

!============================================================================

NOTE: The separation energy is determined in subroutine determine_edge_qm. This subroutine needs the band edges in the quantum region, which are calculated in subroutine prepare_det_edge in pot_condM and pot_valM.

 subroutine prepare_det_edge(chargeC,num_sg)                       !   calculates bandedge for edge-model
 !------------------------------------------------------------------------                   !   in pot_condM  and pot_valM
 ! sets up pot_condM,pot_valM in [eV]
 !  in [eV]

 !------------------------------------------------------------------------

 ...............

 select case(chargeC)
 case('hl')

  ..............

 case('el')

 DO i=1,dim_qr

   i_phys=inv_quantumreg_num1DV(num_qr,i)
   call extract_octants1D(octV,i_phys)
   mat1=mat_numberV(octV(1))
   mat2=mat_numberV(octV(2))
   mat_ind1=map_qr_to_materialV(mat1,num_qr)
   mat_ind2=map_qr_to_materialV(mat2,num_qr)
   ind_l=def_quantum_modelsM(num_qr)%data_sg_elM(num_sg)%bandnumV(mat_ind1)
   ind_r=def_quantum_modelsM(num_qr)%data_sg_elM(num_sg)%bandnumV(mat_ind2)
   pot_l=E_cM(ind_l,octV(1))/abs(electron_charge) -phiV(octV(1))
   pot_r=E_cM(ind_r,octV(2))/abs(electron_charge) -phiV(octV(2))

   if (octV(1)/=octV(2)) then        !--- multiple point ----           ! note: on boundaries of quantum region
     call octants_in_qr(num_qr,i_phys,inVL)                         !       the only bandedges of octants which
                                                                                       !       lie within quantum region are taken.
                                                                                       !       Mind the general hints on
                                                                                       !       Schrödinger equation.

     if (all(inVL)) then
        pot_condM(i,1)=pot_l
        pot_condM(i,2)=pot_r
     else if (inVL(1)) then
        pot_condM(i,1)=pot_l
        pot_condM(i,2)=pot_l
     else if (inVL(2)) then
        pot_condM(i,1)=pot_r
        pot_condM(i,2)=pot_r
     end if
   else
     pot_condM(i,1)=pot_l
     pot_condM(i,2)=pot_r
   end if

END DO

end select

end subroutine prepare_det_edge

subroutine octants_in_qr(num_qr,i_phys,inVL)
!----------------------------------------------------------------------
! decides on basis of quantum_gridM
! which octants are in quantum region num_qr
! if so, inVL(xx) =.true.
!----------------------------------------------------------------------
USE gitter1D,only:quantum_gridM
implicit none

integer,intent(in) :: num_qr,i_phys
logical,dimension(2),intent(out) :: inVL

integer :: i_min,i_and
!--------------------------------------------

if (quantum_gridM(i_phys,1,1)/=num_qr) &
stop 'error calculate_sg1D: internal inconsistency'
i_min=i_phys-1
i_and=i_phys+1

inVL=.true.

if (quantum_gridM(i_min,1,1)/=num_qr) inVL(1)=.false.
if (quantum_gridM(i_and,1,1)/=num_qr) inVL(2)=.false.

end subroutine octants_in_qr

 

   
Last modified: 09-Jun-2011