svdW-DF implemented

git-svn-id: http://qeforge.qe-forge.org/svn/q-e/trunk/espresso@11720 c92efa57-630b-4861-b058-cf58834340f0
This commit is contained in:
thonhauser 2015-09-11 20:44:10 +00:00
parent 08a572991e
commit 1c4852024f
10 changed files with 2873 additions and 3205 deletions

View File

@ -1,5 +1,6 @@
New in svn version:
* svdW-DF - a proper spin version of vdW-DF (courtesy of Timo Thonhauser)
* XSpectra: various improvements
Incompatible changes in 5.2.0 version:

View File

@ -188,9 +188,8 @@ mentioned in Sect.\ref{SubSec:Terms}, include:
vdW corrections;
\item Ikutaro Hamada (NIMS, Japan) for OPTB86B-vdW and REV-vdW-DF2
functionals;
\item Timo Thonhauser's group (Wake Forest University)
for vdW-DF and variants, with support from
Riccardo Sabatini and Stefano de Gironcoli (SISSA and DEMOCRITOS);
\item Timo Thonhauser (WFU) for vdW-DF and variants, including the
spin development svdW-DF;
\item Daniel Forrer (Padua Univ.) and Michele Pavone
(Naples Univ. Federico II) for dispersions interaction in the
framework of DFT-D;

View File

