quantum-espresso/Modules/sic.f90

139 lines
5.3 KiB
Fortran

!
! Copyright (C) 2002 FPMD group
! This file is distributed under the terms of the
! GNU General Public License. See the file `License'
! in the root directory of the present distribution,
! or http://www.gnu.org/copyleft/gpl.txt .
!
!------------------------------------------------------------------------------!
MODULE sic_module
!------------------------------------------------------------------------------!
!
! The versions after 3.0 contain also the self-interaction-correction method
! has proposed by Mauri et al. (PRB 2005), taking also into account the 'comment'
! proposed by Sprik et al. (ICR 2005).
! Thus, we introduce the parameters sic_alpha and sic_epsilon to correct the
! exchange-correlation and the electronic hartree potentials, respectively.
! They are two empirical parameters, thus to remain in a ab-initio
! set them equal to 1.0d0.
! Sprik et al. showed that, in same cases, i.e. OH radical, it should be better
! to under estimate the correction to ex-ch, since in same way the exch already
! corrects the electronic hartree part.
! HOW AND WHEN USE THE SIC::
! Fran's personal considerations:
! the SIC is a way to correct the self-interaction WHEN
! ONE and only ONE e- lives in an unpaired electronic level
! we have choosen for it the spin up
! Remember to select nspin == 2 and nelup = neldw + 1
! the other e- are fictitious calculate in a LSD approach:
! infact, even if the paired e- feel a different potential (for spin up and spin dw)
! we constrain them to have the same force, and the same eigenvalues, the same eigenstates
! When you applied this SIC scheme to a molecule or to an atom, which are neutral,
! remember that you have to consider another correction to the energy level as proposed
! by Landau: infact if you start from a neutral system and subtract the self-intereaction
! the unpaired e- feels a charge system. Thus remeber a correction term ~2.317(Madelung)/2L_box
USE kinds, ONLY: DP
!
IMPLICIT NONE
SAVE
INTEGER, ALLOCATABLE :: ind_localisation(:)
INTEGER :: nat_localisation = 0
LOGICAL :: print_localisation = .FALSE. ! Calculates hartree energy around specified atoms
INTEGER :: self_interaction = 0
REAL(DP) :: sic_epsilon = 0.0d0
REAL(DP) :: sic_alpha = 0.0d0
REAL(DP) :: sic_rloc = 0.0d0
REAL(DP), ALLOCATABLE :: pos_localisation(:,:)
!------------------------------------------------------------------------------!
CONTAINS
!------------------------------------------------------------------------------!
SUBROUTINE sic_initval( nat_ , id_loc_ , sic_ , sic_epsilon_ , sic_alpha_, sic_rloc_ )
IMPLICIT NONE
INTEGER, INTENT(IN) :: nat_
INTEGER, INTENT(IN) :: id_loc_ (:)
CHARACTER(LEN=*), INTENT(IN) :: sic_
REAL(DP), INTENT(IN) :: sic_epsilon_
REAL(DP), INTENT(IN) :: sic_alpha_
REAL(DP), INTENT(IN) :: sic_rloc_
select case ( TRIM( sic_ ) )
case ( 'sic_mac' )
self_interaction = 2
case default
self_interaction = 0
end select
sic_epsilon = sic_epsilon_
sic_alpha = sic_alpha_
sic_rloc = sic_rloc_
! counting the atoms around which i want to calculate the charge localization
IF( ALLOCATED( ind_localisation ) ) DEALLOCATE( ind_localisation )
ALLOCATE( ind_localisation( nat_ ) )
ind_localisation( 1 : nat_ ) = id_loc_ ( 1 : nat_ )
nat_localisation = COUNT( ind_localisation > 0 )
IF( ALLOCATED( pos_localisation ) ) DEALLOCATE( pos_localisation )
ALLOCATE( pos_localisation( 4, MAX( nat_localisation, 1 ) ) )
!
IF( nat_localisation > 0 ) print_localisation = .TRUE.
!
RETURN
END SUBROUTINE sic_initval
!------------------------------------------------------------------------------!
SUBROUTINE deallocate_sic()
IMPLICIT NONE
IF( ALLOCATED( pos_localisation ) ) DEALLOCATE( pos_localisation )
IF( ALLOCATED( ind_localisation ) ) DEALLOCATE( ind_localisation )
RETURN
END SUBROUTINE deallocate_sic
!------------------------------------------------------------------------------!
SUBROUTINE sic_info( )
USE io_global, ONLY: stdout
IMPLICIT NONE
!
! prints the type of USIC we will do :
!
IF( self_interaction == 0 ) THEN
RETURN
END IF
WRITE(stdout, 591)
WRITE(stdout, 592) self_interaction
WRITE(stdout, 593)
!!select case (self_interaction)
IF ( self_interaction /= 0 ) THEN
write(stdout,*) &
' Unpaired-electron self-interaction correction by Mauri', self_interaction
write(stdout,*) &
' E_USIC_EHTE = U_hartree[rho_up + rho_dw]- sic_espilon * U_hartree[rho_up-rhp_down]'
write(stdout,*) &
' E_USIC_XC = E_xc[rho_up,rho_dw] - sic_alpha( E_xc[rho_up,rho_dw] + E_xc[rho_dw, rho_dw]) '
END IF !!select
591 FORMAT( 3X,'')
592 FORMAT( 3X,'Introducing a Mauri Avezac Calandra Self_Interaction Correction: ', I3)
593 FORMAT( 3X,'----------------------------------------')
RETURN
END SUBROUTINE sic_info
!------------------------------------------------------------------------------!
END MODULE sic_module
!------------------------------------------------------------------------------!