2
! Copyright (C) 1996-2016 The SIESTA group
3
! This file is distributed under the terms of the
4
! GNU General Public License: see COPYING in the top directory
5
! or http://www.gnu.org/copyleft/gpl.txt.
6
! See Docs/Contributors.txt for a list of contributors.
8
! This code segment has been fully created by:
9
! Nick Papior Andersen, 2019, nickpapior@gmail.com
10
! Please conctact the author, prior to re-using this code.
12
! Module for calculating energy contributions for the transiesta
14
! Effectively many of the energy contributions stem from Hamiltonian
16
! However, in TranSiesta we only update/use a subset of the full
17
! matrices. As such the energies should only be calculated
18
! on the used elements rather than the full.
20
! There are many more elements that need to be split, while currently
21
! we only calculate a subset of what is actually needed.
22
! The main problem in calculating NEGF energies is:
23
! 1. the open-boundary problem, and
24
! 2. how to handle real-space energies such as Exc from dhscf.
31
subroutine ts_compute_energies()
33
use precision, only: dp
34
use m_ts_options, only: N_Elec, Elecs
35
use m_spin, only: spin
37
use sparse_matrices, only: dit => block_dist
38
use sparse_matrices, only: n_nzs => maxnh
39
use sparse_matrices, only: Dold, Dscf, H
40
use sparse_matrices, only: H_kin_1D, H_vkb_1D
41
use sparse_matrices, only: sp => sparse_pattern
44
use parallel, only : Node
48
use class_OrbitalDistribution
53
use geom_helper, only : UCORB
54
use m_ts_electype, only: Elec
55
use m_energies, only: NEGF_Ebs, NEGF_Ekin, NEGF_Etot, NEGF_Enl
56
use m_energies, only: NEGF_DEharr
58
! **********************
60
! **********************
61
integer, pointer :: l_ncol(:), l_ptr(:), l_col(:)
62
integer :: no_lo, no_u, lio, io, ind, jo, ir, jr, r, ispin
63
real(dp), pointer :: H_vkb(:), H_kin(:)
64
real(dp) :: Etmp(4,0:1+1+N_Elec*2)
66
real(dp) :: tmp(4,0:1+1+N_Elec*2)
70
if ( spin%NCol .or. spin%SO ) then
71
call die('ts_energies: Not implemented for non-colinear or spin-orbit')
74
H_vkb => val(H_vkb_1D)
75
H_kin => val(H_kin_1D)
77
! Retrieve information about the sparsity pattern
79
n_col=l_ncol,list_ptr=l_ptr,list_col=l_col, &
80
nrows=no_lo,nrows_g=no_u)
85
!$OMP parallel do default(shared), &
86
!$OMP&private(lio,io,ir,ind,jo,jr,r,ispin), &
87
!$OMP&reduction(+:Etmp)
90
! obtain the global index of the orbital.
91
io = index_local_to_global(dit,lio,Node)
94
! Loop number of entries in the row... (index frame)
95
do ind = l_ptr(lio) + 1 , l_ptr(lio) + l_ncol(lio)
97
! as the local sparsity pattern is a super-cell pattern,
98
! we need to check the unit-cell orbital
99
! The unit-cell column index
100
jo = UCORB(l_col(ind),no_u)
103
if ( all((/ir,jr/) == TYP_BUFFER) ) then
105
else if ( any((/ir,jr/) == TYP_BUFFER) ) then
107
else if ( all((/ir,jr/) == TYP_DEVICE) ) then
109
else if ( any((/ir,jr/) == TYP_DEVICE) ) then
110
r = 4+(ir+jr-1)*2 ! device/electrode
111
else if ( ir == jr ) then
112
r = 3+(ir-1)*2 ! electrode/electrode
118
Etmp(1,r) = Etmp(1,r) + sum(H(ind,:) * Dscf(ind,:) )
120
do ispin = 1, spin%spinor
122
Etmp(2,r) = Etmp(2,r) + H_kin(ind) * Dscf(ind,ispin)
124
Etmp(3,r) = Etmp(3,r) + H_vkb(ind) * Dscf(ind,ispin)
128
do ispin = 1, spin%spinor
129
Etmp(4,r) = Etmp(4,r) + H(ind,ispin) * (Dscf(ind,ispin) - Dold(ind,ispin))
134
!$OMP end parallel do
136
! Now add the *other* contributions
138
if ( Elecs(ir)%DM_update >= 1 ) then
140
r = 4 + (TYP_DEVICE+ir - 1) * 2
141
Etmp(:,2) = Etmp(:,2) + Etmp(:,r)
143
if ( Elecs(ir)%DM_update == 2 ) then
145
! add diagonal electrode terms
146
Etmp(:,2) = Etmp(:,2) + Etmp(:,r)
151
call MPI_AllReduce(Etmp(1,2),tmp(1,2),size(Etmp, 1), &
152
MPI_Double_Precision,MPI_SUM, MPI_Comm_World,MPIerror)
158
NEGF_Ekin = Etmp(2,2)
160
NEGF_DEharr = Etmp(4,2)
162
end subroutine ts_compute_energies
164
end module ts_energies_m