Changeset 6353

Show
Ignore:
Timestamp:
03/16/10 15:56:54 (6 months ago)
Author:
nitsche
Message:

Rewrote much of the transport code to simplify the modularization (as the next step).
Due to some algorithmic changes most of the complicated restart procedure is not neccessary anymore and is replaced by standard routines.

* removed the symmetric version of the interface matrix vector multiplication
* the central region is no more enlarged
* the Lippmann-Schwinger calculation now shows a progress bar
* now a magnetic groundstate is also supported
* removed some push/pop in the left hand side Lippmann-Schwinger subroutine as these are called many times during a magnetic gs calculation
* The projected part of the lead wave function is now written to a file and then read by the td run.
* the self energy is now directly calculated and stored instead of the surface Green's function
* improved debugging output for the surface Green's function
* Most of the reading part for the extended central region is now obsolete.
* The subroutine restart_read now correctly reads the weights of the kpoints.
* The INNER/OUTER logic of the interface wave function now is obsolete.
* The progress of the convergence of the Crank-Nicholson solver is shown in the debug mode.
* The zeroth source term now uses the lead wave function calculated via the self energy.
* removed an apostroph which caused a compiler warning
* The transport td run does not need a special open boundary gs calculation anymore, a normal gs would also be sufficient (although not recommended for the transport mode).
* one test of the open boundary testsuite failed because energy was the matching criteria. Since the central region is not artificially enlarged anymore the resulting energy for this region is also different.
* adjusted some tests as the values coming from the new algorithm slightly changed

