29  use, 
intrinsic :: iso_fortran_env
 
   57    integer,                  
public :: vdw_correction = -1
 
   58    logical                          :: self_consistent = .false.
 
   59    type(vdw_ts_t),           
public :: vdw_ts
 
   60    type(dftd3_calc)                 :: vdw_d3
 
   61    real(real64), 
public,       
allocatable :: forces(:, :)
 
   63    real(real64), 
public                    :: stress(3, 3)
 
   74  subroutine xc_vdw_init(this, namespace, space, gr, xc, ions, x_id, c_id)
 
   75    class(xc_vdw_t),         
intent(inout) :: this
 
   76    type(namespace_t),       
intent(in)    :: namespace
 
   77    class(space_t),          
intent(in)    :: space
 
   78    type(grid_t),            
intent(in)    :: gr
 
   79    type(xc_t),              
intent(inout) :: xc
 
   80    type(ions_t),            
intent(in)    :: ions
 
   81    integer,                 
intent(in)    :: x_id, c_id
 
   84    type(dftd3_input) :: d3_input
 
   85    character(len=20) :: d3func_def, d3func
 
  109    call parse_variable(namespace, 
'VDWCorrection', option__vdwcorrection__none, this%vdw_correction)
 
  111    if (this%vdw_correction /= option__vdwcorrection__none) 
then 
  114      select case (this%vdw_correction)
 
  115      case (option__vdwcorrection__vdw_ts)
 
  130      case (option__vdwcorrection__vdw_d3)
 
  131        this%self_consistent = .false.
 
  133        if (space%dim /= 3) 
then 
  134          call messages_write(
'xc_vdw_d3 can only be used in 3-dimensional systems')
 
  138        do iatom = 1, ions%natoms
 
  139          if (.not. ions%atom(iatom)%species%represents_real_atom()) 
then 
  140            call messages_write(
'xc_vdw_d3 is not implemented when non-atomic species are present')
 
  149        if (x_id == option__xcfunctional__gga_x_b88 .and. c_id*
libxc_c_index == option__xcfunctional__gga_c_lyp) 
then 
  152        if (x_id == option__xcfunctional__gga_x_pbe .and. c_id*
libxc_c_index == option__xcfunctional__gga_c_pbe) 
then 
  155        if (x_id == option__xcfunctional__gga_x_pbe_sol .and. c_id*
libxc_c_index == option__xcfunctional__gga_c_pbe_sol) 
then 
  156          d3func_def = 
'pbesol' 
  158        if (c_id*
libxc_c_index == option__xcfunctional__hyb_gga_xc_b3lyp) 
then 
  159          d3func_def = 
'b3-lyp' 
  182        call parse_variable(namespace, 
'VDWD3Functional', d3func_def, d3func)
 
  184        if (d3func == 
'') 
then 
  185          call messages_write(
'Cannot find  a matching parametrization  of DFT-D3 for the current')
 
  187          call messages_write(
'XCFunctional.  Please select a different XCFunctional, or select a')
 
  189          call messages_write(
'functional for DFT-D3 using the <tt>VDWD3Functional</tt> variable.')
 
  193        if (space%periodic_dim /= 0 .and. space%periodic_dim /= 3) 
then 
  194          call messages_write(
'For partially periodic systems,  the xc_vdw_d3 interaction is assumed')
 
  200        call dftd3_init(this%vdw_d3, d3_input, trim(
conf%share)//
'/dftd3/pars.dat')
 
  201        call dftd3_set_functional(this%vdw_d3, 
func = d3func, version = 4, tz = .false.)
 
  208      this%self_consistent = .false.
 
  216    class(
xc_vdw_t),   
intent(inout) :: this
 
  220    select case (this%vdw_correction)
 
  221    case (option__vdwcorrection__vdw_ts)
 
  229  subroutine xc_vdw_calc(this, namespace, space, latt, atom, natoms, pos, gr, st, energy, vxc)
 
  230    class(
xc_vdw_t),                   
intent(inout) :: this
 
  232    type(
space_t),                     
intent(in)    :: space
 
  234    type(
atom_t),                      
intent(in)    :: atom(:)
 
  235    integer,                           
intent(in)    :: natoms
 
  236    real(real64),                      
