33 integer,
parameter :: &
34 LIBVDWXC_MODE_AUTO = 1, &
52 integer,
pointer :: libvdwxc_ptr
55 type(mesh_cube_parallel_map_t) :: mesh_cube_map
58 real(real64),
public :: energy
59 real(real64) :: vdw_factor
63 include
"vdwxcfort.f90"
69 type(libvdwxc_t),
intent(out) :: libvdwxc
70 type(namespace_t),
intent(in) :: namespace
71 integer,
intent(in) :: functional
75 call vdwxc_new(functional, libvdwxc%libvdwxc_ptr)
77 message(1) =
"Octopus not compiled with libvdwxc"
80 assert(
associated(libvdwxc%libvdwxc_ptr))
81 libvdwxc%functional = functional
89 call parse_variable(namespace,
'libvdwxcDebug', .false., libvdwxc%debug)
104 type(libvdwxc_t),
intent(in) :: this
108 call vdwxc_print(this%libvdwxc_ptr)
115 type(libvdwxc_t),
intent(in) :: this
116 integer,
optional,
intent(in) :: iunit
117 type(namespace_t),
optional,
intent(in) :: namespace
121 write(
message(1),
'(2x,a)')
'Correlation'
122 if (this%functional == 1)
then
123 write(
message(2),
'(4x,a)')
'vdW-DF from libvdwxc'
124 else if (this%functional == 2)
then
125 write(
message(2),
'(4x,a)')
'vdW-DF2 from libvdwxc'
126 else if (this%functional == 3)
then
127 write(
message(2),
'(4x,a)')
'vdW-DF-cx from libvdwxc'
129 write(
message(2),
'(4x,a)')
'unknown libvdwxc functional'
139 class(
space_t),
intent(in) :: space
140 class(
mesh_t),
intent(in) :: mesh
143 integer :: libvdwxc_mode
156 libvdwxc_mode = libvdwxc_mode_auto
172 call parse_variable(namespace,
'libvdwxcMode', libvdwxc_mode_auto, libvdwxc_mode)
174 if (libvdwxc_mode == libvdwxc_mode_auto)
then
175 if (mesh%mpi_grp%size == 1)
then
184 blocksize = mesh%idx%ll(3) / mesh%mpi_grp%size
185 if (mod(mesh%idx%ll(3), mesh%mpi_grp%size) /= 0)
then
186 blocksize = blocksize + 1
191 cube_space%dim = space%dim
192 cube_space%periodic_dim = space%dim
195 call cube_init(this%cube, mesh%idx%ll, namespace, cube_space, mesh%spacing, &
199 call cube_init(this%cube, mesh%idx%ll, namespace, cube_space, mesh%spacing, &
200 mesh%coord_system, mpi_grp = mesh%mpi_grp, &
201 need_partition = .
true., blocksize = blocksize)
211 call vdwxc_set_unit_cell(this%libvdwxc_ptr, &
212 this%cube%rs_n_global(3), this%cube%rs_n_global(2), this%cube%rs_n_global(1), &
213 this%cube%latt%rlattice(3, 3), this%cube%latt%rlattice(2, 3), this%cube%latt%rlattice(1, 3), &
214 this%cube%latt%rlattice(3, 2), this%cube%latt%rlattice(2, 2), this%cube%latt%rlattice(1, 2), &
215 this%cube%latt%rlattice(3, 1), this%cube%latt%rlattice(2, 1), this%cube%latt%rlattice(1, 1))
218 call vdwxc_init_serial(this%libvdwxc_ptr)
220#ifdef HAVE_LIBVDWXC_MPI
221 call vdwxc_init_mpi(this%libvdwxc_ptr, mesh%mpi_grp%comm%MPI_VAL)
223 message(1) =
"libvdwxc was not compiled with MPI"
224 message(2) =
"Recompile libvdwxc with MPI for vdW with domain decomposition"
228 call vdwxc_print(this%libvdwxc_ptr)
237 class(
space_t),
intent(in) :: space
238 real(real64),
dimension(:,:),
contiguous,
intent(inout) :: rho
239 real(real64),
dimension(:,:,:),
contiguous,
intent(in) :: gradrho
240 real(real64),
dimension(:,:),
contiguous,
intent(inout) :: dedd
241 real(real64),
dimension(:,:,:),
contiguous,
intent(inout) :: dedgd
245 real(real64),
allocatable :: workbuffer(:)
246 real(real64),
allocatable :: cube_rho(:,:,:), cube_sigma(:,:,:), cube_dedrho(:,:,:), cube_dedsigma(:,:,:)
247 real(real64),
dimension(3) :: energy_and_integrals_buffer
249 integer :: ii, is, idir
253 assert(
size(rho, 2) == 1)
254 assert(
size(gradrho, 3) == 1)
255 assert(
size(dedd, 2) == 1)
256 assert(
size(dedgd, 3) == 1)
282 safe_allocate(workbuffer(1:this%mesh%np))
283 safe_allocate(cube_rho(1:this%cube%rs_n(1), 1:this%cube%rs_n(2), 1:this%cube%rs_n(3)))
284 safe_allocate(cube_sigma(1:this%cube%rs_n(1), 1:this%cube%rs_n(2), 1:this%cube%rs_n(3)))
285 safe_allocate(cube_dedrho(1:this%cube%rs_n(1), 1:this%cube%rs_n(2), 1:this%cube%rs_n(3)))
286 safe_allocate(cube_dedsigma(1:this%cube%rs_n(1), 1:this%cube%rs_n(2), 1:this%cube%rs_n(3)))
288 workbuffer(:) = sum(gradrho(:, :, 1)**2, 2)
302 call tocube(rho(:, 1), cube_rho)
303 call tocube(workbuffer, cube_sigma)
307 call vdwxc_calculate(this%libvdwxc_ptr, cube_rho, cube_sigma, cube_dedrho, cube_dedsigma, this%energy)
309 this%energy = this%energy * this%vdw_factor
310 cube_dedrho = cube_dedrho * this%vdw_factor
311 cube_dedsigma = cube_dedsigma * this%vdw_factor
313 call fromcube(cube_dedrho, workbuffer)
319 call fromcube(cube_dedsigma, workbuffer)
323 do ii = 1, this%mesh%np
324 dedgd(ii, :, 1) = dedgd(ii, :, 1) +
m_two * workbuffer(ii) * gradrho(ii, :, 1)
327 energy_and_integrals_buffer(1) = this%energy
331 do is = 1,
size(rho, 2)
332 do ii = 1, this%mesh%np
333 vsum = vsum + rho(ii, is) * dedd(ii, is)
337 energy_and_integrals_buffer(2) = vsum * this%mesh%volume_element
341 do idir = 1,
size(gradrho, 3)
342 do is = 1,
size(gradrho, 2)
343 do ii = 1, this%mesh%np
344 vsum = vsum + gradrho(ii, is, idir) * dedgd(ii, is, idir)
349 energy_and_integrals_buffer(3) = vsum * this%mesh%volume_element
351 call this%mesh%mpi_grp%allreduce_inplace(energy_and_integrals_buffer(1), 3, mpi_double_precision, mpi_sum)
352 this%energy = energy_and_integrals_buffer(1)
353 write(
message(1),
'(a,f18.10,a)')
'libvdwxc non-local correlation energy: ', energy_and_integrals_buffer(1),
' Ha'
354 write(
message(2),
'(a,f18.10)')
' n-dedn integral: ', energy_and_integrals_buffer(2)
355 write(
message(3),
'(a,f18.10)')
' gradn-dedgradn integral: ', energy_and_integrals_buffer(3)
358 safe_deallocate_a(workbuffer)
359 safe_deallocate_a(cube_rho)
360 safe_deallocate_a(cube_sigma)
361 safe_deallocate_a(cube_dedrho)
362 safe_deallocate_a(cube_dedsigma)
369 subroutine tocube(array, cubearray)
370 real(real64),
contiguous,
intent(in) :: array(:)
371 real(real64),
intent(out) :: cubearray(:,:,:)
375 if (this%cube%parallel_in_domains)
then
380 cubearray(:,:,:) = cf%dRS
384 subroutine fromcube(cubearray, array)
385 real(real64),
intent(in) :: cubearray(:,:,:)
386 real(real64),
contiguous,
intent(out) :: array(:)
390 if (this%cube%parallel_in_domains)
then
399 real(real64),
intent(in) :: arr(:)
400 character(len=*),
intent(in) :: fname
404 fname, namespace, space, this%mesh, arr,
unit_one, ierr)
414 call vdwxc_finalize(this%libvdwxc_ptr)
constant times a vector plus a vector
subroutine libvdwxc_write_array(arr, fname)
subroutine fromcube(cubearray, array)
subroutine tocube(array, cubearray)
subroutine, public dmesh_to_cube(mesh, mf, cube, cf)
Convert a function from the mesh to the cube.
subroutine, public dcube_to_mesh(cube, cf, mesh, mf)
Convert a function from the cube to the mesh.
subroutine, public dcube_function_alloc_rs(cube, cf, in_device, force_alloc)
Allocates locally the real space grid, if PFFT library is not used. Otherwise, it assigns the PFFT re...
subroutine, public dcube_function_free_rs(cube, cf)
Deallocates the real space grid.
subroutine, public dmesh_to_cube_parallel(mesh, mf, cube, cf, map)
The next two subroutines convert a function between the normal mesh and the cube in parallel.
subroutine, public dcube_to_mesh_parallel(cube, cf, mesh, mf, map)
subroutine, public cube_init(cube, nn, namespace, space, spacing, coord_system, fft_type, fft_library, dont_optimize, nn_out, mpi_grp, need_partition, tp_enlarge, blocksize)
subroutine, public cube_end(cube)
subroutine, public cube_init_cube_map(cube, mesh)
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
subroutine, public dio_function_output(how, dir, fname, namespace, space, mesh, ff, unit, ierr, pos, atoms, grp, root)
Top-level IO routine for functions defined on the mesh.
subroutine, public libvdwxc_end(this)
subroutine, public libvdwxc_init(libvdwxc, namespace, functional)
subroutine, public libvdwxc_write_info(this, iunit, namespace)
integer, parameter libvdwxc_mode_serial
integer, parameter libvdwxc_mode_mpi
subroutine, public libvdwxc_print(this)
subroutine, public libvdwxc_set_geometry(this, namespace, space, mesh)
subroutine, public libvdwxc_calculate(this, namespace, space, rho, gradrho, dedd, dedgd)
subroutine, public mesh_cube_parallel_map_end(this)
subroutine, public mesh_cube_parallel_map_init(this, mesh, cube)
This module defines the meshes, which are used in Octopus.
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_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
The low level module to work with the PFFT library. http:
This module defines the unit system, used for input and output.
type(unit_t), public unit_one
some special units required for particular quantities
Describes mesh distribution to nodes.