Dear Fabio,
I added some lines in the attached file 'Modules/xc_mgga_drivers.f90' so
that, by replacing it with the original one, you should be able to set the
c parameter in tb09. You can do it directly into that module by setting the
initial value of cc_param or in any part of the program by calling the
routine 'set_cc_for_tb09(xx)' (but in case you may need to adjust the
module dependencies).
Before the compilation you need to add the '-lxcf03' in LD_LIBS in the
make.inc file
Hope it helps,
Fabrizio

On Wed, Nov 6, 2019 at 8:36 PM Fabio Costa <fabiocos...@hotmail.com> wrote:

> Dear users and developers
>
> After some more attempts to use the TB09 functional, I ended up finding
> this previous post:
> https://lists.quantum-espresso.org/pipermail/users/2019-April/042619.html ,
> and after changing v_of_rho.f90, the code is now able to end without any
> error.
>
> In my attempts, I'm performing the calculations as an initial scf run with
> a PBE pseudopotencial, and then another scf run, now with restart_mode =
> 'restart' and input_dft = 'MGGA_X_TB09'. By following this procedure, as
> described in E. Germaneau's paper, the calculations do converge.
>
> The issue now is that the gap energies I'm finding are very large. For
> example, for silicon, the calculations result in a 2.8 eV gap, larger even
> than the results presented in the paper, where the values ranged between
> 1.9 to 2.3. Despite the large gaps, the band structure and DOS agree well
> with the ones obtained with PBE.
>
> Is there any way to improve these results. My first guess is to adjust the
> "c" parameter in the mBJ functional. After some searching through the
> routines and Libxc files, I'm still clueless on how to proceed on this
> matter.
>
> Any further suggestions will be much appreciated
>
> Thank you
> Fábio Costa
>
>
>
> ------------------------------
> *De:* users <users-boun...@lists.quantum-espresso.org> em nome de Fabio
> Costa <fabiocos...@hotmail.com>
> *Enviado:* segunda-feira, 14 de outubro de 2019 13:10
> *Para:* users@lists.quantum-espresso.org <users@lists.quantum-espresso.org
> >
> *Assunto:* [QE-users] On the use of the modified Becke-Johnson (TB09)
> functional
>
> Dear all
>
> I'm having some difficulties to work with the TB09 functional. After some
> reading, I found in  some old posts that this can be done by compiling QE
> with Libxc, and by adding the line 'input_dft='tb09'' in the pw.x input.
>
> When I try to use this functional, the scf calculation always ends like
> this:
>
>      total energy              =              NaN Ry     Harris-Foulkes
> estimate   =     -11.24358313 Ry     estimated scf accuracy    <
> 0.01858366 Ry     iteration # 18     ecut=   120.00 Ry     beta= 0.10
>  Davidson diagonalization with
> overlap 
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
>    Error in routine cdiaghg (7):     eigenvectors failed to
> converge 
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
>
> What draws my attention is that always in the last cycle before the error
> the total energy is printed as NaN. The parameters to the calculation seem
> to be fine, as it ends smoothly without the input_dft line.
>
> By searching in the QE user guide, there is a reference to the work of E.
> Germaneau, which lead me to his paper (DOI: 10.1016/j.cpc.2013.02.020
> <http://dx.doi.org/10.1016/j.cpc.2013.02.020>), where the results of his
> implementation are presented. Even though, it is unclear to me how to use
> the functional correctly.
>
> Thanks for any assistance
> Fábio Costa
> _______________________________________________
> Quantum ESPRESSO is supported by MaX (www.max-centre.eu/quantum-espresso)
> users mailing list users@lists.quantum-espresso.org
> https://lists.quantum-espresso.org/mailman/listinfo/users
MODULE xc_mgga
!
USE kinds,     ONLY: DP
USE funct,     ONLY: get_meta, get_metac, is_libxc, &
                     exx_is_active, scan_exx, get_exx_fraction
!
IMPLICIT NONE
!
PRIVATE
SAVE
!
!  GGA exchange-correlation drivers
PUBLIC :: xc_metagcx
PUBLIC :: tau_xc, tau_xc_spin
PUBLIC :: change_threshold_mgga, set_cc_for_tb09
!
!
!  input thresholds (default values)
REAL(DP) :: rho_threshold   = 1.0E-8_DP
REAL(DP) :: grho2_threshold = 1.0E-12_DP
REAL(DP) :: tau_threshold   = 1.0E-8_DP
!
!TB09 ONLY********************************************+++
REAL(DP) :: cc_param = 1.0_DP
!***************************************************

!
 CONTAINS
!
!
!-------------------------------------------------------------------------------------
SUBROUTINE change_threshold_mgga( rho_thr_in, grho2_thr_in, tau_thr_in )
  !------------------------------------------------------------------------------------
  !! Change rho, grho and tau thresholds.
  ! 
  REAL(DP), INTENT(IN) :: rho_thr_in
  REAL(DP), INTENT(IN), OPTIONAL :: grho2_thr_in
  REAL(DP), INTENT(IN), OPTIONAL :: tau_thr_in
  !
  rho_threshold = rho_thr_in
  IF ( PRESENT(grho2_thr_in) ) grho2_threshold = grho2_thr_in
  IF ( PRESENT(tau_thr_in)  ) tau_threshold  = tau_thr_in
  !
  RETURN
  !
END SUBROUTINE change_threshold_mgga
!
!
! ONLY FOR TB09 ********************************************************
SUBROUTINE set_cc_for_tb09( cc_in )
  !--------------------------------------------------------------------
  !! Change rho threshold.
  !
  IMPLICIT NONE
  !
  REAL(DP), INTENT(IN) :: cc_in
  !
  cc_param = cc_in
  !
  RETURN
  !
END SUBROUTINE
!*********************************************************************
!
!
!----------------------------------------------------------------------------------------
SUBROUTINE xc_metagcx( length, ns, np, rho, grho, tau, ex, ec, v1x, v2x, v3x, v1c, v2c, v3c )
  !-------------------------------------------------------------------------------------
  !! Wrapper routine. Calls metaGGA drivers from internal libraries
  !! of q-e or from the external libxc, depending on the input choice.
  !
#if defined(__LIBXC)
  USE funct,            ONLY : get_libxc_flags_exc
  USE xc_f90_types_m
  USE xc_f90_lib_m
  USE xc_f03_lib_m
#endif 
  !
  IMPLICIT NONE
  !
  INTEGER, INTENT(IN) :: length
  !! length of the I/O arrays
  INTEGER, INTENT(IN) :: ns
  !! spin components
  INTEGER, INTENT(IN) :: np
  !! first dimension of v2c
  REAL(DP), INTENT(IN) :: rho(length,ns)
  !! the charge density
  REAL(DP), INTENT(IN) :: grho(3,length,ns)
  !! grho = \nabla rho
  REAL(DP), INTENT(IN) :: tau(length,ns)
  !! kinetic energy density
  REAL(DP), INTENT(OUT) :: ex(length)
  !! sx = E_x(rho,grho)
  REAL(DP), INTENT(OUT) :: ec(length)
  !! sc = E_c(rho,grho)
  REAL(DP), INTENT(OUT) :: v1x(length,ns)
  !! v1x = D(E_x)/D(rho)
  REAL(DP), INTENT(OUT) :: v2x(length,ns)
  !! v2x = D(E_x)/D( D rho/D r_alpha ) / |\nabla rho|
  REAL(DP), INTENT(OUT) :: v3x(length,ns)
  !! v3x = D(E_x)/D(tau)
  REAL(DP), INTENT(OUT) :: v1c(length,ns)
  !! v1c = D(E_c)/D(rho)
  REAL(DP), INTENT(OUT) :: v2c(np,length,ns)
  !! v2c = D(E_c)/D( D rho/D r_alpha ) / |\nabla rho|
  REAL(DP), INTENT(OUT) :: v3c(length,ns)
  !! v3c = D(E_c)/D(tau)
  !
  ! ... local variables
  !
  INTEGER :: is, imeta, imetac
  REAL(DP), ALLOCATABLE :: grho2(:,:)
  !
#if defined(__LIBXC)
  TYPE(xc_f90_pointer_t) :: xc_func
  TYPE(xc_f90_pointer_t) :: xc_info1, xc_info2
  !
  !TB09 ONLY******************************************************************
  TYPE(xc_f03_func_t) :: xc_func03
  REAL(DP) :: ext_params(1)  !number of external parameters could be bigger,
                             !depending on the chosen functionals
  !*********************************************************************
  
  REAL(DP), ALLOCATABLE :: rho_lxc(:), sigma(:), tau_lxc(:)
  REAL(DP), ALLOCATABLE :: ex_lxc(:), ec_lxc(:)
  REAL(DP), ALLOCATABLE :: vx_rho(:), vx_sigma(:), vx_tau(:)
  REAL(DP), ALLOCATABLE :: vc_rho(:), vc_sigma(:), vc_tau(:)
  REAL(DP), ALLOCATABLE :: lapl_rho(:), vlapl_rho(:) ! not used in TPSS
  !
  REAL(DP) :: exx_fraction
  INTEGER :: k, ipol, pol_unpol, eflag
  LOGICAL :: POLARIZED
  !
  imeta  = get_meta()
  imetac = get_metac()
  !
  ex = 0.0_DP ;  v1x = 0.0_DP ;  v2x = 0.0_DP ;  v3x = 0.0_DP
  ec = 0.0_DP ;  v1c = 0.0_DP ;  v2c = 0.0_DP ;  v3c = 0.0_DP
  !
  POLARIZED = .FALSE.
  IF (ns == 2) THEN
     POLARIZED = .TRUE.
  ENDIF
  !
  pol_unpol = ns
  !
  ALLOCATE( rho_lxc(length*ns), sigma(length*ns), tau_lxc(length*ns) )
  ALLOCATE( lapl_rho(length*ns) )
  !
  ALLOCATE( ex_lxc(length)    , ec_lxc(length) )
  ALLOCATE( vx_rho(length*ns) , vx_sigma(length*ns), vx_tau(length*ns) )
  ALLOCATE( vc_rho(length*ns) , vc_sigma(length*ns), vc_tau(length*ns) )
  ALLOCATE( vlapl_rho(length*ns) )
  !
  !
  IF ( ns == 1 ) THEN
    !
    DO k = 1, length
      rho_lxc(k) = ABS( rho(k,1) )
      IF ( rho_lxc(k) > rho_threshold ) &
         sigma(k) = grho(1,k,1)**2 + grho(2,k,1)**2 + grho(3,k,1)**2
      tau_lxc(k) = tau(k,1)
    ENDDO
    !
  ELSE
    !
    DO k = 1, length
       rho_lxc(2*k-1) = rho(k,1)
       rho_lxc(2*k)   = rho(k,2)
       !
       sigma(3*k-2) = grho(1,k,1)**2 + grho(2,k,1)**2 + grho(3,k,1)**2
       sigma(3*k-1) = grho(1,k,1) * grho(1,k,2) + grho(2,k,1) * grho(2,k,2) + &
                      grho(3,k,1) * grho(3,k,2)
       sigma(3*k)   = grho(1,k,2)**2 + grho(2,k,2)**2 + grho(3,k,2)**2
       !
       tau_lxc(2*k-1) = tau(k,1)
       tau_lxc(2*k)   = tau(k,2)
    ENDDO
    !
  ENDIF
  !
  IF ( .NOT.is_libxc(5) .AND. imetac==0 ) THEN
    !
    ALLOCATE( grho2(length,ns) )
    !
    DO is = 1, ns
       grho2(:,is) = grho(1,:,is)**2 + grho(2,:,is)**2 + grho(3,:,is)**2
    ENDDO
    !
    IF (ns == 1) THEN
       CALL tau_xc( length, rho(:,1), grho2(:,1), tau(:,1), ex, ec, v1x(:,1), &
                    v2x(:,1), v3x(:,1), v1c(:,1), v2c(1,:,1), v3c(:,1) )
    ELSEIF (ns == 2) THEN
       CALL tau_xc_spin( length, rho, grho, tau, ex, ec, v1x, v2x, v3x, v1c, &
                         v2c, v3c )
    ENDIF
    !
    DEALLOCATE( grho2 )
    !
  ENDIF
  !
  ! META EXCHANGE
  !
  IF ( is_libxc(5) ) THEN
     !
     !ONLY FOR TB09***********************************************************
     IF ( imeta==208 ) THEN
       CALL xc_f03_func_init( xc_func03, imeta, 1 )
        ext_params(1) = cc_param
        CALL xc_f03_func_set_ext_params( xc_func03, ext_params )
       CALL xc_f03_func_end( xc_func03 )
     ENDIF
     !********************************************************************
     !
    CALL xc_f90_func_init( xc_func, xc_info1, imeta, pol_unpol )
     CALL get_libxc_flags_exc( xc_info1, eflag )
     IF (eflag==1) THEN
       CALL xc_f90_mgga_exc_vxc( xc_func, length, rho_lxc(1), sigma(1), lapl_rho(1), tau_lxc(1), &
                                 ex_lxc(1), vx_rho(1), vx_sigma(1), vlapl_rho(1), vx_tau(1) )
     ELSE
       CALL xc_f90_mgga_vxc( xc_func, length, rho_lxc(1), sigma(1), lapl_rho(1), tau_lxc(1), &
                             vx_rho(1), vx_sigma(1), vlapl_rho(1), vx_tau(1) )
     ENDIF
    CALL xc_f90_func_end( xc_func )
    !
    IF (.NOT. POLARIZED) THEN
      DO k = 1, length
        ex(k) = ex_lxc(k) * rho_lxc(k)
        v1x(k,1) = vx_rho(k)
        v2x(k,1) = vx_sigma(k) * 2.0_DP
        v3x(k,1) = vx_tau(k)
      ENDDO
    ELSE
      DO k = 1, length
        ex(k) = ex_lxc(k) * (rho_lxc(2*k-1)+rho_lxc(2*k))
        v1x(k,1) = vx_rho(2*k-1)
        v1x(k,2) = vx_rho(2*k)
        v2x(k,1) = vx_sigma(3*k-2)*2.d0
        v2x(k,2) = vx_sigma(3*k)*2.d0
        v3x(k,1) = vx_tau(2*k-1)
        v3x(k,2) = vx_tau(2*k)
      ENDDO
    ENDIF
    !
    ! ... only for HK/MCA: SCAN0 (used in CPV)
    IF ( scan_exx ) THEN
       exx_fraction = get_exx_fraction()
       IF (exx_is_active()) THEN
         ex  = (1.0_DP - exx_fraction) * ex
         v1x = (1.0_DP - exx_fraction) * v1x
         v2x = (1.0_DP - exx_fraction) * v2x
         v3x = (1.0_DP - exx_fraction) * v3x
       ENDIF
    ENDIF
    !
  ENDIF
  !
  ! META CORRELATION
  !
  IF ( is_libxc(6) ) THEN
    !
    CALL xc_f90_func_init( xc_func, xc_info1, imetac, pol_unpol )
     CALL xc_f90_mgga_exc_vxc( xc_func, length, rho_lxc(1), sigma(1), lapl_rho(1), tau_lxc(1), &
                               ec_lxc(1), vc_rho(1), vc_sigma(1), vlapl_rho(1), vc_tau(1) )
    CALL xc_f90_func_end( xc_func )
    !
    IF (.NOT. POLARIZED) THEN
       DO k = 1, length
          ec(k) = ec_lxc(k) * rho_lxc(k) !* SIGN(1.0_DP, rho(k,1))
          v1c(k,1) = vc_rho(k)
          v2c(1,k,1) = vc_sigma(k) * 2.0_DP
          v3c(k,1) = vc_tau(k)
       ENDDO
    ELSE
       DO k = 1, length
          ec(k) = ec_lxc(k) * (rho_lxc(2*k-1)+rho_lxc(2*k))
          v1c(k,1) = vc_rho(2*k-1)
          v1c(k,2) = vc_rho(2*k)
          DO ipol = 1, 3
            v2c(ipol,k,1) = vc_sigma(3*k-2)*grho(ipol,k,1)*2.D0 + vc_sigma(3*k-1)*grho(ipol,k,2)
            v2c(ipol,k,2) = vc_sigma(3*k)  *grho(ipol,k,2)*2.D0 + vc_sigma(3*k-1)*grho(ipol,k,1)
          ENDDO
          v3c(k,1) = vc_tau(2*k-1)
          v3c(k,2) = vc_tau(2*k)
       ENDDO
    ENDIF
    !
  ENDIF
  !
  DEALLOCATE( rho_lxc, sigma, tau_lxc, lapl_rho )
  DEALLOCATE( ex_lxc , ec_lxc )
  DEALLOCATE( vx_rho , vx_sigma, vx_tau )
  DEALLOCATE( vc_rho , vc_sigma, vc_tau, vlapl_rho )
  !
#else
  !
  ALLOCATE( grho2(length,ns) )
  !
  DO is = 1, ns
     grho2(:,is) = grho(1,:,is)**2 + grho(2,:,is)**2 + grho(3,:,is)**2
  ENDDO
  !
  IF (ns == 1) THEN
     !
     CALL tau_xc( length, rho(:,1), grho2(:,1), tau(:,1), ex, ec, v1x(:,1), &
                  v2x(:,1), v3x(:,1), v1c(:,1), v2c(1,:,1), v3c(:,1) )
     !
  ELSEIF (ns == 2) THEN
     !
     CALL tau_xc_spin( length, rho, grho, tau, ex, ec, v1x, v2x, v3x, v1c, &
                       v2c, v3c )
     !
  ENDIF
  !
  DEALLOCATE( grho2 )
  !
#endif
  !
  RETURN
  !
END SUBROUTINE xc_metagcx
!
!
!---------------------------------------------------------------------------------
SUBROUTINE tau_xc( length, rho, grho2, tau, ex, ec, v1x, v2x, v3x, v1c, v2c, v3c )
  !-------------------------------------------------------------------------------
  !  gradient corrections for exchange and correlation - Hartree a.u.
  !  See comments at the beginning of module for implemented cases
  !
  !  input:  rho, grho=|\nabla rho|^2
  !
  !  definition:  E_x = \int e_x(rho,grho) dr
  !
  !  output: sx = e_x(rho,grho) = grad corr
  !          v1x= D(E_x)/D(rho)
  !          v2x= D(E_x)/D( D rho/D r_alpha ) / |\nabla rho|
  !          v3x= D(E_x)/D(tau)
  !
  !          sc, v1c, v2c as above for correlation
  !
  IMPLICIT NONE
  !
  INTEGER, INTENT(IN) :: length
  !
  INTEGER :: k, imeta
  REAL(DP) :: arho
  REAL(DP), DIMENSION(length) :: rho, grho2, tau, &
                                 ex, ec, v1x, v2x, v3x, v1c, v2c, v3c
  !
  imeta = get_meta()
  !
  v1x=0.d0 ; v2x=0.d0 ; v3x=0.d0 ; ex=0.d0
  v1c=0.d0 ; v2c=0.d0 ; v3c=0.d0 ; ec=0.d0
  !
  DO k = 1, length
    !
    arho = ABS(rho(k))
    !
    IF ( (arho<=rho_threshold).OR.(grho2(k)<=grho2_threshold).OR.(ABS(tau(k))<=rho_threshold) ) CYCLE
    !
    SELECT CASE( imeta )
    CASE( 1 )
       CALL tpsscxc( arho, grho2(k), tau(k), ex(k), ec(k), v1x(k), v2x(k), v3x(k), v1c(k), v2c(k), v3c(k) )
    CASE( 2 )
       CALL m06lxc(  arho, grho2(k), tau(k), ex(k), ec(k), v1x(k), v2x(k), v3x(k), v1c(k), v2c(k), v3c(k) )
    CASE DEFAULT
       CALL errore( 'tau_xc', 'This case is not implemented', imeta )
    END SELECT
    !
  ENDDO
  !
  RETURN
  !
END SUBROUTINE tau_xc
!
!
!----------------------------------------------------------------------------------------
SUBROUTINE tau_xc_spin( length, rho, grho, tau, ex, ec, v1x, v2x, v3x, v1c, v2c, v3c )
  !------------------------------------------------------------------------------------
  !
  IMPLICIT NONE
  !
  INTEGER,  INTENT(IN) :: length
  REAL(DP), INTENT(IN) :: rho(length,2), tau(length,2)
  REAL(DP), INTENT(IN) :: grho(3,length,2)
  !
  REAL(DP), INTENT(OUT) :: ex(length), ec(length), v1x(length,2), v2x(length,2), &
                           v3x(length,2), v1c(length,2), v3c(length,2)
  REAL(DP), INTENT(OUT) :: v2c(3,length,2)
  !
  !  ... local variables
  !
  INTEGER :: k, ipol, imeta
  REAL(DP) :: rh, zeta, atau, grho2(2), ggrho2
  REAL(DP) :: v2cup, v2cdw
  !
  imeta = get_meta()
  !
  ex=0.0_DP ; v1x=0.0_DP ; v2x=0.0_DP ; v3x=0.0_DP
  ec=0.0_DP ; v1c=0.0_DP ; v2c=0.0_DP ; v3c=0.0_DP
  !
  ! FIXME: for SCAN, this will be calculated later
  !
  DO k = 1, length
     !
     rh   = rho(k,1) + rho(k,2)
     atau = tau(k,1) + tau(k,2)             ! KE-density in Hartree
     grho2(1) = SUM( grho(:,k,1)**2 )
     grho2(2) = SUM( grho(:,k,2)**2 )
     ggrho2 = ( grho2(1) + grho2(2) ) * 4.0_DP
     !
     IF ((rh <= rho_threshold) .OR. (ggrho2 <= grho2_threshold) .OR. (ABS(atau) <= tau_threshold)) CYCLE
     !
     SELECT CASE( imeta )
     CASE( 1 )
        !
        CALL tpsscx_spin( rho(k,1), rho(k,2), grho2(1), grho2(2), tau(k,1), &
                          tau(k,2), ex(k), v1x(k,1), v1x(k,2), v2x(k,1), v2x(k,2), v3x(k,1), v3x(k,2) )
        !
        zeta = (rho(k,1) - rho(k,2)) / rh
        !
        CALL tpsscc_spin( rh, zeta, grho(:,k,1), grho(:,k,2), atau, ec(k), &
                          v1c(k,1), v1c(k,2), v2c(:,k,1), v2c(:,k,2), v3c(k,1), v3c(k,2) )
        !
     CASE( 2 )
        !
        CALL m06lxc_spin( rho(k,1), rho(k,2), grho2(1), grho2(2), tau(k,1), tau(k,2), ex(k), ec(k), &
                          v1x(k,1), v1x(k,2), v2x(k,1), v2x(k,2), v3x(k,1), v3x(k,2), &
                          v1c(k,1), v1c(k,2), v2cup   , v2cdw   , v3c(k,1), v3c(k,2)  )
        !
        v2c(:,k,1) = v2cup*grho(:,k,1)
        v2c(:,k,2) = v2cdw*grho(:,k,2)
        !
     CASE DEFAULT
        !
        CALL errore( 'tau_xc_spin', 'This case not implemented', imeta )
        !
     END SELECT
     !
  ENDDO
  !
  RETURN
  !
END SUBROUTINE tau_xc_spin
!
!
END MODULE xc_mgga
_______________________________________________
Quantum ESPRESSO is supported by MaX (www.max-centre.eu/quantum-espresso)
users mailing list users@lists.quantum-espresso.org
https://lists.quantum-espresso.org/mailman/listinfo/users

Reply via email to