intent(in)    :: pos(1:space%dim,1:natoms)
 
  237    type(
grid_t),                      
intent(in)    :: gr
 
  239    real(real64),                      
intent(out)   :: energy
 
  240    real(real64),                      
intent(inout) :: vxc(:,:)
 
  242    integer :: ispin, iatom, idir
 
  243    real(real64), 
allocatable :: vxc_vdw(:)
 
  244    integer, 
allocatable :: atnum(:)
 
  245    real(real64) :: rlattice(3, 3)
 
  247    real(real64), 
parameter :: aperiodic_scaling = 1000.0_real64
 
  250    if (this%vdw_correction == option__vdwcorrection__none) 
return 
  254    assert(space%dim == 3)
 
  256    safe_allocate(vxc_vdw(1:gr%np))
 
  257    safe_allocate(this%forces(1:space%dim, 1:natoms))
 
  259    select case (this%vdw_correction)
 
  261    case (option__vdwcorrection__vdw_ts)
 
  263      call vdw_ts_calculate(this%vdw_ts, namespace, space, latt, atom, natoms, pos, &
 
  264        gr, st%d%nspin, st%rho, energy, vxc_vdw, this%forces)
 
  267    case (option__vdwcorrection__vdw_d3)
 
  269      safe_allocate(atnum(1:natoms))
 
  271      atnum = [(nint(atom(iatom)%species%get_z()), iatom=1, natoms)]
 
  273      if (space%is_periodic()) 
then 
  279        rlattice = latt%rlattice(1:3, 1:3)
 
  280        if (space%periodic_dim < 3) 
then 
  281          message(1) = 
"Info: Using DFT-D3 van der Walls corrections for a system with mixed-periodicity," 
  282          message(2) = 
"      but DFTD3 treats system as fully periodic. Octopus will set the DFT-D3" 
  283          message(3) = 
"      lattice vectors along non-periodic dimensions to a suitably large value." 
  286          do idir = space%periodic_dim + 1, 3
 
  287            rlattice(idir,idir) = (maxval(abs(pos(idir,:))) + 
m_one)*aperiodic_scaling
 
  290        call dftd3_pbc_dispersion(this%vdw_d3, pos, atnum, rlattice, energy, this%forces, &
 
  293        call dftd3_dispersion(this%vdw_d3, pos, atnum, energy, this%forces)
 
  297      safe_deallocate_a(atnum)
 
  303    if (this%self_consistent) 
then 
  304      do ispin = 1, st%d%nspin
 
  309    safe_deallocate_a(vxc_vdw)
 
constant times a vector plus a vector
 
real(real64) function func(r1, rn, n, a)
 
real(real64), parameter, public m_zero
 
type(conf_t), public conf
Global instance of Octopus configuration.
 
real(real64), parameter, public m_one
 
This module implements the underlying real-space grid.
 
subroutine, public libvdwxc_set_geometry(this, namespace, space, mesh)
 
subroutine, public messages_warning(no_lines, all_nodes, namespace)
 
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
 
subroutine, public messages_new_line()
 
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
 
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
 
subroutine, public messages_experimental(name, namespace)
 
logical function, public parse_is_defined(namespace, name)
 
subroutine, public vdw_ts_init(this, namespace, ions)
 
subroutine, public vdw_ts_calculate(this, namespace, space, latt, atom, natoms, pos, mesh, nspin, density, energy, potential, force)
Calculate the potential for the Tatchenko-Scheffler vdW correction as described in Phys....
 
subroutine, public vdw_ts_end(this)
 
integer, parameter, public xc_family_libvdwxc
 
integer, parameter, public libxc_c_index
 
integer, parameter, public func_c
 
pure logical function, public in_family(family, xc_families)
 
A module that takes care of xc contribution from vdW interactions.
 
subroutine xc_vdw_end(this)
 
subroutine xc_vdw_init(this, namespace, space, gr, xc, ions, x_id, c_id)
 
subroutine xc_vdw_calc(this, namespace, space, latt, atom, natoms, pos, gr, st, energy, vxc)
 
Description of the grid, containing information on derivatives, stencil, and symmetries.
 
The states_elec_t class contains all electronic wave functions.