29 use,
intrinsic :: iso_fortran_env
58 integer,
public :: vdw_correction = -1
59 logical :: self_consistent = .false.
60 type(vdw_ts_t),
public :: vdw_ts
61 type(dftd3_calc) :: vdw_d3
62 real(real64),
public,
allocatable :: forces(:, :)
64 real(real64),
public :: stress(3, 3)
76 integer(int64),
parameter :: d3_lib_options(5) = [&
77 option__vdwcorrection__vdw_d2, &
78 option__vdwcorrection__vdw_d3_zero_damping, &
79 option__vdwcorrection__vdw_d3_bj, &
80 option__vdwcorrection__vdw_d3m_zero_damping, &
81 option__vdwcorrection__vdw_d3m_bj &
87 subroutine xc_vdw_init(this, namespace, space, gr, xc, ions, x_id, c_id)
88 class(xc_vdw_t),
intent(inout) :: this
89 type(namespace_t),
intent(in) :: namespace
90 class(space_t),
intent(in) :: space
91 type(grid_t),
intent(in) :: gr
92 type(xc_t),
intent(inout) :: xc
93 type(ions_t),
intent(in) :: ions
94 integer,
intent(in) :: x_id, c_id
97 type(dftd3_input) :: d3_input
98 character(len=20) :: d3func_def, d3func
138 call parse_variable(namespace,
'VDWCorrection', option__vdwcorrection__none, this%vdw_correction)
140 if (this%vdw_correction == option__vdwcorrection__none)
then
141 this%self_consistent = .false.
148 if( this%vdw_correction == option__vdwcorrection__vdw_ts)
then
164 this%self_consistent = .false.
166 if (space%dim /= 3)
then
167 call messages_write(
'xc_vdw_d3 can only be used in 3-dimensional systems')
171 do iatom = 1, ions%natoms
172 if (.not. ions%atom(iatom)%species%represents_real_atom())
then
173 call messages_write(
'xc_vdw_d3 is not implemented when non-atomic species are present')
182 if (x_id == option__xcfunctional__gga_x_b88 .and. c_id*
libxc_c_index == option__xcfunctional__gga_c_lyp)
then
185 if (x_id == option__xcfunctional__gga_x_pbe .and. c_id*
libxc_c_index == option__xcfunctional__gga_c_pbe)
then
188 if (x_id == option__xcfunctional__gga_x_pbe_sol .and. c_id*
libxc_c_index == option__xcfunctional__gga_c_pbe_sol)
then
189 d3func_def =
'pbesol'
191 if (c_id*
libxc_c_index == option__xcfunctional__hyb_gga_xc_b3lyp)
then
192 d3func_def =
'b3-lyp'
194 if (c_id*
libxc_c_index == option__xcfunctional__hyb_gga_xc_pbeh)
then
215 call parse_variable(namespace,
'VDWD3Functional', d3func_def, d3func)
217 if (d3func ==
'')
then
218 call messages_write(
'Cannot find a matching parametrization of DFT-D3 for the current')
220 call messages_write(
'XCFunctional. Please select a different XCFunctional, or select a')
222 call messages_write(
'functional for DFT-D3 using the <tt>VDWD3Functional</tt> variable.')
226 if (space%periodic_dim /= 0 .and. space%periodic_dim /= 3)
then
227 call messages_write(
'For partially periodic systems, the xc_vdw_d3 interaction is assumed')
233 call dftd3_init(this%vdw_d3, d3_input, trim(
conf%share)//
'/dftd3/pars.dat')
234 call dftd3_set_functional(this%vdw_d3,
func = d3func, version = this%d3_version(), tz = .false.)
245 integer :: d3_version
249 select case (this%vdw_correction)
250 case (option__vdwcorrection__vdw_d2)
252 case (option__vdwcorrection__vdw_d3_zero_damping)
254 case (option__vdwcorrection__vdw_d3_bj)
256 case (option__vdwcorrection__vdw_d3m_zero_damping)
258 case (option__vdwcorrection__vdw_d3m_bj)
271 class(
xc_vdw_t),
intent(inout) :: this
275 select case (this%vdw_correction)
276 case (option__vdwcorrection__vdw_ts)
284 subroutine xc_vdw_calc(this, namespace, space, latt, atom, natoms, pos, gr, st, energy, vxc)
285 class(
xc_vdw_t),
intent(inout) :: this
287 type(
space_t),
intent(in) :: space
289 type(
atom_t),
intent(in) :: atom(:)
290 integer,
intent(in) :: natoms
291 real(real64),
intent(in) :: pos(1:space%dim,1:natoms)
292 type(
grid_t),
intent(in) :: gr
294 real(real64),
intent(out) :: energy
295 real(real64),
contiguous,
intent(inout) :: vxc(:,:)
297 integer :: ispin, iatom, idir
298 real(real64),
allocatable :: vxc_vdw(:)
299 integer,
allocatable :: atnum(:)
300 real(real64) :: rlattice(3, 3)
302 real(real64),
parameter :: aperiodic_scaling = 1000.0_real64
305 if (this%vdw_correction == option__vdwcorrection__none)
return
309 assert(space%dim == 3)
311 safe_allocate(vxc_vdw(1:gr%np))
312 safe_allocate(this%forces(1:space%dim, 1:natoms))
314 if(this%vdw_correction == option__vdwcorrection__vdw_ts)
then
316 call vdw_ts_calculate(this%vdw_ts, namespace, space, latt, atom, natoms, pos, &
317 gr, st%d%nspin, st%rho, energy, vxc_vdw, this%forces)
320 elseif(any(this%vdw_correction == d3_lib_options))
then
322 safe_allocate(atnum(1:natoms))
324 atnum = [(nint(atom(iatom)%species%get_z()), iatom=1, natoms)]
326 if (space%is_periodic())
then
332 rlattice = latt%rlattice(1:3, 1:3)
333 if (space%periodic_dim < 3)
then
334 message(1) =
"Info: Using DFT-D3 van der Walls corrections for a system with mixed-periodicity,"
335 message(2) =
" but DFTD3 treats system as fully periodic. Octopus will set the DFT-D3"
336 message(3) =
" lattice vectors along non-periodic dimensions to a suitably large value."
339 do idir = space%periodic_dim + 1, 3
340 rlattice(idir,idir) = (maxval(abs(pos(idir,:))) +
m_one)*aperiodic_scaling
343 call dftd3_pbc_dispersion(this%vdw_d3, pos, atnum, rlattice, energy, this%forces, &
346 call dftd3_dispersion(this%vdw_d3, pos, atnum, energy, this%forces)
350 safe_deallocate_a(atnum)
356 if (this%self_consistent)
then
357 do ispin = 1, st%d%nspin
362 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)
integer, parameter, private libxc_c_index
Tkatchenko-Scheffler pairwise method for van der Waals (vdW, dispersion) interactions.
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 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)
Initialize a xc_vdw_t instance.
integer function xc_vdw_octopus_input_to_version(this)
Map Octopus''s VDWCORRECTION input option to the DFTD3 library''s input option "version".
integer(int64), dimension(5), parameter, public d3_lib_options
VDWCORRECTION options that correspond to the DFT-D3 library.
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.