32 integer,
parameter :: &
33 LIBVDWXC_MODE_AUTO = 1, &
51 integer,
pointer :: libvdwxc_ptr
54 type(mesh_cube_parallel_map_t) :: mesh_cube_map
57 real(real64),
public :: energy
58 real(real64) :: vdw_factor
62 include
"vdwxcfort.f90"
68 type(libvdwxc_t),
intent(out) :: libvdwxc
69 type(namespace_t),
intent(in) :: namespace
70 integer,
intent(in) :: functional
74 call vdwxc_new(functional, libvdwxc%libvdwxc_ptr)
76 message(1) =
"Octopus not compiled with libvdwxc"
79 assert(
associated(libvdwxc%libvdwxc_ptr))
80 libvdwxc%functional = functional
88 call parse_variable(namespace,
'libvdwxcDebug', .false., libvdwxc%debug)
103 type(libvdwxc_t),
intent(in) :: this
107 call vdwxc_print(this%libvdwxc_ptr)
114 type(libvdwxc_t),
intent(in) :: this
115 integer,
optional,
intent(in) :: iunit
116 type(namespace_t),
optional,
intent(in) :: namespace
120 write(
message(1),
'(2x,a)')
'Correlation'
121 if (this%functional == 1)
then
122 write(
message(2),
'(4x,a)')
'vdW-DF from libvdwxc'
123 else if (this%functional == 2)
then
124 write(
message(2),
'(4x,a)')
'vdW-DF2 from libvdwxc'
125 else if (this%functional == 3)
then
126 write(
message(2),
'(4x,a)')
'vdW-DF-cx from libvdwxc'
128 write(
message(2),
'(4x,a)')
'unknown libvdwxc functional'
138 class(
space_t),
intent(in) :: space
139 class(
mesh_t),
intent(in) :: mesh
142 integer :: libvdwxc_mode
143 type(space_t) :: cube_space
155 libvdwxc_mode = libvdwxc_mode_auto
171 call parse_variable(namespace,
'libvdwxcMode', libvdwxc_mode_auto, libvdwxc_mode)
173 if (libvdwxc_mode == libvdwxc_mode_auto)
then
174 if (mesh%mpi_grp%size == 1)
then
183 blocksize = mesh%idx%ll(3) / mesh%mpi_grp%size
184 if (mod(mesh%idx%ll(3), mesh%mpi_grp%size) /= 0)
then
185 blocksize = blocksize + 1
190 cube_space%dim = space%dim
191 cube_space%periodic_dim = space%dim
194 call cube_init(this%cube, mesh%idx%ll, namespace, cube_space, mesh%spacing, &
198 call cube_init(this%cube, mesh%idx%ll, namespace, cube_space, mesh%spacing, &
199 mesh%coord_system, mpi_grp = mesh%mpi_grp, &
200 need_partition = .
true., blocksize = blocksize)
210 call vdwxc_set_unit_cell(this%libvdwxc_ptr, &
211 this%cube%rs_n_global(3), this%cube%rs_n_global(2), this%cube%rs_n_global(1), &
212 this%cube%latt%rlattice(3, 3), this%cube%latt%rlattice(2, 3), this%cube%latt%rlattice(1, 3), &
213 this%cube%latt%rlattice(3, 2), this%cube%latt%rlattice(2, 2), this%cube%latt%rlattice(1, 2), &
214 this%cube%latt%rlattice(3, 1), this%cube%latt%rlattice(2, 1), this%cube%latt%rlattice(1, 1))
217 call vdwxc_init_serial(this%libvdwxc_ptr)
219#ifdef HAVE_LIBVDWXC_MPI
220 call vdwxc_init_mpi(this%libvdwxc_ptr, mesh%mpi_grp%comm%MPI_VAL)
222 message(1) =
"libvdwxc was not compiled with MPI"
223 message(2) =
"Recompile libvdwxc with MPI for vdW with domain decomposition"
227 call vdwxc_print(this%libvdwxc_ptr)
236 class(
space_t),
intent(in) :: space
237 real(real64),
dimension(:,:),
contiguous,
intent(inout) :: rho
238 real(real64),
dimension(:,:,:),
contiguous,
intent(in) :: gradrho
239 real(real64),
dimension(:,:),
contiguous,
intent(inout) :: dedd
240 real(real64),
dimension(:,:,:),
contiguous,
intent(inout) :: dedgd
244 real(real64),
allocatable :: workbuffer(:)
245 real(real64),
allocatable :: cube_rho(:,:,:), cube_sigma(:,:,:), cube_dedrho(:,:,:), cube_dedsigma(:,:,:)
246 real(real64),
dimension(3) :: energy_and_integrals_buffer
251 assert(
size(rho, 2) == 1)
252 assert(
size(gradrho, 3) == 1)
253 assert(
size(dedd, 2) == 1)
254 assert(
size(dedgd, 3) == 1)
280 safe_allocate(workbuffer(1:this%mesh%np))
281 safe_allocate(cube_rho(1:this%cube%rs_n(1), 1:this%cube%rs_n(2), 1:this%cube%rs_n(3)))
282 safe_allocate(cube_sigma(1:this%cube%rs_n(1), 1:this%cube%rs_n(2), 1:this%cube%rs_n(3)))
283 safe_allocate(cube_dedrho(1:this%cube%rs_n(1), 1:this%cube%rs_n(2), 1:this%cube%rs_n(3)))
284 safe_allocate(cube_dedsigma(1:this%cube%rs_n(1), 1:this%cube%rs_n(2), 1:this%cube%rs_n(3)))
286 workbuffer(:) = sum(gradrho(:, :, 1)**2, 2)
300 call tocube(rho(:, 1), cube_rho)
301 call tocube(workbuffer, cube_sigma)
305 call vdwxc_calculate(this%libvdwxc_ptr, cube_rho, cube_sigma, cube_dedrho, cube_dedsigma, this%energy)
307 this%energy = this%energy * this%vdw_factor
308 cube_dedrho = cube_dedrho * this%vdw_factor
309 cube_dedsigma = cube_dedsigma * this%vdw_factor
311 call fromcube(cube_dedrho, workbuffer)
316 dedd(1:this%mesh%np, 1) = dedd(1:this%mesh%np, 1) + workbuffer
317 call fromcube(cube_dedsigma, workbuffer)
321 do ii = 1, this%mesh%np
322 dedgd(ii, :, 1) = dedgd(ii, :, 1) +
m_two * workbuffer(ii) * gradrho(ii, :, 1)
325 energy_and_integrals_buffer(1) = this%energy
326 energy_and_integrals_buffer(2) = sum(rho(1:this%mesh%np,:) * dedd(1:this%mesh%np,:)) * this%mesh%volume_element
327 energy_and_integrals_buffer(3) = sum(gradrho(1:this%mesh%np,:,:) * dedgd(1:this%mesh%np,:,:)) * this%mesh%volume_element
329 call this%mesh%mpi_grp%allreduce_inplace(energy_and_integrals_buffer(1), 3, mpi_double_precision, mpi_sum)
330 this%energy = energy_and_integrals_buffer(1)
331 write(
message(1),
'(a,f18.10,a)')
'libvdwxc non-local correlation energy: ', energy_and_integrals_buffer(1),
' Ha'
332 write(
message(2),
'(a,f18.10)')
' n-dedn integral: ', energy_and_integrals_buffer(2)
333 write(
message(3),
'(a,f18.10)')
' gradn-dedgradn integral: ', energy_and_integrals_buffer(3)
336 safe_deallocate_a(workbuffer)
337 safe_deallocate_a(cube_rho)
338 safe_deallocate_a(cube_sigma)
339 safe_deallocate_a(cube_dedrho)
340 safe_deallocate_a(cube_dedsigma)
347 subroutine tocube(array, cubearray)
348 real(real64),
contiguous,
intent(in) :: array(:)
349 real(real64),
intent(out) :: cubearray(:,:,:)
353 if (this%cube%parallel_in_domains)
then
358 cubearray(:,:,:) = cf%dRS
362 subroutine fromcube(cubearray, array)
363 real(real64),
intent(in) :: cubearray(:,:,:)
364 real(real64),
contiguous,
intent(out) :: array(:)
368 if (this%cube%parallel_in_domains)
then
377 real(real64),
intent(in) :: arr(:)
378 character(len=*),
intent(in) :: fname
382 fname, namespace, space, this%mesh, arr,
unit_one, ierr)
392 call vdwxc_finalize(this%libvdwxc_ptr)
subroutine libvdwxc_write_array(arr, fname)
subroutine fromcube(cubearray, array)
subroutine tocube(array, cubearray)
subroutine, public dmesh_to_cube(mesh, mf, cube, cf)
The next two subroutines convert a function between the normal mesh and the cube.
subroutine, public dcube_to_mesh(cube, cf, mesh, mf)
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.
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, 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.