@ -110,8 +110,11 @@ module funct
! "hse" = "sla+pw+hse+pbc" = Heyd-Scuseria-Ernzerhof (HSE 06, see note below)
! "b3lyp" = "b3lp+vwn+b3lp+b3lp"= B3LYP
! "gaupbe"= "sla+pw+gaup+pbc" = Gau-PBE (also "gaup")
! "vdw-df" ="sla+pw+rpb +vdw1" = vdW-DF
! "vdw-df" ="sla+pw+rpb +vdw1" = vdW-DF1
! "vdw-df2" ="sla+pw+rw86+vdw2" = vdW-DF2
! "vdw-df-x" ="sla+pw+????+vdwx" = vdW-DF-x, reserved Thonhauser, not implemented
! "vdw-df-y" ="sla+pw+????+vdwy" = vdW-DF-y, reserved Thonhauser, not implemented
! "vdw-df-z" ="sla+pw+????+vdwz" = vdW-DF-z, reserved Thonhauser, not implemented
! "vdw-df-c09" ="sla+pw+c09x+vdw1" = vdW-DF-C09
! "vdw-df2-c09" ="sla+pw+c09x+vdw2" = vdW-DF2-C09
! "vdw-df-cx" ="sla+pw+cx13+vdW1" = vdW-DF-cx
@ -189,10 +192,13 @@ module funct
! "tb09" TB09 Meta-GGA imeta=3
!
! Van der Waals functionals (nonlocal term only)
! "nonlc" none inlc =0 (default)
! "nonlc" none inlc =0 (default)
! "vdw1" vdW-DF1 inlc =1
! "vdw2" vdW-DF2 inlc =2
! "vv10" rVV10 inlc =3
! "vv10" rVV10 inlc =3
! "vdwx" vdW-DF-x inlc =4, reserved Thonhauser, not implemented
! "vdwy" vdW-DF-y inlc =5, reserved Thonhauser, not implemented
! "vdwz" vdW-DF-z inlc =6, reserved Thonhauser, not implemented
!
! Note: as a rule, all keywords should be unique, and should be different
! from the short name, but there are a few exceptions.
@ -230,7 +236,7 @@ module funct
! J.Phys.Chem 98, 11623 (1994)
! vdW-DF M. Dion et al., PRL 92, 246401 (2004)
! T. Thonhauser et al., PRB 76, 125112 (2007)
! vdw-DF2 Lee et al., Phys. Rev. B 82, 081101 (2010)
! vdW-DF2 Lee et al., Phys. Rev. B 82, 081101 (2010)
! rev-vdW-DF2 I. Hamada, Phys. Rev. B 89, 121103(R) (2014)
! vdW-DF-cx K. Berland and P. Hyldgaard, PRB 89, 035412 (2014)
! vdW-DF-obk8 Klimes et al, J. Phys. Cond. Matter, 22, 022201 (2010)
@ -286,7 +292,7 @@ module funct
real(DP):: finite_size_cell_volume = notset
logical :: discard_input_dft = .false.
!
integer, parameter:: nxc=8, ncc=10, ngcx=27, ngcc=12, nmeta=3, ncnl=3
integer, parameter:: nxc=8, ncc=10, ngcx=27, ngcc=12, nmeta=3, ncnl=6
character (len=4) :: exc, corr, gradx, gradc, meta, nonlocc
dimension :: exc (0:nxc), corr (0:ncc), gradx (0:ngcx), gradc (0:ngcc), &
meta(0:nmeta), nonlocc (0:ncnl)
@ -305,7 +311,7 @@ module funct
data meta / 'NONE', 'TPSS', 'M06L', 'TB09' /
data nonlocc/'NONE', 'VDW1', 'VDW2', 'VV10' /
data nonlocc/'NONE', 'VDW1', 'VDW2', 'VV10', 'VDWX', 'VDWY', 'VDWZ' /
CONTAINS
!-----------------------------------------------------------------------
@ -450,6 +456,15 @@ CONTAINS
! Special case vdW-DF
dft_defined = set_dft_values(1,4,4,0,1,0)
else if ('VDW-DF-X' .EQ. TRIM(dftout) ) then
call errore('set_dft_from_name','functional not yet implemented',1)
else if ('VDW-DF-Y' .EQ. TRIM(dftout) ) then
call errore('set_dft_from_name','functional not yet implemented',1)
else if ('VDW-DF-Z' .EQ. TRIM(dftout) ) then
call errore('set_dft_from_name','functional not yet implemented',1)
else if ('VDW-DF-CX' .EQ. TRIM(dftout)) then
! Special case vdW-DF-CX
dft_defined = set_dft_values(1,4,27,0,1,0)
@ -461,12 +476,14 @@ CONTAINS
else if ('VDW-DF-OBK8' .EQ. TRIM(dftout)) then
! Special case vdW-DF-obk8, or vdW-DF + optB88
dft_defined = set_dft_values(1,4,23,0,1,0)
else if ('VDW-DF3' .EQ. TRIM(dftout) ) then
call errore('set_dft_from_name','obsolete XC label, use VDW-DF-OBK8',1)
else if ('VDW-DF-OB86' .EQ. TRIM(dftout) ) then
! Special case vdW-DF-ob86, or vdW-DF + optB86
dft_defined = set_dft_values(1,4,24,0,1,0)
else if ('VDW-DF4'.EQ.TRIM(dftout) .OR. 'OPTB86B-VDW'.EQ.TRIM(dftout) ) then
call errore('set_dft_from_name','obsolete XC label, use VDW-DF-OB86',1)
@ -966,7 +983,7 @@ CONTAINS
shortname_ = 'TB09'
end if
if ( inlc_==1) then
if ( inlc_==1 ) then
if (iexch_==1.and.icorr_==4.and.igcx_==4.and.igcc_==0) then
shortname_ = 'VDW-DF'
else if (iexch_==1.and.icorr_==4.and.igcx_==27.and.igcc_==0) then
@ -978,7 +995,7 @@ CONTAINS
else if (iexch_==1.and.icorr_==4.and.igcx_==23.and.igcc_==0) then
shortname_ = 'VDW-DF-OBK8'
end if
else if ( inlc_==2) then
else if ( inlc_==2 ) then
if (iexch_==1.and.icorr_==4.and.igcx_==13.and.igcc_==0) then
shortname_ = 'VDW-DF2'
else if (iexch_==1.and.icorr_==4.and.igcx_==16.and.igcc_==0) then
@ -1618,6 +1635,44 @@ subroutine gcx_spin (rhoup, rhodw, grhoup2, grhodw2, &
v2xup = 2.0_DP * v2xup
v2xdw = 2.0_DP * v2xdw
elseif (igcx == 13) then ! 'revised PW86 for vdw-df2'
if (rhoup > small .and. sqrt (abs (grhoup2) ) > small) then
call rPW86 (2.0_DP * rhoup, 4.0_DP * grhoup2, sxup, v1xup, v2xup)
else
sxup = 0.0_DP
v1xup = 0.0_DP
v2xup = 0.0_DP
endif
if (rhodw > small .and. sqrt (abs (grhodw2) ) > small) then
call rPW86 (2.0_DP * rhodw, 4.0_DP * grhodw2, sxdw, v1xdw, v2xdw)
else
sxdw = 0.0_DP
v1xdw = 0.0_DP
v2xdw = 0.0_DP
endif
sx = 0.5_DP * (sxup + sxdw)
v2xup = 2.0_DP * v2xup
v2xdw = 2.0_DP * v2xdw
elseif (igcx == 16) then ! 'c09x for vdw-df-c09.'
if (rhoup > small .and. sqrt (abs (grhoup2) ) > small) then
call c09x (2.0_DP * rhoup, 4.0_DP * grhoup2, sxup, v1xup, v2xup)
else
sxup = 0.0_DP
v1xup = 0.0_DP
v2xup = 0.0_DP
endif
if (rhodw > small .and. sqrt (abs (grhodw2) ) > small) then
call c09x (2.0_DP * rhodw, 4.0_DP * grhodw2, sxdw, v1xdw, v2xdw)
else
sxdw = 0.0_DP
v1xdw = 0.0_DP
v2xdw = 0.0_DP
endif
sx = 0.5_DP * (sxup + sxdw)
v2xup = 2.0_DP * v2xup
v2xdw = 2.0_DP * v2xdw
elseif (igcx == 21) then ! 'PW86'
if (rhoup > small .and. sqrt (abs (grhoup2) ) > small) then
call pw86 (2.0_DP * rhoup, 4.0_DP * grhoup2, sxup, v1xup, v2xup)
@ -1869,6 +1924,48 @@ subroutine gcx_spin_vec(rhoup, rhodw, grhoup2, grhodw2, &
v2xup = 2.0_DP * v2xup
v2xdw = 2.0_DP * v2xdw
case(13) ! 'rPW86 for vdw-df2'
do i=1,length
if (rhoup(i) > small .and. sqrt(abs(grhoup2(i))) > small) then
call rPW86 (2.0_DP * rhoup(i), 4.0_DP * grhoup2(i), sxup(i), v1xup(i), v2xup(i))
else
sxup(i) = 0.0_DP
v1xup(i) = 0.0_DP
v2xup(i) = 0.0_DP
endif
if (rhodw(i) > small .and. sqrt(abs(grhodw2(i))) > small) then
call rPW86 (2.0_DP * rhodw(i), 4.0_DP * grhodw2(i), sxdw(i), v1xdw(i), v2xdw(i))
else
sxdw(i) = 0.0_DP
v1xdw(i) = 0.0_DP
v2xdw(i) = 0.0_DP
endif
end do
sx = 0.5_DP * (sxup + sxdw)
v2xup = 2.0_DP * v2xup
v2xdw = 2.0_DP * v2xdw
case(16) ! 'c09x for vdw-df-c09'
do i=1,length
if (rhoup(i) > small .and. sqrt(abs(grhoup2(i))) > small) then
call c09x (2.0_DP * rhoup(i), 4.0_DP * grhoup2(i), sxup(i), v1xup(i), v2xup(i))
else
sxup(i) = 0.0_DP
v1xup(i) = 0.0_DP
v2xup(i) = 0.0_DP
endif
if (rhodw(i) > small .and. sqrt(abs(grhodw2(i))) > small) then
call c09x (2.0_DP * rhodw(i), 4.0_DP * grhodw2(i), sxdw(i), v1xdw(i), v2xdw(i))
else
sxdw(i) = 0.0_DP
v1xdw(i) = 0.0_DP
v2xdw(i) = 0.0_DP
endif
end do
sx = 0.5_DP * (sxup + sxdw)
v2xup = 2.0_DP * v2xup
v2xdw = 2.0_DP * v2xdw
case(21) ! 'pw86'
do i=1,length
if (rhoup(i) > small .and. sqrt(abs(grhoup2(i))) > small) then
@ -2087,7 +2184,7 @@ subroutine nlc (rho_valence, rho_core, nspin, enl, vnl, v)
! v = Correction to the potential
!
USE vdW_DF, ONLY: xc_vdW_DF, vdw_type
USE vdW_DF, ONLY: xc_vdW_DF, xc_vdW_DF_spin, vdw_type
USE rVV10, ONLY: xc_rVV10
implicit none
@ -2097,14 +2194,20 @@ subroutine nlc (rho_valence, rho_core, nspin, enl, vnl, v)
REAL(DP), INTENT(INOUT) :: v(:,:)
REAL(DP), INTENT(INOUT) :: enl, vnl
if (inlc == 1 .or. inlc == 2) then
if ( inlc == 1 .or. inlc == 2 .or. inlc == 4 .or. inlc == 5 .or. inlc == 6 ) then
vdw_type = inlc
call xc_vdW_DF(rho_valence, rho_core, nspin, enl, vnl, v)
if( nspin == 1 ) then
call xc_vdW_DF (rho_valence, rho_core, enl, vnl, v)
else if( nspin == 2 ) then
call xc_vdW_DF_spin (rho_valence, rho_core, enl, vnl, v)
else
call errore ('nlc','vdW-DF not available for noncollinear spin case',1)
end if
elseif (inlc == 3) then
call xc_rVV10(rho_valence, rho_core, nspin, enl, vnl, v)
call xc_rVV10 (rho_valence, rho_core, nspin, enl, vnl, v)
else
enl = 0.0_DP

View File

@ -1,183 +1,198 @@
!
! Copyright (C) 2001-2009 Quantum ESPRESSO group
! Copyright (C) 2009 Brian Kolb, Timo Thonhauser - Wake Forest University
! 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 kernel_table
!! This module is used to read in the kernel table file
!! "vdW_kernel_table" and store some of the important parameters. The
!! top of the vdW_kernel_table file holds the number of q points, the
!! number of radial points (r) used in the kernel generation, the maximum
!! value of r used (r is the parameter in the kernel function d=q*r where
!! q is defined in DION equation 11), and the values of the q points
!! used. These parameters are stored as public parameters for use in
!! various routines. This routine also reads the tabulated values of the
!! Fourier transformed kernel function for each pair of q values (see
!! SOLER equations 3 and 8). Since these kernel functions need to be
!! interpolated using splines, the second derivatives of the Fourier
!! transformed kernel functions (phi_alpha_beta) are also tabulated in
!! the vdW_kernel_table and are read in here.
!! This is done in a module because there are quite a few subroutines in
!! xc_vdW_DF.f90 that require knowledge of the number (identity) of q
!! points, the maximum value of the radius, and, of course, the tabulated
!! kernel function and its second derivatives (for spline interpolation).
!! Putting this routine in a module meas that those routines can just use
!! kernel_table rather than passing variables around all over the place.
USE kinds, ONLY : dp
USE io_files, ONLY : pseudo_dir
USE constants, ONLY : pi
use wrappers, ONLY : md5_from_file
implicit none
private
save
!! Variables to be used by various routines in xc_vdW_DF.f90, declared
!! public so they can be seen from outside
! --------------------------------------------------------------------------
public :: Nqs, Nr_points, r_max, q_mesh, q_cut, q_min, dk
public :: kernel, d2phi_dk2
public :: initialize_kernel_table
public :: vdw_table_name
public :: vdw_kernel_md5_cksum
integer :: Nqs, Nr_points !! The number of q points and radial points
! !! used in generating the kernel phi(q1*r, q2*r)
! !! (see DION 14-16 and SOLER 3)
! This module is used to read in the kernel table file
! "vdW_kernel_table" and store some of the important parameters. The top
! of the vdW_kernel_table file holds the number of q points, the number
! of radial points (r) used in the kernel generation, the maximum value
! of r used (r is the parameter in the kernel function d=q*r where q is
! defined in DION equation 11), and the values of the q points used.
! These parameters are stored as public parameters for use in various
! routines. This routine also reads the tabulated values of the Fourier
! transformed kernel function for each pair of q values (see SOLER
! equations 3 and 8). Since these kernel functions need to be
! interpolated using splines, the second derivatives of the Fourier
! transformed kernel functions (phi_alpha_beta) are also tabulated in
! the vdW_kernel_table and are read in here.
real(dp) :: r_max, q_cut, q_min, dk !! The maximum value of r, the maximum and minimum
! !! values of q and the k-space spacing of grid points.
! !! Note that, during a vdW run, values of q0 found
! !! larger than q_cut will be saturated (SOLER 5) to
! !! q_cut
! This is done in a module because there are quite a few subroutines in
! xc_vdW_DF.f90 that require knowledge of the number (identity) of q
! points, the maximum value of the radius, and, of course, the tabulated
! kernel function and its second derivatives (for spline interpolation).
! Putting this routine in a module meas that those routines can just use
! kernel_table rather than passing variables around all over the place.
real(dp), allocatable :: q_mesh(:) !! The values of all the q points used
USE kinds, ONLY : dp
USE io_files, ONLY : pseudo_dir
USE constants, ONLY : pi
use wrappers, ONLY : md5_from_file
implicit none
real(dp), allocatable :: kernel(:,:,:) !! A matrix holding the Fourier transformed kernel function
! !! for each pair of q values. The ordering is
! !! kernel(k_point, q1_value, q2_value)
private
save
! ----------------------------------------------------------------------
! Variables to be used by various routines in xc_vdW_DF.f90, declared
! public so they can be seen from outside
public :: Nqs, Nr_points, r_max, q_mesh, q_cut, q_min, dk
public :: kernel, d2phi_dk2
public :: initialize_kernel_table
public :: vdw_table_name
public :: vdw_kernel_md5_cksum
integer :: Nqs, Nr_points ! The number of q points and radial points
! used in generating the kernel phi(q1*r, q2*r)
! (see DION 14-16 and SOLER 3-5).
real(dp) :: r_max, q_cut, q_min, dk ! The maximum value of r, the maximum and minimum
! values of q and the k-space spacing of grid points.
! Note that, during a vdW run, values of q0 found
! larger than q_cut will be saturated (SOLER 5) to
! q_cut.
real(dp), allocatable :: q_mesh(:) ! The values of all the q points used.
real(dp), allocatable :: kernel(:,:,:) ! A matrix holding the Fourier transformed kernel
! function for each pair of q values. The ordering
! is kernel(k_point, q1_value, q2_value).
real(dp), allocatable :: d2phi_dk2(:,:,:) ! A matrix holding the second derivatives of the
! above kernel matrix at each of the q points.
! Stored as d2phi_dk2(k_point, q1_value, q2_value).
character(len=256) :: vdw_table_name = ' ' ! If present from input use this name.
character(LEN=30) :: double_format = "(1p4e23.14)"
character(len=32) :: vdw_kernel_md5_cksum = 'NOT SET'
integer, external :: find_free_unit
real(dp), allocatable :: d2phi_dk2(:,:,:) !! A matrix holding the second derivatives of the above
! !! kernel matrix at each of the q points. Stored as
! !! d2phi_dk2(k_point, q1_value, q2_value)
!
character(len=256) :: vdw_table_name = ' ' !! If present from input use this name
CHARACTER(LEN=30) :: double_format = "(1p4e23.14)"
CHARACTER(len=32) :: vdw_kernel_md5_cksum = 'NOT SET'
!
INTEGER, EXTERNAL :: find_free_unit
! --------------------------------------------------------------------------
CONTAINS
!! ###################################################################################
!! | |
!! | INITIALIZE_KERNEL_TABLE |
!! |___________________________|
!! Subroutine that actually reads the kernel file and stores the parameters. This routine
!! is called only once, at the start of a vdW run.
! ####################################################################
! | |
! | INITIALIZE_KERNEL_TABLE |
! |___________________________|
!
! Subroutine that actually reads the kernel file and stores the
! parameters. This routine is called only once, at the start of a vdW
! run.
subroutine initialize_kernel_table(inlc)
integer, INTENT(IN) :: inlc
integer :: q1_i, q2_i !! Indexing variables
integer :: q1_i, q2_i ! Indexing variables.
integer :: kernel_file ! The unit number for the kernel file.
logical :: file_exists ! A variable to say whether
! needed file exists.
character(len=1000) :: kernel_file_name ! The path to the kernel file.
! Although this name must be
! "vdW_kernel_table", this variable
! is used to hold the entire path
! since we check 3 places for it.
integer :: kernel_file !! The unit number for the kernel file
logical :: file_exists !! A variable to say whether
! !! needed file exists
character(len=1000) :: kernel_file_name !! The path to the kernel file.
! !! Although this name must be
! !! "vdW_kernel_table", this variable
! !! is used to hold the entire path
! !! since we check 3 places for it.
!!write(*,*) "Reading kernel table ... "
!! Get the unit number for the kernel file
kernel_file = find_free_unit()
!!
!!
if (TRIM(vdw_table_name)==' ') then
if (inlc==3) then
vdw_table_name='rVV10_kernel_table'
else
vdw_table_name='vdW_kernel_table'
endif
endif
endif
if (allocated(kernel)) then
return
if (allocated(kernel)) return
end if
!! First we check the current directory for the vdW_kernel_table file
!! If it is not found there it is looked for in the pseudopotential
!! directory. If it's not there the default kernel file installed
!! in the PW directory of the PWSCF source is tried. If none of those
!! exist the code crashes.
! ------------------------------------------------------------------
! First we check the current directory for the vdW_kernel_table
! file. If it is not found there, it is looked for in the
! pseudopotential directory. If it's not therei, the default kernel
! file installed in the PW directory of the PWSCF source is tried.
! If none of those exist the code crashes.
kernel_file_name=vdw_table_name
inquire(file=kernel_file_name, exist=file_exists)
!! If the file is found in the current directory we use that one
!! ------------------------------------------------------------------------------------------
! ------------------------------------------------------------------
! If the file is found in the current directory we use that one.
if (.not. file_exists) then
!! No "vdW_kernel_table" file in the current directory. Try the pseudopotential directory
!! -----------------------------------------------------------------------------------------
! ---------------------------------------------------------------
! No "vdW_kernel_table" file in the current directory. Try the
! pseudopotential directory.
kernel_file_name = trim(pseudo_dir)//'/'//vdw_table_name
inquire(file=kernel_file_name, exist=file_exists)
if (.not. file_exists) call errore('read_kernel_table', &
TRIM(vdw_table_name)//' file could be found',1)
if (.not. file_exists) call errore('read_kernel_table', &
TRIM(vdw_table_name)//' file not found',1)
end if
!! Generates the md5 file
! ------------------------------------------------------------------
! Generates the md5 file.
CALL md5_from_file(kernel_file_name, vdw_kernel_md5_cksum)
!! Open the file to read
open(unit=kernel_file, file=kernel_file_name, status='old', form='formatted', action='read')
!! Read in the number of q points used for this kernel file, the
!! number of r points, and the maximum value of the r point
! ------------------------------------------------------------------
! Open the file to read.
open(unit=kernel_file, file=kernel_file_name, status='old', form='formatted', action='read')
! ------------------------------------------------------------------
! Read in the number of q points used for this kernel file, the
! number of r points, and the maximum value of the r point.
read(kernel_file, '(2i5)') Nqs, Nr_points
read(kernel_file, double_format) r_max
allocate( q_mesh(Nqs) )
allocate( kernel(0:Nr_points,Nqs,Nqs), d2phi_dk2(0:Nr_points,Nqs,Nqs) )
!! Read in the values of the q points used to generate this kernel
! ------------------------------------------------------------------
! Read in the values of the q points used to generate this kernel.
read(kernel_file, double_format) q_mesh
!! For each pair of q values, read in the function phi_q1_q2(k).
!! That is, the fourier transformed kernel function assuming q1 and q2
!! for all the values of r used.
!! ----------------------------------------------------------------------------------------------
! ------------------------------------------------------------------
! For each pair of q values, read in the function phi_q1_q2(k).
! That is, the fourier transformed kernel function assuming q1 and
! q2 for all the values of r used.
do q1_i = 1, Nqs
do q2_i = 1, q1_i
@ -187,15 +202,12 @@ CONTAINS
end do
end do
!! ----------------------------------------------------------------------------------------------
!! Again, for each pair of q values (q1 and q2), read in the value
!! of the second derivative of the above mentiond Fourier transformed
!! kernel function phi_alpha_beta(k). These are used for spline
!! interpolation of the Fourier transformed kernel.
!! -----------------------------------------------------------------------------------------------
! ------------------------------------------------------------------
! Again, for each pair of q values (q1 and q2), read in the value of
! the second derivative of the above mentiond Fourier transformed
! kernel function phi_alpha_beta(k). These are used for spline
! interpolation of the Fourier transformed kernel.
do q1_i = 1, Nqs
do q2_i = 1, q1_i
@ -206,23 +218,19 @@ CONTAINS
end do
end do
!! -----------------------------------------------------------------------------------------------
close(kernel_file)
!! Define a few more vaiables useful to some of the subroutines in xc_vdW_DF.f90
!! ------------------------------------------------------------------------------------------------
! ------------------------------------------------------------------
! Define a few more vaiables useful to some of the subroutines in
! xc_vdW_DF.f90.
q_cut = q_mesh(Nqs)
q_min = q_mesh(1)
dk = 2.0D0*pi/r_max
!! ------------------------------------------------------------------------------------------------
end subroutine initialize_kernel_table
!! #################################################################################################
end MODULE kernel_table

View File

@ -1349,12 +1349,11 @@ CONTAINS
! Vdw kernel table
!
IF ( present(inlc) ) THEN
IF ( inlc == 1 .OR. inlc ==2 .OR. inlc == 3 ) THEN
IF ( inlc > 0 ) THEN
IF ( .NOT. PRESENT( vdw_table_name ) .OR. &
.NOT. PRESENT( pseudo_dir ) .OR. &
.NOT. PRESENT( dirname )) &
CALL errore( 'write_xc', &
' variable vdw_table_name not present', 1 )
.NOT. PRESENT( pseudo_dir ) .OR. &
.NOT. PRESENT( dirname )) &
CALL errore( 'write_xc', ' variable vdw_table_name not present', 1 )
CALL iotk_write_dat( ounit, "NON_LOCAL_DF", inlc )
CALL iotk_write_dat( ounit, "VDW_KERNEL_NAME", TRIM(vdw_table_name))
@ -3453,8 +3452,7 @@ CONTAINS
CALL iotk_scan_dat( iunit, "NON_LOCAL_DF", inlc_, FOUND = found )
IF ( found ) THEN
!
IF ( inlc_ == 1 .OR. inlc_ == 2 .OR. inlc_ == 3 ) &
CALL iotk_scan_dat( iunit, "VDW_KERNEL_NAME", vdw_table_name_ )
IF ( inlc_ > 0 ) CALL iotk_scan_dat( iunit, "VDW_KERNEL_NAME", vdw_table_name_ )
!
ELSE
!

File diff suppressed because it is too large Load Diff

View File

@ -139,8 +139,7 @@ and many others. We quote in particular:
built upon previous work by Guido Fratesi (Univ.Milano Bicocca)
and Riccardo Mazzarello (ETHZ-USI Lugano);
\item Matteo Cococcioni (Univ. Minnesota) for DFT+U implementation;
\item Timo Thonhauser's group (Wake Forest University) for vdW-DF and
variants;
\item Timo Thonhauser (WFU) for vdW-DF, svdW-DF, and variants;
\end{itemize}
and the more recent contributors:
\begin{itemize}

File diff suppressed because it is too large Load Diff

View File

@ -30,14 +30,12 @@ subroutine stres_nonloc_dft( rho, rho_core, nspin, sigma_nonloc_dft )
sigma_nonloc_dft(:,:) = 0.d0
inlc = get_inlc()
if (inlc==1 .or. inlc==2) then
if (nspin>2) call errore('stres_vdW_DF', &
'vdW+DF non implemented in spin polarized calculations',1)
if ( inlc==1 .or. inlc==2 .or. inlc==4 .or. inlc==5 .or. inlc==6 ) then
if ( nspin>1 ) call errore ('stres_vdW_DF', 'vdW stress not implemented for nspin > 1',1)
CALL stress_vdW_DF(rho, rho_core, nspin, sigma_nonloc_dft)
elseif (inlc == 3) then
if (nspin>2) call errore('stress_rVV10', &
'rVV10 non implemented with nspin>2',1)
CALL stress_rVV10(rho, rho_core, nspin, sigma_nonloc_dft)
elseif ( inlc == 3 ) then
if ( nspin>2 ) call errore ('stress_rVV10', 'rVV10 stress not implemented for nspin > 2',1)
CALL stress_rVV10(rho, rho_core, nspin, sigma_nonloc_dft)
end if
return

View File

@ -471,10 +471,8 @@ SUBROUTINE print_vdw_info
integer :: inlc
inlc = get_inlc()
if (inlc==1 .or. inlc==2 .or. inlc==3) then
WRITE( stdout, '(/5x,"vdW kernel table read from file ",a)')&
TRIM (vdw_table_name)
if ( inlc > 0 ) then
WRITE( stdout, '(/5x,"vdW kernel table read from file ",a)') TRIM (vdw_table_name)
WRITE( stdout, '(5x,"MD5 check sum: ", a )') vdw_kernel_md5_cksum
endif