Location:
trunk
Files:
15 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/grid/ob_interface.F90

    r6250 r6353  
    3838  public ::                 & 
    3939    lead_t,                 & 
    40     interface_apply_sym_op, & 
    4140    interface_apply_op,     & 
    4241    interface_t,            & 
     
    261260 
    262261  ! --------------------------------------------------------- 
    263   ! Apply an np x np symmetric operator op to the interface region of the wavefunction. 
    264   ! np is the number of points in the interface: res <- res + alpha op wf 
    265   subroutine interface_apply_sym_op(intf, alpha, op, wf, res) 
    266     type(interface_t), intent(in)    :: intf 
    267     CMPLX,             intent(in)    :: alpha 
    268     CMPLX,             intent(in)    :: op(:, :) 
    269     CMPLX,             intent(in)    :: wf(:) 
    270     CMPLX,             intent(inout) :: res(:) 
    271      
    272     CMPLX, allocatable :: intf_wf(:), op_intf_wf(:) 
    273  
    274     call push_sub('ob_interface.interface_apply_sym_op') 
    275  
    276     SAFE_ALLOCATE(intf_wf(1:intf%np_uc)) 
    277     SAFE_ALLOCATE(op_intf_wf(1:intf%np_uc)) 
    278  
    279     call get_intf_wf(intf, wf, intf_wf) 
    280     call get_intf_wf(intf, res, op_intf_wf) 
    281     call lalg_symv(intf%np_uc, alpha, op, intf_wf, M_z1, op_intf_wf) 
    282     call put_intf_wf(intf, op_intf_wf, res) 
    283  
    284     SAFE_DEALLOCATE_A(intf_wf) 
    285     SAFE_DEALLOCATE_A(op_intf_wf) 
    286  
    287     call pop_sub() 
    288   end subroutine interface_apply_sym_op 
    289  
    290  
    291   ! --------------------------------------------------------- 
    292262  ! Write number of interface points. 
    293263  subroutine interface_write_info(intf, iunit) 
  • trunk/src/ions/simul_box.F90

    r6341 r6353  
    7777    BEFORE    = 7,              & ! for 4D open system 
    7878    AFTER     = 8,              & ! 
    79     OUTER     = 1,              & ! Block indices of interface wavefunctions 
    80     INNER     = 2,              & ! for source term. 
    8179    TRANS_DIR = 1                 ! Transport is in x-direction. 
    8280 
     
    361359              call write_fatal(1) 
    362360            end if 
    363             ! If we are doing a ground-state calculation add one more unit 
    364             ! cell at both ends to calculate the extended eigenstates. 
    365             if(calc_mode_is(CM_GS)) then 
    366               sb%add_unit_cells(1:NLEADS) = sb%add_unit_cells(1:NLEADS) + 1 
    367             end if 
    368361          case(TD_POT_FORMULA) 
    369362            call parse_block_string(blk, nr, 1, sb%lead_td_pot_formula(LEFT)) 
  • trunk/src/scf/ground_state.F90

    r6349 r6353  
    7070      call states_allocate_free_states(sys%st, sys%gr) 
    7171      call read_free_states(sys%st, sys%gr) 
    72       ! allocate Green`s function and calculate 
    73       call states_init_green(sys%st, sys%gr, hm%d%nspin, hm%d%ispin, hm%lead) 
     72      ! allocate self_energy and calculate 
     73      call states_init_self_energy(sys%st, sys%gr, hm%d%nspin, hm%d%ispin, hm%lead) 
    7474    end if 
    7575 
  • trunk/src/scf/ob_lippmann_schwinger.F90

    r6167 r6353  
    3232  use io_function_m 
    3333  use lalg_basic_m 
     34  use loct_m 
    3435  use math_m 
    3536  use messages_m 
     
    5051    lippmann_schwinger 
    5152 
    52   type pg 
    53     CMPLX, pointer           :: green(:, :, :) 
    54   end type pg 
     53  type p_se_t 
     54    CMPLX, pointer           :: self_energy(:, :, :) 
     55  end type p_se_t 
    5556 
    5657  ! Pointers to communicate with iterative linear solver. 
    5758  integer, pointer             :: ist_p, ik_p 
    5859  FLOAT, pointer               :: energy_p 
    59   type(pg), pointer            :: lead_p(:) 
     60  type(p_se_t), pointer        :: lead_p(:) 
    6061  type(grid_t), pointer        :: gr_p 
    6162  type(hamiltonian_t), pointer :: hm_p 
     
    7879    FLOAT                      :: tol, res 
    7980    CMPLX, allocatable         :: rhs(:, :) 
    80     type(pg), target           :: lead(2*MAX_DIM) 
     81    type(p_se_t), target       :: lead(2*MAX_DIM) 
    8182    logical                    :: conv 
    8283#ifdef HAVE_MPI 
     
    9495        np = gr%intf(il)%np_uc 
    9596      end if 
    96       SAFE_ALLOCATE(lead(il)%green(1:np, 1:np, 1:st%d%dim)) 
     97      SAFE_ALLOCATE(lead(il)%self_energy(1:np, 1:np, 1:st%d%dim)) 
    9798    end do 
    9899 
     
    108109    energy_p => energy 
    109110 
     111    ASSERT(ubound(st%zphi, dim = 1) >= gr%mesh%np_part) 
     112 
     113    ! We have many k-points, so show the progress 
     114    if(mpi_grp_is_root(mpi_world)) call loct_progress_bar(-1, st%nst*st%d%nik) 
     115 
    110116    do ik = st%d%kpt%start, st%d%kpt%end 
    111117      do ist = st%st_start, st%st_end 
    112         ! Solve Schroedinger equation for this energy. 
     118        ! Solve Lippmann-Schwinger equation for this energy. 
    113119        energy = st%ob_eigenval(ist, ik) 
    114120        st%eigenval(ist, ik) = energy 
    115  
    116         ASSERT(ubound(st%zphi, dim = 1) >= gr%mesh%np_part) 
     121        do il = 1, NLEADS 
     122          lead(il)%self_energy(:, :, :) = st%ob_lead(il)%self_energy(:, :, :, ist, ik) 
     123        end do 
    117124 
    118125        ! Calculate right hand side e-T-V0-sum(a)[H_ca*g_a*H_ac]. 
    119         rhs(:, :) = M_z0 
    120         call zhamiltonian_apply(hm, gr%der, st%zphi(:, :, ist, ik), rhs(:, :), ist, ik, kinetic_only=.true.) 
    121  
    122         ! Apply lead potential. 
    123         ! FIXME: this wrong when non-symmetric leads are used, here the periodicity is assumed 
    124         ! for the Lippmann-Schwinger solution 
    125         do idim = 1, st%d%dim 
    126           do ip = 1, gr%mesh%np 
    127             ip_lead = mod(ip-1, gr%intf(LEFT)%np_intf) + 1 
    128             rhs(ip, idim) = rhs(ip, idim) + hm%lead(LEFT)%vks(ip_lead, idim)*st%zphi(ip, idim, ist, ik) 
    129           end do 
    130         end do 
    131  
    132         ! Add energy. 
    133         do idim = 1, st%d%dim 
    134           rhs(1:gr%mesh%np, idim) = energy*st%zphi(1:gr%mesh%np, idim, ist, ik) - rhs(1:gr%mesh%np, idim) 
    135         end do 
    136  
    137         ! Apply term with lead Green functions. 
    138         do il = 1, NLEADS 
    139           do idim = 1, st%d%dim 
    140             np_intf = gr%intf(il)%np_intf 
    141             call apply_coupling(st%ob_lead(il)%green(1:np_intf, 1:np_intf, idim, ist, ik), & 
    142                             hm%lead(il)%h_offdiag(:, :), lead(il)%green(:, :, idim), np_intf, il) 
    143           end do 
    144         end do 
    145         do il = 1, NLEADS 
    146           do idim = 1, st%d%dim 
    147             if (associated(hm%ep%A_static)) then ! magnetic gs 
    148               call interface_apply_op(gr%intf(il), -M_z1, lead(il)%green(:, :, idim), & 
    149                 st%zphi(:, idim, ist, ik), rhs(:, idim)) 
    150             else 
    151               call interface_apply_sym_op(gr%intf(il), -M_z1, lead(il)%green(:, :, idim), & 
    152                 st%zphi(:, idim, ist, ik), rhs(:, idim)) 
    153             end if 
    154           end do 
    155         end do 
    156  
    157         if (associated(hm%ep%A_static)) then ! magnetic gs 
    158         ! FIXME: multiply rhs with (e-h-g)^T 
    159         else 
    160         end if 
     126        call calc_rhs(st%zphi(:, :, ist, ik), rhs) 
     127 
     128        if (associated(hm%ep%A_static)) call calc_rhs(rhs, rhs, .true.) ! multiply transposed version 
     129 
    161130        ! Solve linear system lhs psi = rhs. 
    162131        iter = eigens%es_maxiter 
     
    164133 
    165134        conv = .false. 
    166         call zqmr_sym(gr%mesh%np_part*st%d%dim, st%zpsi(:, 1, ist, ik), rhs(:, 1), lhs, dotu, nrm2, precond, & 
    167           iter, residue=res, threshold=tol, converged=conv) 
    168         ! call zqmr(gr%mesh%np_part*st%d%dim, st%zpsi(:, 1, ist, ik), rhs(:, 1), lhs, lhs_t, & 
    169         !   precond, precond, iter, residue=dres, threshold=tol, converged=conv, showprogress=.true.) 
     135        if (associated(hm%ep%A_static)) then ! magnetic gs 
     136          call zqmr_sym(gr%mesh%np_part*st%d%dim, st%zpsi(:, 1, ist, ik), rhs(:, 1), lhs_symmetrized, dotu, & 
     137            nrm2, precond, iter, residue=res, threshold=tol, converged=conv, showprogress=in_debug_mode) 
     138        else 
     139          call zqmr_sym(gr%mesh%np_part*st%d%dim, st%zpsi(:, 1, ist, ik), rhs(:, 1), lhs, dotu, nrm2, precond, & 
     140            iter, residue=res, threshold=tol, converged=conv, showprogress=in_debug_mode) 
     141        end if 
     142        if(in_debug_mode) then ! write info 
     143          write(message(1), '(a,i8,e10.3)') 'Iterations, Residual: ', iter, res 
     144          call write_info(1) 
     145        end if 
    170146 
    171147        eigens%matvec = eigens%matvec + iter + 1 + 2 
    172         if(conv) then 
    173           eigens%converged = eigens%converged + 1 
    174         end if 
     148        if(conv) eigens%converged = eigens%converged + 1 
    175149        eigens%diff(ist, ik) = res 
     150        if(mpi_grp_is_root(mpi_world)) call loct_progress_bar(st%nst*(ik - 1), st%nst*st%d%nik) 
    176151      end do 
    177152    end do 
     
    199174    SAFE_DEALLOCATE_A(rhs) 
    200175    do il = 1, NLEADS 
    201       SAFE_DEALLOCATE_P(lead(il)%green) 
     176      SAFE_DEALLOCATE_P(lead(il)%self_energy) 
    202177    end do 
    203178 
    204179    call pop_sub() 
    205180  end subroutine lippmann_schwinger 
     181 
     182 
     183  ! --------------------------------------------------------- 
     184  ! The right hand side of the Lippmann-Schwinger equation 
     185  ! e-T-V0-sum(a)[H_ca*g_a*H_ac]. 
     186  subroutine calc_rhs(zphi, rhs, transposed) 
     187    CMPLX, intent(in)             :: zphi(:, :) 
     188    CMPLX, intent(out)            :: rhs(:, :) 
     189    logical, optional, intent(in) :: transposed ! needed only for the non hermitian part 
     190 
     191    integer :: ip, idim, il 
     192    logical :: transposed_ 
     193    CMPLX, allocatable :: tmp(:, :) 
     194 
     195    call push_sub('ob_lippmann_schwinger.calc_rhs') 
     196 
     197    SAFE_ALLOCATE(tmp(1:gr_p%mesh%np_part, 1:st_p%d%dim)) 
     198 
     199    transposed_ = .false. 
     200    if(present(transposed)) transposed_ = transposed 
     201 
     202    if(transposed_) then ! the usual conjugate trick for the hermitian part 
     203      tmp = conjg(zphi) 
     204    else 
     205      tmp = zphi 
     206    end if 
     207    ! Calculate right hand side e-T-V0-sum(a)[H_ca*g_a*H_ac]. 
     208    rhs(:, :) = M_z0 
     209 
     210    call zhamiltonian_apply(hm_p, gr_p%der, tmp, rhs, ist_p, ik_p, kinetic_only=.true.) 
     211 
     212    ! Apply lead potential. Left and right lead potential are assumed to be equal. 
     213    forall(ip = 1:gr_p%mesh%np ) 
     214      rhs(ip, :) = rhs(ip, :) + hm_p%lead(LEFT)%vks(mod(ip-1, gr_p%intf(LEFT)%np_intf) + 1, :) * tmp(ip, :) 
     215    end forall 
     216 
     217    ! Add energy. 
     218    forall(ip = 1:gr_p%mesh%np ) rhs(ip, :) = energy_p * tmp(ip, :) - rhs(ip, :) 
     219 
     220    if(transposed_) then 
     221      rhs = conjg(rhs) 
     222      tmp = conjg(tmp) ! restore original 
     223    end if 
     224 
     225    do il = 1, NLEADS 
     226      do idim = 1, st_p%d%dim 
     227        if(transposed_) then 
     228          call interface_apply_op(gr_p%intf(il), -M_z1, transpose(lead_p(il)%self_energy(:, :, idim)), & 
     229                                tmp(:, idim), rhs(:, idim)) 
     230        else 
     231          call interface_apply_op(gr_p%intf(il), -M_z1, lead_p(il)%self_energy(:, :, idim), & 
     232                                tmp(:, idim), rhs(:, idim)) 
     233        end if 
     234      end do 
     235    end do 
     236     
     237    SAFE_DEALLOCATE_A(tmp) 
     238    call pop_sub() 
     239  end subroutine calc_rhs 
    206240 
    207241 
     
    212246    CMPLX, intent(in) :: y(:) 
    213247 
    214     integer :: np_part, np, dim, idim 
     248    integer :: np_part, np, idim 
    215249    CMPLX   :: dot 
    216250 
    217     call push_sub('ob_lippmann_schwinger.dotu') 
     251!    call push_sub('ob_lippmann_schwinger.dotu') 
    218252 
    219253    np_part = gr_p%mesh%np_part 
    220254    np      = gr_p%mesh%np 
    221     dim     = st_p%d%dim 
    222255 
    223256    dot = M_ZERO 
    224     do idim = 1, dim 
     257    do idim = 1, st_p%d%dim 
    225258      dot = dot + blas_dotu(np, x(l(idim)), 1, y(l(idim)), 1) 
    226259    end do 
    227260    dotu = dot 
    228261 
    229     call pop_sub() 
     262!    call pop_sub() 
    230263 
    231264  contains 
     
    245278    CMPLX, intent(in) :: x(:) 
    246279 
    247     integer :: np_part, np, dim, idim 
     280    integer :: np_part, np, idim 
    248281    FLOAT   :: nrm 
    249282 
    250     call push_sub('ob_lippmann_schwinger.nrm2') 
     283!    call push_sub('ob_lippmann_schwinger.nrm2') 
    251284 
    252285    np_part = gr_p%mesh%np_part 
    253286    np      = gr_p%mesh%np 
    254     dim     = st_p%d%dim 
    255287 
    256288    nrm = M_ZERO 
    257     do idim = 1, dim 
     289    do idim = 1, st_p%d%dim 
    258290      nrm = nrm + lalg_nrm2(np, x(l(idim):u(idim))) 
    259291    end do 
    260292    nrm2 = nrm 
    261293 
    262     call pop_sub() 
     294!    call pop_sub() 
    263295 
    264296  contains 
     
    290322    integer            :: np_part, idim, il, dim 
    291323 
    292     call push_sub('ob_lippmann_schwinger.lhs') 
     324!    call push_sub('ob_lippmann_schwinger.lhs') 
    293325 
    294326    np_part = gr_p%mesh%np_part 
     
    305337    ! y <- e x - tmp_y 
    306338    do idim = 1, dim 
    307       y(l(idim):u(idim)) = energy_p*x(l(idim):u(idim)) - tmp_y(1:np_part, idim) 
     339      tmp_y(:, idim) = energy_p * x(l(idim):u(idim)) - tmp_y(1:np_part, idim) 
    308340    end do 
    309341 
    310342    do il = 1, NLEADS 
    311343      do idim = 1, dim 
    312         call interface_apply_sym_op(gr_p%intf(il), & 
    313           -M_z1, lead_p(il)%green(:, :, idim), tmp_x(:, idim), y(l(idim):u(idim))) 
     344        call interface_apply_op(gr_p%intf(il), -M_z1, & 
     345          lead_p(il)%self_energy(:, :, idim), tmp_x(:, idim), tmp_y(:, idim)) 
    314346      end do 
     347    end do 
     348 
     349    do idim = 1, dim 
     350      y(l(idim):u(idim)) = tmp_y(1:np_part, idim) 
    315351    end do 
    316352 
    317353    SAFE_DEALLOCATE_A(tmp_x) 
    318354    SAFE_DEALLOCATE_A(tmp_y) 
    319     call pop_sub() 
     355!    call pop_sub() 
    320356 
    321357  contains 
     
    333369    end function u 
    334370  end subroutine lhs 
     371 
     372 
     373  ! --------------------------------------------------------- 
     374  ! The left hand side of the Lippmann-Schwinger equation 
     375  ! (e-H-sum(a)[H_ca*g_a*H_ac])^T. 
     376  ! Used by the iterative linear solver. 
     377  subroutine lhs_t(x, y) 
     378    CMPLX, intent(in)  :: x(:) 
     379    CMPLX, intent(out) :: y(:) 
     380 
     381    CMPLX, allocatable :: tmp_x(:, :) 
     382    CMPLX, allocatable :: tmp_y(:, :) 
     383    integer            :: np_part, idim, il, dim 
     384 
     385!    call push_sub('ob_lippmann_schwinger.lhs_t') 
     386 
     387    np_part = gr_p%mesh%np_part 
     388    dim     = st_p%d%dim 
     389 
     390    SAFE_ALLOCATE(tmp_x(1:np_part, 1:dim)) 
     391    SAFE_ALLOCATE(tmp_y(1:np_part, 1:dim)) 
     392 
     393    do idim = 1, dim 
     394      tmp_x(1:np_part, idim) = conjg(x(l(idim):u(idim))) 
     395    end do 
     396    call zhamiltonian_apply(hm_p, gr_p%der, tmp_x, tmp_y, ist_p, ik_p) 
     397 
     398    ! y <- e x - tmp_y 
     399    do idim = 1, dim 
     400      tmp_y(1:np_part, idim) = energy_p * tmp_x(1:np_part, idim) - tmp_y(1:np_part, idim) 
     401    end do 
     402    tmp_y = conjg(tmp_y) 
     403    tmp_x = conjg(tmp_x) ! restore for the non-hermitian part 
     404 
     405    do il = 1, NLEADS 
     406      do idim = 1, dim 
     407        call interface_apply_op(gr_p%intf(il), -M_z1, transpose(lead_p(il)%self_energy(:, :, idim)), & 
     408                                tmp_x(:, idim), tmp_y(:, idim)) 
     409      end do 
     410    end do 
     411 
     412    do idim = 1, dim 
     413      y(l(idim):u(idim)) = tmp_y(1:np_part, idim) 
     414    end do 
     415 
     416    SAFE_DEALLOCATE_A(tmp_x) 
     417    SAFE_DEALLOCATE_A(tmp_y) 
     418!    call pop_sub() 
     419 
     420  contains 
     421 
     422    integer function l(idim) 
     423      integer, intent(in) :: idim 
     424 
     425      l = (idim-1)*np_part+1 
     426    end function l 
     427 
     428    integer function u(idim) 
     429      integer, intent(in) :: idim 
     430 
     431      u = l(idim)+np_part-1 
     432    end function u 
     433  end subroutine lhs_t 
     434 
     435 
     436  ! --------------------------------------------------------- 
     437  ! The left hand side of the Lippmann-Schwinger equation 
     438  ! (e-H-sum(a)[H_ca*g_a*H_ac])^T*(e-H-sum(a)[H_ca*g_a*H_ac]). 
     439  ! Used by the iterative linear solver. 
     440  subroutine lhs_symmetrized(x, y) 
     441    CMPLX, intent(in)  :: x(:) 
     442    CMPLX, intent(out) :: y(:) 
     443 
     444!    call push_sub('ob_lippmann_schwinger.lhs_symmetrized') 
     445 
     446    call lhs(x, y) 
     447    call lhs_t(y, y) 
     448 
     449!    call pop_sub() 
     450  end subroutine lhs_symmetrized 
    335451 
    336452 
     
    343459    CMPLX, intent(out) :: y(:) 
    344460 
    345     call push_sub('ob_lippmann_schwinger.precond') 
     461!    call push_sub('ob_lippmann_schwinger.precond') 
    346462 
    347463    y(:) = x(:) 
    348464 
    349     call pop_sub() 
     465!    call pop_sub() 
    350466  end subroutine precond 
    351467end module ob_lippmann_schwinger_m 
  • trunk/src/scf/scf.F90

    r6349 r6353  
    576576      call scf_write_static(STATIC_DIR, "info") 
    577577      call h_sys_output_all(outp, gr, geo, st, hm, STATIC_DIR) 
     578 
     579      if(gr%sb%open_boundaries) then ! write part of the source term s(0) 
     580        call states_write_proj_lead_wf('open_boundaries/', gr%intf, st) 
     581      end if 
     582 
    578583    end if 
    579584 
  • trunk/src/states/ob_green.F90

    r6270 r6353  
    2424module ob_green_m 
    2525  use global_m 
    26   use grid_m 
    2726  use lalg_adv_m 
    2827  use lalg_basic_m 
    29   use parser_m 
    3028  use math_m 
    3129  use messages_m 
    32   use nl_operator_m 
    3330  use ob_interface_m 
    3431  use profiling_m 
    3532  use simul_box_m 
    36   use string_m 
    3733 
    3834  implicit none 
     
    4036 
    4137  public ::         & 
    42     lead_green 
     38    lead_self_energy 
    4339 
    4440contains 
    4541 
    46   ! calculate the surface Green`s function 
     42  ! calculate the lead self energy 
    4743  ! prefer the fast method if possible, but if not converged check also other method 
    48   subroutine lead_green(energy, diag, offdiag, intf, green, h_is_real) 
     44  subroutine lead_self_energy(energy, diag, offdiag, intf, self_energy, h_is_real) 
    4945    FLOAT,             intent(in)  :: energy        ! Energy to calculate Green`s function for. 
    5046    CMPLX,             intent(in)  :: diag(:, :)    ! Diagonal block of lead Hamiltonian. 
    5147    CMPLX,             intent(in)  :: offdiag(:, :) ! Off-diagonal block of lead Hamiltonian. 
    5248    type(interface_t), intent(in)  :: intf          ! => gr%intf(il) 
    53     CMPLX,             intent(out) :: green(:, :)   ! The calculated Green`s function. 
     49    CMPLX,             intent(inout) :: self_energy(:, :) ! The calculated self_energy. 
    5450    logical,           intent(in)  :: h_is_real     ! Is the Hamiltonian real? (no vector potential) 
    5551 
     
    5955    CMPLX, allocatable :: green2(:, :) 
    6056 
    61     call push_sub('ob_green.lead_green') 
     57    call push_sub('ob_green.lead_self_energy') 
    6258 
    6359    np = intf%np_intf 
     
    7268    ! we have only one way of calculating the Green`s function: with the Sancho method 
    7369    if(.not.intf%reducible) then ! use large matrices (rank = np_uc) 
    74       call lead_green_sancho(c_energy, diag, offdiag, np_uc, green, threshold, h_is_real) 
    75       residual = calc_residual_green(energy, green, diag, offdiag, intf) 
     70      call lead_green_sancho(c_energy, diag, offdiag, np_uc, self_energy, threshold, h_is_real) 
     71      residual = calc_residual_green(energy, self_energy, diag, offdiag, intf) 
    7672      if(in_debug_mode) then ! write info 
    7773        write(message(1), '(a)') 'Non-reducible unit cell' 
     
    8177    else 
    8278      ! 1. calculate with the fastest method 
    83       call lead_green_umerski(c_energy, diag, offdiag, intf, green) 
     79      call lead_green_umerski(c_energy, diag, offdiag, intf, self_energy) 
    8480      ! 2. check if converged 
    85       residual = calc_residual_green(energy, green, diag, offdiag, intf) 
     81      residual = calc_residual_green(energy, self_energy, diag, offdiag, intf) 
    8682      if(in_debug_mode) then ! write info 
    8783        write(message(1), '(a,e10.3)') 'Umerski-Residual = ', residual 
     
    9995        ! 4. if also not converged choose the best one and give warning 
    10096        if(residual2.lt.eps) then ! finally converged 
    101           green = green2 
     97          self_energy = green2 
    10298        else ! write warning 
    10399          if(residual2.lt.residual) then 
    104             green = green2 
     100            self_energy = green2 
    105101          end if 
    106102          message(1) = 'The surface Green`s function did not converge properly' 
     
    115111      end if 
    116112    end if 
    117  
    118     call pop_sub() 
    119   end subroutine lead_green 
     113    ! now calculate the self energy 
     114    if(intf%il.eq.LEFT) then 
     115      call lalg_trmm(np, np, 'U', 'N', 'L', M_z1, offdiag, self_energy) 
     116      call lalg_trmm(np, np, 'U', 'T', 'R', M_z1, offdiag, self_energy) 
     117    else 
     118      call lalg_trmm(np, np, 'L', 'N', 'L', M_z1, offdiag, self_energy) 
     119      call lalg_trmm(np, np, 'L', 'T', 'R', M_z1, offdiag, self_energy) 
     120    end if 
     121 
     122    call pop_sub() 
     123  end subroutine lead_self_energy 
    120124 
    121125 
    122126  ! check if the Green`s function gives the correct density of states 
    123127  ! if not compute its Hermitian conjugate 
    124   subroutine fix_green(np, green, dos) 
     128  subroutine fix_green(np, green) 
    125129    integer, intent(in)    :: np 
    126130    CMPLX,   intent(inout) :: green(:, :) 
    127     FLOAT,   intent(out)   :: dos 
    128131 
    129132    integer  :: j 
     133    FLOAT    :: dos 
    130134 
    131135    call push_sub('ob_green.fix_green') 
     
    136140      dos = dos - aimag(green(j, j)) 
    137141    end do 
     142 
     143    if(in_debug_mode) then ! write info 
     144      write(message(1), '(a,e10.3)') 'density of states = ', abs(dos) 
     145      call write_info(1) 
     146    end if 
     147 
    138148    if(dos.lt.M_ZERO) then 
    139149      green(:, :) = transpose(conjg(green(:, :))) 
     150      if(in_debug_mode) then ! write info 
     151        message(1) = "surface Green's function changed to its hermitian conjugate" 
     152        call write_info(1) 
     153      end if 
    140154    end if 
    141155 
     
    207221    CMPLX, allocatable :: tmp1(:, :), tmp2(:, :), tmp3(:, :) 
    208222    integer            :: i, j 
    209     FLOAT              :: dos, old_norm, norm, res 
     223    FLOAT              :: det, old_norm, norm, res 
    210224 
    211225    call push_sub('ob_green.lead_green_sancho') 
     
    236250 
    237251      forall (j = 1:np) inv(j, j) = inv(j, j) + energy 
    238       dos = lalg_inverter(np, inv, invert=.true.) 
     252      det = lalg_inverter(np, inv, invert=.true.) 
    239253 
    240254      call lalg_gemm(np, np, np, M_z1, a, inv, M_z0, tmp2) 
     
    262276 
    263277    forall (j = 1:np) green(j, j) = green(j, j) + energy 
    264     dos = lalg_inverter(np, green, invert = .true.) 
     278    det = lalg_inverter(np, green, invert = .true.) 
    265279    if (h_is_real) then ! the Green`s function is complex symmetric 
    266280      call matrix_symmetric_average(green, np) 
    267281    end if ! otherwise it is general complex 
    268282 
    269     call fix_green(np, green, dos) 
    270  
    271283    if(in_debug_mode) then ! write some info 
    272       write(message(1), '(a,e10.3)') 'Sancho-DOS = ', dos 
     284      message(1) = "surface Green's function: iterative algorithm" 
    273285      call write_info(1) 
    274286    end if 
     287 
     288    call fix_green(np, green) 
    275289 
    276290    SAFE_DEALLOCATE_A(e) 
     
    393407    integer              :: ib, np, np2 
    394408    CMPLX, allocatable   :: x(:,:), x2(:,:), o2(:,:), o4(:,:), d(:), h(:, :, :), v(:, :, :) 
    395     FLOAT                :: dos 
     409    FLOAT                :: det 
    396410 
    397411    call push_sub('ob_green.lead_green_umerski') 
     
    435449    o4(1:np, 1:np) = x(np+1:np2, np+1:np2) 
    436450    ! 4. calculate green = o2*o4^(-1) 
    437     dos = lalg_inverter(np, o4, invert = .true.) 
     451    det = lalg_inverter(np, o4, invert = .true.) 
    438452    call zgemm('N', 'N', np, np, np, M_z1, o2, np, o4, np, M_z0, green, np) 
    439453 
    440     call fix_green(np, green, dos) 
    441454    if(in_debug_mode) then ! write some info 
    442       write(message(1), '(a,e10.5)') 'Umerski: DOS = ', dos 
     455      message(1) = "surface Green's function: direct algorithm (Moebius transformation)" 
    443456      call write_info(1) 
    444457    end if 
     458 
     459    call fix_green(np, green) 
    445460 
    446461    SAFE_DEALLOCATE_A(x) 
  • trunk/src/states/restart.F90

    r6349 r6353  
    2828  use io_m 
    2929  use io_function_m 
     30  use lalg_basic_m 
    3031  use linear_response_m 
    3132  use loct_m 
     
    3637  use messages_m 
    3738  use mpi_m 
     39  use ob_green_m 
    3840  use parser_m 
    3941  use profiling_m 
     
    5658    restart_write,           & 
    5759    restart_read,            & 
    58     restart_read_ob_intf,    & 
    59     restart_read_ob_central, & 
     60    restart_get_ob_intf,     & 
    6061    restart_format,          & 
    6162    restart_dir,             & 
     
    365366 
    366367  ! --------------------------------------------------------- 
    367   ! Reads the interface regions of the ground-state wavefunctions of 
    368   ! an open-boundaries calculation. 
    369   ! Can also read the inner interface wf of a non-open boundary gs calculation 
    370   ! Returns (in ierr) 
    371   ! <0 => Fatal error, 
    372   ! =0 => read all wavefunctions, 
    373   ! >0 => could only read x wavefunctions. 
    374   subroutine restart_read_ob_intf(dir, st, gr, ierr) 
    375     character(len=*), intent(in)    :: dir 
     368  ! Reads the interface regions of the wavefunctions 
     369  subroutine restart_get_ob_intf(st, gr) 
    376370    type(states_t),   intent(inout) :: st 
    377     type(grid_t),     intent(inout) :: gr 
    378     integer,          intent(out)   :: ierr 
    379  
    380     integer              :: io_wfns, io_occs, io_mesh, np, lead_np, np_uc, int, err, il, ip 
    381     integer              :: ik, ist, idim, tnp 
    382     FLOAT                :: flt 
    383     character            :: char 
    384     character(len=256)   :: line, filename 
    385     CMPLX, allocatable   :: tmp(:) 
    386     type(mesh_t)         :: gs_mesh 
    387     type(mpi_grp_t)      :: mpi_grp 
    388  
    389     call push_sub('restart.restart_read_ob_intf') 
     371    type(grid_t),     intent(in) :: gr 
     372 
     373    integer              :: ik, ist, idim, il, ip 
     374 
     375    call push_sub('restart.restart_get_ob_intf') 
    390376 
    391377    write(message(1), '(a,i5)') 'Info: Reading ground-state interface wavefunctions.' 
    392378    call write_info(1) 
    393379 
    394     mpi_grp = mpi_world 
    395380    ! Sanity check. 
    396381    do il = 1, NLEADS 
     
    399384    end do 
    400385 
    401     ierr = 0 
    402  
    403     ! Read the mesh of the ground-state calculation. 
    404     io_mesh = io_open(trim(dir)//'/mesh', action='read', status='old', die=.false., is_tmp=.true.) 
    405     if(io_mesh.lt.0) then 
    406       ierr = -1 
    407       call io_close(io_mesh, grp=mpi_grp) 
    408       call pop_sub() 
    409       return 
    410     end if 
    411        
    412     gs_mesh%sb => gr%mesh%sb 
    413     call mesh_init_from_file(gs_mesh, io_mesh) 
    414     call io_close(io_mesh)  
    415  
    416     io_wfns  = io_open(trim(dir)//'/wfns', action='read', status='old', die=.false., is_tmp=.true., grp=mpi_grp) 
    417     if(io_wfns.lt.0) then 
    418       ierr = -1 
    419     end if 
    420  
    421     io_occs = io_open(trim(dir)//'/occs', action='read', status='old', die=.false., is_tmp=.true., grp=mpi_grp) 
    422     if(io_occs.lt.0) then 
    423       if(io_wfns.gt.0) call io_close(io_wfns, grp=mpi_grp) 
    424       ierr = -1 
    425     end if 
    426  
    427     if(ierr .ne. 0) then 
    428       write(message(1),'(a)') 'Could not load ground-state interface wavefunctions.' 
    429       call write_info(1) 
    430       call messages_print_stress(stdout) 
    431       call pop_sub() 
    432       return 
    433     end if 
    434  
    435     ! Skip two lines. 
    436     call iopar_read(mpi_grp, io_wfns, line, err) 
    437     call iopar_read(mpi_grp, io_wfns, line, err) 
    438  
    439     call iopar_read(mpi_grp, io_occs, line, err) 
    440     call iopar_read(mpi_grp, io_occs, line, err) 
    441  
    442     ! FIXME: make the assertion more exact! 
    443 !    lead_np = gr%mesh%lead_unit_cell(LEFT)%np 
    444 !    np = gr%intf(LEFT)%np_intf 
    445     ASSERT(gr%mesh%np.le.gs_mesh%np) 
    446     SAFE_ALLOCATE(tmp(1:gs_mesh%np)) 
    447      
    448     do 
    449       call iopar_read(mpi_grp, io_wfns, line, int) 
    450       read(line, '(a)') char 
    451       if(int .ne. 0 .or. char .eq. '%') exit 
    452  
    453       call iopar_backspace(mpi_grp, io_wfns) 
    454  
    455       call iopar_read(mpi_grp, io_wfns, line, err) 
    456       read(line, *) ik, char, ist, char, idim, char, filename 
    457  
    458       call iopar_read(mpi_grp, io_occs, line, err) 
    459       read(line, *) st%occ(ist, ik), char, st%eigenval(ist, ik), char, flt, char, flt,& 
    460                     char, flt, char, st%d%kweights(ik) 
    461  
    462       if(ist .ge. st%st_start .and. ist .le. st%st_end .and. & 
    463          ik .ge. st%d%kpt%start .and. ik .le. st%d%kpt%end) then 
    464         ! Open boundaries imply complex wavefunctions. 
    465         call zrestart_read_function(dir, filename, gs_mesh, tmp, err) 
    466  
    467          
    468         if(err.le.0) then 
    469           ierr = ierr + 1 ! count the valid file readings 
    470           if(gr%mesh%np .eq. gs_mesh%np) then ! no extra unit cell present 
    471             do il = 1, NLEADS 
    472               forall(ip = 1:gr%intf(il)%np_uc) 
    473                 st%ob_lead(il)%intf_psi(ip, INNER, idim, ist, ik) = tmp(gr%intf(il)%index(ip)) 
    474               end forall 
    475               ! the outer part is zero (if the source term is still active) 
    476               st%ob_lead(il)%intf_psi(:, OUTER, idim, ist, ik) = M_ZERO 
    477             end do 
    478           else ! transport mode with extra unit cell 
    479             ! FIXME: to be generalized for more than 2 leads 
    480             lead_np = gr%mesh%lead_unit_cell(LEFT)%np 
    481             np = gr%intf(LEFT)%np_intf 
    482             np_uc = gr%intf(LEFT)%np_uc 
    483             ! Here we use the fact that transport is in x-direction (x is the index 
    484             ! running slowest). 
    485             ! Outer block. 
    486             tnp = gr%mesh%np + 2 * lead_np 
    487             ! FIXME: check for extent>der-order if this is still correct (left side) 
    488             st%ob_lead(LEFT)%intf_psi(1:np, OUTER, idim, ist, ik)  = tmp(lead_np - np + 1:lead_np) 
    489             st%ob_lead(RIGHT)%intf_psi(1:np, OUTER, idim, ist, ik) = tmp(tnp - lead_np + 1:tnp - lead_np + np) 
    490             ! Inner block. 
    491             st%ob_lead(LEFT)%intf_psi(1:np, INNER, idim, ist, ik)  = tmp(lead_np + 1:lead_np+np) 
    492             st%ob_lead(RIGHT)%intf_psi(1:np, INNER, idim, ist, ik) = tmp(tnp - lead_np - np + 1:tnp - lead_np) 
    493           end if 
    494         end if ! err 
    495       end if 
     386    do ik = st%d%kpt%start, st%d%kpt%end 
     387      do ist = st%st_start, st%st_end 
     388        do idim = 1, st%d%dim 
     389          do il = 1, NLEADS 
     390            forall(ip = 1:gr%intf(il)%np_uc) 
     391              st%ob_lead(il)%intf_psi(ip, idim, ist, ik) = st%zpsi(gr%intf(il)%index(ip), idim, ist, ik) 
     392            end forall 
     393          end do 
     394        end do 
     395      end do 
    496396    end do 
    497      
    498 #if defined(HAVE_MPI) 
    499     if(st%parallel_in_states) then 
    500       call MPI_Allreduce(ierr, err, 1, MPI_INTEGER, MPI_SUM, st%mpi_grp%comm, mpi_err) 
    501       ierr = err 
    502     end if 
    503     if(st%d%kpt%parallel) then 
    504       call MPI_Allreduce(ierr, err, 1, MPI_INTEGER, MPI_SUM, st%d%kpt%mpi_grp%comm, mpi_err) 
    505       ierr = err 
    506     end if 
    507 #endif 
    508  
    509     if(ierr.eq.0) then 
    510       ierr = -1 
    511       call messages_print_stress(stdout, 'Loading restart information') 
    512       message(1) = 'No interface wavefunctions could be read.' 
    513       call write_info(1) 
    514       call messages_print_stress(stdout) 
    515     else 
    516       if(ierr .eq. st%nst * st%d%nik * st%d%dim) then 
    517         ierr = 0 
    518       else 
    519         call messages_print_stress(stdout, 'Loading restart information') 
    520         write(message(1),'(a,i4,a,i4,a)') 'Only ', ierr,' interface wavefunctions out of ', & 
    521           st%nst * st%d%nik * st%d%dim, ' could be read.' 
    522         call write_info(1) 
    523         call messages_print_stress(stdout) 
    524       end if 
    525     end if 
    526  
    527     call io_close(io_wfns, mpi_grp) 
    528     call io_close(io_occs, mpi_grp) 
    529  
    530     SAFE_DEALLOCATE_A(tmp) 
    531397 
    532398    call pop_sub() 
    533   end subroutine restart_read_ob_intf 
    534  
    535  
    536   ! --------------------------------------------------------- 
    537   ! Reads the central regions of the ground-state wavefunctions of 
    538   ! an open-boundaries calculation. 
    539   ! Returns (in ierr) 
    540   ! <0 => Fatal error, 
    541   ! =0 => read all wavefunctions, 
    542   ! >0 => could only read x wavefunctions. 
    543   subroutine restart_read_ob_central(dir, st, gr, ierr) 
    544     character(len=*), intent(in)    :: dir 
    545     type(states_t),   intent(inout) :: st 
    546     type(grid_t),     intent(in)    :: gr 
    547     integer,          intent(out)   :: ierr 
    548  
    549     logical              :: psi_allocated 
    550     integer              :: io_wfns, io_occs, io_mesh, lead_np, int, err 
    551     integer              :: ik, ist, idim 
    552     character            :: char 
    553     character(len=256)   :: line, filename 
    554     CMPLX, allocatable   :: tmp(:) 
    555     type(mesh_t)         :: gs_mesh 
    556     type(mpi_grp_t)      :: mpi_grp 
    557     FLOAT                :: k_x, k_y, k_z 
    558  
    559     call push_sub('restart.restart_read_ob_central') 
    560  
    561     write(message(1), '(a,i5)') 'Info: Loading restart information' 
    562     call write_info(1) 
    563  
    564     mpi_grp = mpi_world 
    565  
    566     ! Sanity check. 
    567     psi_allocated = (associated(st%dpsi) .and. st%wfs_type.eq.M_REAL) .or. & 
    568       (associated(st%zpsi) .and. st%wfs_type.eq.M_CMPLX) 
    569     ASSERT(psi_allocated) 
    570  
    571     ierr = 0 
    572  
    573     ! Read the mesh of the ground state calculation. 
    574     io_mesh = io_open(trim(dir)//'/mesh', action='read', status='old', die=.false., is_tmp=.true.) 
    575     if(io_mesh.lt.0) then 
    576       ierr = -1 
    577       call io_close(io_mesh, grp=mpi_grp) 
    578       call pop_sub(); return 
    579     end if 
    580     gs_mesh%sb => gr%mesh%sb 
    581     call mesh_init_from_file(gs_mesh, io_mesh) 
    582     call io_close(io_mesh) 
    583  
    584     io_wfns  = io_open(trim(dir)//'/wfns', action='read', status='old', die=.false., is_tmp=.true., grp=mpi_grp) 
    585     if(io_wfns.lt.0) then 
    586       ierr = -1 
    587     end if 
    588  
    589     io_occs = io_open(trim(dir)//'/occs', action='read', status='old', die=.false., is_tmp = .true., grp = mpi_grp) 
    590     if(io_occs.lt.0) then 
    591       if(io_wfns.gt.0) call io_close(io_wfns, grp=mpi_grp) 
    592       ierr = -1 
    593     end if 
    594  
    595     if(ierr .ne. 0) then 
    596       write(message(1),'(a)') 'Could not load any previous restart information.' 
    597       call write_info(1) 
    598       call messages_print_stress(stdout) 
    599       call pop_sub() 
    600       return 
    601     end if 
    602  
    603     ! Skip two lines. 
    604     call iopar_read(mpi_grp, io_wfns, line, err) 
    605     call iopar_read(mpi_grp, io_wfns, line, err) 
    606  
    607     call iopar_read(mpi_grp, io_occs, line, err) 
    608     call iopar_read(mpi_grp, io_occs, line, err) 
    609  
    610     lead_np = gr%mesh%lead_unit_cell(LEFT)%np 
    611     SAFE_ALLOCATE(tmp(1:gr%mesh%np + 2 * lead_np)) 
    612      
    613     do 
    614       call iopar_read(mpi_grp, io_wfns, line, int) 
    615       if(int .ne. 0) exit 
    616       read(line, '(a)') char 
    617       if(char.eq.'%') exit 
    618  
    619       call iopar_backspace(mpi_grp, io_wfns) 
    620  
    621       call iopar_read(mpi_grp, io_wfns, line, err) 
    622       read(line, *) ik, char, ist, char, idim, char, filename 
    623  
    624       call iopar_read(mpi_grp, io_occs, line, err) 
    625       read(line, *) st%occ(ist, ik), char, st%eigenval(ist, ik), char, & 
    626                     k_x, char, k_y, char, k_z, char, st%d%kweights(ik) 
    627       st%d%kpoints(:, ik) = (/k_x, k_y, k_z/) 
    628  
    629       if(ist .ge. st%st_start .and. ist .le. st%st_end .and. & 
    630          ik .ge. st%d%kpt%start .and. ik .le. st%d%kpt%end) then 
    631         ! Open boundaries imply complex wavefunctions. 
    632         call zrestart_read_function(dir, filename, gs_mesh, tmp, err) 
    633         ! Here we use the fact that transport is in x-direction (x is the index 
    634         ! running slowest). 
    635         st%zpsi(1:gr%mesh%np, idim, ist, ik) = tmp(lead_np + 1:gr%mesh%np + lead_np) 
    636         if(err.le.0) then 
    637           ierr = ierr + 1 
    638         end if 
    639       end if 
    640     end do 
    641      
    642 #if defined(HAVE_MPI) 
    643     if(st%parallel_in_states) then 
    644       call MPI_Allreduce(ierr, err, 1, MPI_INTEGER, MPI_SUM, st%mpi_grp%comm, mpi_err) 
    645       ierr = err 
    646     end if 
    647     if(st%d%kpt%parallel) then 
    648       call MPI_Allreduce(ierr, err, 1, MPI_INTEGER, MPI_SUM, st%d%kpt%mpi_grp%comm, mpi_err) 
    649       ierr = err 
    650     end if 
    651 #endif 
    652     if(ierr.eq.0) then 
    653       ierr = -1 
    654       call messages_print_stress(stdout, 'Loading restart information') 
    655       message(1) = 'No files could be read. No restart information can be used.' 
    656       call write_info(1) 
    657       call messages_print_stress(stdout) 
    658     else 
    659       if(ierr.eq.st%nst * st%d%nik * st%d%dim) then 
    660         ierr = 0 
    661       else 
    662         call messages_print_stress(stdout, 'Loading restart information') 
    663         write(message(1),'(a,i4,a,i4,a)') 'Only ', ierr,' files out of ', & 
    664           st%nst * st%d%nik * st%d%dim, ' could be read.' 
    665         call write_info(1) 
    666         call messages_print_stress(stdout) 
    667       end if 
    668     end if 
    669  
    670     call io_close(io_wfns, mpi_grp) 
    671     call io_close(io_occs, mpi_grp) 
    672  
    673     SAFE_DEALLOCATE_A(tmp) 
    674  
    675     call pop_sub() 
    676   end subroutine restart_read_ob_central 
     399  end subroutine restart_get_ob_intf 
    677400 
    678401 
     
    700423    character(len=50)    :: str 
    701424 
    702     FLOAT                :: my_occ 
     425    FLOAT                :: my_occ, flt 
    703426    logical              :: read_occ_, gs_allocated, lr_allocated 
    704427 
     
    719442    read_occ_ = .true. 
    720443    if(present(read_occ)) read_occ_ = .false. 
    721  
     444     
    722445    ! sanity check 
    723446    gs_allocated = (associated(st%dpsi) .and. st%wfs_type == M_REAL) .or. & 
     
    780503 
    781504      call iopar_read(gr%mesh%mpi_grp, iunit2, line, err) 
    782       read(line, *) my_occ, char, st%eigenval(ist, ik) 
     505      read(line, *) my_occ, char, st%eigenval(ist, ik), char, flt, char, flt,& 
     506                    char, flt, char, st%d%kweights(ik) 
    783507      if(read_occ_) st%occ(ist, ik) = my_occ 
    784508 
  • trunk/src/states/states.F90

    r6330 r6353  
    9595    states_freeze_orbitals,           & 
    9696    states_total_density,             & 
    97     states_init_green 
     97    states_init_self_energy,          & 
     98    states_write_proj_lead_wf,        & 
     99    states_read_proj_lead_wf 
    98100 
    99101  public ::                           & 
     
    102104 
    103105  type states_lead_t 
    104     CMPLX, pointer     :: intf_psi(:, :, :, :, :) !< (np, 2, st%d%dim, st%nst, st%d%nik) 
     106    CMPLX, pointer     :: intf_psi(:, :, :, :) !< (np, st%d%dim, st%nst, st%d%nik) 
    105107    FLOAT, pointer     :: rho(:, :)   !< Density of the lead unit cells. 
    106     CMPLX, pointer     :: green(:, :, :, :, :) !< (np, np, nspin, ncs, nik) Green`s function of the leads. 
     108    CMPLX, pointer     :: self_energy(:, :, :, :, :) !< (np, np, nspin, ncs, nik) self energy of the leads. 
    107109  end type states_lead_t 
    108110 
     
    186188    nullify(st%dpsi, st%zpsi, st%zphi, st%rho, st%current, st%rho_core, st%frozen_rho, st%eigenval) 
    187189    do il=1, NLEADS 
    188       nullify(st%ob_lead(il)%intf_psi, st%ob_lead(il)%rho, st%ob_lead(il)%green) 
     190      nullify(st%ob_lead(il)%intf_psi, st%ob_lead(il)%rho, st%ob_lead(il)%self_energy) 
    189191    end do 
    190192    nullify(st%ob_eigenval, st%ob_occ) 
     
    917919      do il = 1, NLEADS 
    918920        np = mesh%lead_unit_cell(il)%np 
    919         SAFE_ALLOCATE(st%ob_lead(il)%intf_psi(1:np, 1:2, 1:st%d%dim, st1:st2, k1:k2)) 
     921        SAFE_ALLOCATE(st%ob_lead(il)%intf_psi(1:np, 1:st%d%dim, st1:st2, k1:k2)) 
    920922        st%ob_lead(il)%intf_psi = M_z0 
    921923      end do 
     
    11071109      SAFE_DEALLOCATE_P(st%ob_occ) 
    11081110      do il = 1, NLEADS 
    1109         SAFE_DEALLOCATE_P(st%ob_lead(il)%green) 
     1111        SAFE_DEALLOCATE_P(st%ob_lead(il)%self_energy) 
    11101112      end do 
    11111113    end if 
     
    27622764 
    27632765  ! --------------------------------------------------------- 
    2764   !> initialize the surface Green`s functions of the leads 
    2765   subroutine states_init_green(st, gr, nspin, d_ispin, lead) 
     2766  !> initialize the self energy of the leads 
     2767  subroutine states_init_self_energy(st, gr, nspin, d_ispin, lead) 
    27662768    type(states_t),      intent(inout) :: st 
    27672769    type(grid_t),        intent(in)    :: gr 
     
    27712773 
    27722774    character(len=2)      :: spin 
    2773     character(len=256)    :: fmt, fname_real, fname_imag 
     2775    character(len=256)    :: fmt, fname, fname_real, fname_imag 
    27742776    FLOAT                 :: energy 
    27752777    integer  :: np, ik, ist, il, ispin, s1, s2, k1, k2 
    27762778    integer  :: green_real, green_imag, irow 
    27772779 
    2778     call push_sub('states.states_init_green') 
    2779  
    2780     ! Calculate Green`s function of the leads. 
     2780    call push_sub('states.states_init_self_energy') 
     2781 
     2782    ! Calculate self energy of the leads. 
    27812783    ! FIXME: For spinors, this calculation is almost certainly wrong. 
    27822784    ASSERT(st%ob_nst == st%nst) 
     
    27862788    do il = 1, NLEADS 
    27872789      np = gr%intf(il)%np_intf 
    2788       SAFE_ALLOCATE(st%ob_lead(il)%green(1:np, 1:np, 1:nspin, s1:s2, k1:k2)) 
     2790      SAFE_ALLOCATE(st%ob_lead(il)%self_energy(1:np, 1:np, 1:nspin, s1:s2, k1:k2)) 
    27892791    end do 
    2790     call messages_print_stress(stdout, "Lead Green's functions") 
     2792    call messages_print_stress(stdout, "Lead self energy") 
    27912793    message(1) = ' st#     k#  Spin      Lead     Energy' 
    27922794    call write_info(1) 
     
    28232825              trim(spin), trim(LEAD_NAME(il)), energy 
    28242826            call write_info(1) 
    2825             ! \todo magnetic gs 
    2826             call lead_green(energy, lead(il)%h_diag(:, :, ispin), lead(il)%h_offdiag(:, :), & 
    2827               gr%intf(il), st%ob_lead(il)%green(:, :, ispin, ist, ik), .true.) 
    2828  
    2829             ! Write the entire Green`s function to a file. 
     2827 
     2828            call lead_self_energy(energy, lead(il)%h_diag(:, :, ispin), lead(il)%h_offdiag(:, :), & 
     2829              gr%intf(il), st%ob_lead(il)%self_energy(:, :, ispin, ist, ik), .true.) 
     2830 
     2831            ! Write the entire self energy to a file. 
    28302832            if(in_debug_mode) then 
    28312833              call io_mkdir('debug/open_boundaries') 
    2832               write(fname_real, '(3a,i4.4,a,i3.3,a,i1.1,a)') 'debug/open_boundaries/green-', & 
     2834              write(fname_real, '(3a,i4.4,a,i3.3,a,i1.1,a)') 'debug/open_boundaries/self-energy-', & 
    28332835                trim(LEAD_NAME(il)), '-', ist, '-', ik, '-', ispin, '.real' 
    2834               write(fname_imag, '(3a,i4.4,a,i3.3,a,i1.1,a)') 'debug/open_boundaries/green-', & 
     2836              write(fname_imag, '(3a,i4.4,a,i3.3,a,i1.1,a)') 'debug/open_boundaries/self-energy-', & 
    28352837                trim(LEAD_NAME(il)), '-', ist, '-', ik, '-', ispin, '.imag' 
    28362838              green_real = io_open(fname_real, action='write', grp=st%d%kpt%mpi_grp, is_tmp=.false.) 
     
    28392841              write(fmt, '(a,i6,a)') '(', np, 'e24.16)' 
    28402842              do irow = 1, np 
    2841                 write(green_real, fmt) real(st%ob_lead(il)%green(irow, :, ispin, ist, ik)) 
    2842                 write(green_imag, fmt) aimag(st%ob_lead(il)%green(irow, :, ispin, ist, ik)) 
     2843                write(green_real, fmt) real(st%ob_lead(il)%self_energy(irow, :, ispin, ist, ik)) 
     2844                write(green_imag, fmt) aimag(st%ob_lead(il)%self_energy(irow, :, ispin, ist, ik)) 
    28432845              end do 
    28442846              call io_close(green_real); call io_close(green_imag) 
     
    28512853 
    28522854    call pop_sub() 
    2853   end subroutine states_init_green 
     2855  end subroutine states_init_self_energy 
     2856 
     2857 
     2858  ! --------------------------------------------------------- 
     2859  ! write H_(C,apha)*Psi_(alpha) without using Psi_(alpha) 
     2860  subroutine states_write_proj_lead_wf(dir, intf, st) 
     2861    character(len=*),  intent(in) :: dir   ! directory 
     2862    type(interface_t), intent(in) :: intf(:) 
     2863    type(states_t),    intent(in) :: st 
     2864 
     2865    integer :: ik, ist, idim, il, np, ip, iunit 
     2866    CMPLX, allocatable :: psi(:, :), phi(:, :), hpsi(:, :), self_energy(:, :) 
     2867    character(len=256) :: fname 
     2868 
     2869    call push_sub('states.write_proj_lead_wf') 
     2870 
     2871    np = maxval(intf(1:NLEADS)%np_intf) 
     2872 
     2873    SAFE_ALLOCATE(psi(1:np, 1:st%d%dim)) 
     2874    SAFE_ALLOCATE(phi(1:np, 1:st%d%dim)) 
     2875    SAFE_ALLOCATE(hpsi(1:np, 1:st%d%dim)) 
     2876    SAFE_ALLOCATE(self_energy(1:np, 1:np)) 
     2877 
     2878    hpsi(:, :) = M_z0 
     2879 
     2880    call io_mkdir(dir, is_tmp=.true.) 
     2881 
     2882    do ik = st%d%kpt%start, st%d%kpt%end 
     2883      do ist = st%st_start, st%st_end 
     2884        do il = 1, NLEADS 
     2885          np = intf(il)%np_intf 
     2886          forall(ip = 1:np) 
     2887            psi(ip, :) = st%zpsi(intf(il)%index(ip), :, ist, ik) 
     2888            phi(ip, :) = st%zphi(intf(il)%index(ip), :, ist, ik) 
     2889          end forall 
     2890          do idim = 1, st%d%dim 
     2891            self_energy(1:np, 1:np) = st%ob_lead(il)%self_energy(1:np, 1:np, idim, ist, ik) 
     2892            call lalg_gemv(np, np, M_z1, self_energy(1:np, 1:np), psi(1:np, idim), M_z0, hpsi(1:np, idim)) 
     2893            if((il.eq.LEFT).and.(-st%d%kpoints(1, ik).gt.M_ZERO) .or. (il.eq.RIGHT).and.(-st%d%kpoints(1, ik).lt.M_ZERO)) then 
     2894              ! add the reflecting part 
     2895              self_energy(1:np, 1:np) = transpose(conjg(self_energy(1:np, 1:np))) - self_energy(1:np, 1:np) 
     2896              call lalg_gemv(np, np, M_z1, self_energy(1:np, 1:np), phi(1:np, idim), M_z1, hpsi(1:np, idim)) 
     2897            end if 
     2898            write(fname, '(3a,i4.4,a,i3.3,a,i1.1)') 'src0-', trim(LEAD_NAME(il)), '-', ist, '-', ik, '-', idim 
     2899            iunit = io_open(trim(dir)//trim(fname), action='write', form='unformatted', is_tmp=.true.) 
     2900            if(iunit.lt.0) then 
     2901              message(1) = 'Cannot write term for source term to file.' 
     2902              call write_warning(1) 
     2903              call io_close(iunit) 
     2904              call pop_sub(); return 
     2905            end if 
     2906            ! Write parameters. 
     2907            write(iunit) np 
     2908            ! Write matrix. 
     2909            write(iunit) hpsi(1:np, idim) 
     2910            call io_close(iunit) 
     2911          end do 
     2912        end do 
     2913      end do 
     2914    end do 
     2915 
     2916    SAFE_DEALLOCATE_A(psi) 
     2917    SAFE_DEALLOCATE_A(phi) 
     2918    SAFE_DEALLOCATE_A(hpsi) 
     2919    SAFE_DEALLOCATE_A(self_energy) 
     2920 
     2921    call pop_sub() 
     2922  end subroutine states_write_proj_lead_wf 
     2923 
     2924  ! --------------------------------------------------------- 
     2925  subroutine states_read_proj_lead_wf(dir, intf, st, src0) 
     2926    character(len=*),  intent(in)    :: dir   ! directory 
     2927    type(interface_t), intent(in)    :: intf 
     2928    type(states_t),    intent(in)    :: st 
     2929    CMPLX,             intent(inout) :: src0(:, : ,:, :) 
     2930 
     2931    integer :: ik, ist, idim, np, ip, iunit 
     2932    character(len=256) :: fname 
     2933 
     2934    call push_sub('states.states_read_proj_lead_wf') 
     2935 
     2936    do ik = st%d%kpt%start, st%d%kpt%end 
     2937      do ist = st%st_start, st%st_end 
     2938        do idim = 1, st%d%dim 
     2939          ! Try to open file. 
     2940          write(fname, '(3a,i4.4,a,i3.3,a,i1.1)') 'src0-', trim(LEAD_NAME(intf%il)), '-', ist, '-', ik, '-', idim 
     2941          iunit = io_open(trim(dir)//trim(fname), action='read', status='old', die=.false., is_tmp=.true., form='unformatted') 
     2942          if(iunit.lt.0) then ! no file found 
     2943            message(1) = 'Cannot read src(0) from file.' 
     2944            call write_fatal(1) 
     2945          end if 
     2946 
     2947          ! Now read the data. 
     2948          read(iunit) np 
     2949 
     2950          if(np.ne.size(src0, 1)) then 
     2951            message(1) = 'Size mismatch! Cannot read src(0) from file.' 
     2952            call write_fatal(1) 
     2953          end if 
     2954 
     2955          read(iunit) src0(1:np, idim, ist, ik) 
     2956 
     2957          call io_close(iunit) 
     2958        end do 
     2959      end do 
     2960    end do 
     2961 
     2962    call pop_sub() 
     2963  end subroutine states_read_proj_lead_wf 
     2964 
    28542965 
    28552966end module states_m 
  • trunk/src/td/ob_rti.F90

    r6270 r6353  
    220220      SAFE_ALLOCATE(ob%lead(il)%st_intface(1:np, s1:s2, k1:k2, 0:ob%max_mem_coeffs)) 
    221221      ob%lead(il)%st_intface = M_z0 
     222      call states_read_proj_lead_wf('open_boundaries/', gr%intf(il), st, ob%lead(il)%src_prev) 
    222223    end do 
    223224 
     
    324325            end if 
    325326            call calc_source_wf(ob%max_mem_coeffs, m, np, il, hm%lead(il)%h_offdiag, tmp_mem(1:np, 1:np), dt, & 
    326               st%ob_lead(il)%intf_psi(:, :, 1, ist, ik), ob%src_mem_u(:, il), f0, fac,              & 
     327              st%ob_lead(il)%intf_psi(:, 1, ist, ik), ob%src_mem_u(:, il), f0, fac,              & 
    327328              lambda(m, 0, max_iter, ob%src_mem_u(:, il)), ob%lead(il)%src_prev(:, 1, ist, ik)) 
    328329            call apply_src(gr%intf(il), ob%lead(il)%src_prev(1:np, 1, ist, ik), st%zpsi(:, :, ist, ik)) 
     
    355356        ! h_eff_backward must be a complex symmetric operator ! 
    356357        call zqmr_sym(gr%mesh%np, st%zpsi(:, 1, ist, ik), tmp(:, 1), h_eff_backward, precond_prop, & 
    357           qmr_iter, residue=dres, threshold=qmr_tol, showprogress=.false., converged=conv) 
     358          qmr_iter, residue=dres, threshold=qmr_tol, showprogress=in_debug_mode, converged=conv) 
    358359      end do 
    359360      if(in_debug_mode) then ! write info 
     
    447448            if(m.gt.0) tmp_mem(1:npo) = tmp_mem(1:npo) + ob%lead(il)%q_sp(1:npo, m-1) 
    448449            call calc_source_wf_sp(max_iter, m, np, il, hm%lead(il)%h_offdiag(:, :),     & 
    449               tmp_mem(1:npo), dt, order, gr%sb%dim, st%ob_lead(il)%intf_psi(:, :, 1, ist, ik), & 
     450              tmp_mem(1:npo), dt, order, gr%sb%dim, st%ob_lead(il)%intf_psi(:, 1, ist, ik), & 
    450451              ob%lead(il)%q_s(:, :, :), ob%lead(il)%sp2full_map, ob%src_mem_u(:, il), f0, fac,   & 
    451452              lambda(m, 0, max_iter, ob%src_mem_u(:, il)), ob%lead(il)%src_prev(:, 1, ist, ik)) 
  • trunk/src/td/ob_src.F90

    r6072 r6353  
    8888    CMPLX,   intent(in)    :: mem(np, np)   ! the effective memory coefficient 
    8989    FLOAT,   intent(in)    :: dt            ! Timestep. 
    90     CMPLX,   intent(in)    :: psi0(:, :)    ! (np, INNER/OUTER). 
     90    CMPLX,   intent(in)    :: psi0(:)       ! (np). 
    9191    CMPLX,   intent(in)    :: u(0:) 
    9292    CMPLX,   intent(in)    :: f0 
     
    9898 
    9999    call push_sub('ob_src.calc_source_wf') 
    100  
    101100    if(m.eq.0) then 
    102       src(1:np) = psi0(1:np, OUTER) 
    103       if (il.eq.LEFT) then 
    104         call ztrmv('U', 'N', 'N', np, offdiag, np, src, 1) 
    105       else 
    106         call ztrmv('L', 'N', 'N', np, offdiag, np, src, 1) 
    107       end if 
    108       tmp = -M_zI*dt*u(0)*f0 
    109 !      call lalg_gemv(np, np, tmp*M_zI*M_HALF*dt, mem, psi0(1:np, INNER), tmp, src) 
    110       call zsymv('U', np, tmp*M_zI*M_HALF*dt, mem, np, psi0(1:np, INNER), 1, tmp,  src, 1) 
     101      ! initial src is V*psi0(outer) (precalculated in gs mode) 
     102      tmp = -M_zI*dt*f0*u(0) 
     103      !call lalg_gemv(np, np, tmp*M_zI*M_HALF*dt, mem, psi0, tmp, src) 
     104      call zsymv('U', np, tmp*M_zI*M_HALF*dt, mem, np, psi0, 1, tmp, src, 1) 
    111105    else 
    112106      tmp   = factor*u(m)*u(m-1) 
     
    115109      else 
    116110        alpha = M_HALF*dt**2*f0*lambda/u(m) 
    117 !        call lalg_gemv(np, np, alpha, mem, psi0(1:np, INNER), tmp, src) 
    118         call zsymv('U', np, alpha, mem, np, psi0(1:np, INNER), 1, tmp, src, 1) 
     111!        call lalg_gemv(np, np, alpha, mem, psi0, tmp, src) 
     112        call zsymv('U', np, alpha, mem, np, psi0, 1, tmp, src, 1) 
    119113      end if 
    120114    end if 
     
    138132    CMPLX,   intent(in)    :: sp_mem(:) 
    139133    FLOAT,   intent(in)    :: dt             ! Timestep. 
    140     CMPLX,   intent(in)    :: psi0(:, :)     ! (np, INNER/OUTER) 
     134    CMPLX,   intent(in)    :: psi0(:)        ! (np) 
    141135    CMPLX,   intent(in)    :: mem_s(:, :, :) 
    142136    integer, intent(in)    :: mapping(:) 
  • trunk/src/td/pes_rc_inc.F90

    r6286 r6353  
    3838  !%Section Time-Dependent::PES 
    3939  !%Description 
    40   !% List of points where to calculate the photoelectron spectrum by Suraud's method. 
     40  !% List of points where to calculate the photoelectron spectrum by Suraud`s method. 
    4141  !% The exact syntax is: 
    4242  !% 
  • trunk/src/td/td.F90

    r6290 r6353  
    394394          fromScratch = .true. 
    395395        end if 
    396       end if 
    397  
    398       if(.not.fromscratch .and. st%open_boundaries) then 
    399         call restart_read_ob_intf(trim(restart_dir)//GS_DIR, st, gr, ierr) 
     396        ! extract the interface wave function 
     397        if(st%open_boundaries) call restart_get_ob_intf(st, gr) 
    400398      end if 
    401399 
     
    432430 
    433431        if(.not. st%only_userdef_istates) then 
    434           ! In the open-boundary case the ground-state wavefunctions are bit too "wide". 
    435           ! Therefore, we need a special routine to extract the middle. 
    436           if(gr%sb%open_boundaries) then 
    437             call restart_read_ob_intf(trim(restart_dir)//GS_DIR, st, gr, ierr) 
    438             if(ierr.ne.0) then 
    439               message(1) = "Could not read interface wavefunctions from '"//trim(restart_dir)//GS_DIR//"'" 
    440               message(2) = "Please run an open-boundaries ground-state calculation first!" 
    441               call write_fatal(2) 
    442             end if 
    443             call restart_read_ob_central(trim(restart_dir)//GS_DIR, st, gr, ierr) 
    444           else 
    445             call restart_read(trim(restart_dir)//GS_DIR, st, gr, geo, ierr) 
    446           end if 
     432          call restart_read(trim(restart_dir)//GS_DIR, st, gr, geo, ierr) 
    447433          if(ierr.ne.0) then 
    448434            message(1) = "Could not read KS orbitals from '"//trim(restart_dir)//GS_DIR//"'" 
    449435            message(2) = "Please run a ground-state calculation first!" 
    450436            call write_fatal(2) 
     437          end if 
     438           
     439          if(gr%sb%open_boundaries) then 
     440            ! extract the interface wave function 
     441            call restart_get_ob_intf(st, gr) 
    451442          end if 
    452443        end if 
  • trunk/testsuite/open_systems/01-wavepacket.test

    r6188 r6353  
    2020match ; Density [step   0] ; LINE(flat_td.general/multipoles,  16, 30) ; 3.981621426799e+00 
    2121match ; Density [step 100] ; LINE(flat_td.general/multipoles, 116, 30) ; 3.954076302565e+00 
    22 match ; Density [step 200] ; LINE(flat_td.general/multipoles, 216, 30) ; 2.434921125600e+00 
    23 match ; Density [step 300] ; LINE(flat_td.general/multipoles, 316, 30) ; 9.635221759786e-01 
     22match ; Density [step 200] ; LINE(flat_td.general/multipoles, 216, 30) ; 2.434921125591e+00 
     23match ; Density [step 300] ; LINE(flat_td.general/multipoles, 316, 30) ; 9.635221759715e-01 
  • trunk/testsuite/open_systems/03-extended_eigenstate.test

    r6028 r6353  
    99# Calculate eigenstate of 1d attractive square potential barrier. 
    1010Input: 03-extended_eigenstate.01-square_well_1d.inp 
    11 match ; Total energy ; GREP(well_static/info, 'Total       =', 20) ; 5.7224 
     11match ; Total energy ; GREP(well_static/info, 'Total       =', 20) ; 5.0117 
    1212 
    1313# Calculate eigenstates of 2D ring potential attached to upside-down Gaussian 
    1414# shaped lead channels. 
    1515Input: 03-extended_eigenstate.02-ring_leads_2d.inp 
    16 match ; Total energy ; GREP(ring_lead_static/info, 'Total       =', 20) ; 81.6571 
     16match ; Total energy ; GREP(ring_lead_static/info, 'Total       =', 20) ; 58.9977 
  • trunk/testsuite/open_systems/04-propagate_eigenstate.test

    r6086 r6353  
    99# Calculate eigenstate of 1d attractive square-potential barrier. 
    1010Input: 04-propagate_eigenstate.01-square_well_1d.inp 
    11 match ; Total energy [step   0]; LINE(well_td.general/energy,   6, 30) ; 2.049018304223e+00 
    12 match ; Total energy [step 100]; LINE(well_td.general/energy, 106, 30) ; 2.049017944732e+00 
    13 match ; Total energy [step 200]; LINE(well_td.general/energy, 206, 30) ; 2.049017813254e+00 
    14 match ; Total energy [step 300]; LINE(well_td.general/energy, 306, 30) ; 2.049017923834e+00 
     11match ; Total energy [step   0]; LINE(well_td.general/energy,   6, 30) ; 2.064297127468e+00 
     12match ; Total energy [step 100]; LINE(well_td.general/energy, 106, 30) ; 2.064289561608e+00 
     13match ; Total energy [step 200]; LINE(well_td.general/energy, 206, 30) ; 2.064286304422e+00 
     14match ; Total energy [step 300]; LINE(well_td.general/energy, 306, 30) ; 2.064284239477e+00 
    1515 
    1616# Calculate eigenstates of 2D ring potential attached to upside-down Gaussian-shaped 
    1717# lead channels and propagate with a bias switched on. 
    1818Input: 04-propagate_eigenstate.02-ring_leads_2d.inp 
    19 match ; Total energy [step   0]; LINE(ring_lead_td.general/energy,   6, 30) ; 4.626426074917e+02 
    20 match ; Total energy [step  25]; LINE(ring_lead_td.general/energy,  31, 30) ; 4.635193147887e+02 
    21 match ; Total energy [step  50]; LINE(ring_lead_td.general/energy,  56, 30) ; 4.648048709782e+02 
    22 match ; Total energy [step  75]; LINE(ring_lead_td.general/energy,  81, 30) ; 4.676178752149e+02 
    23 match ; Total energy [step 100]; LINE(ring_lead_td.general/energy, 106, 30) ; 4.714202246759e+02 
     19match ; Total energy [step   0]; LINE(ring_lead_td.general/energy,   6, 30) ; 4.626426040993e+02 
     20match ; Total energy [step  25]; LINE(ring_lead_td.general/energy,  31, 30) ; 4.635193115106e+02 
     21match ; Total energy [step  50]; LINE(ring_lead_td.general/energy,  56, 30) ; 4.648048674987e+02 
     22match ; Total energy [step  75]; LINE(ring_lead_td.general/energy,  81, 30) ; 4.676178717766e+02 
     23match ; Total energy [step 100]; LINE(ring_lead_td.general/energy, 106, 30) ; 4.714202213930e+02