Octopus
exchange_operator.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2018 M. Marques, A. Castro, A. Rubio, G. Bertsch, N. Tancogne-Dejean
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
22 use accel_oct_m
24 use batch_oct_m
26 use blas_oct_m
27 use comm_oct_m
28 use debug_oct_m
31 use fft_oct_m, only: fftlib_accel
33 use global_oct_m
34 use grid_oct_m
39 use math_oct_m
40 use mesh_oct_m
44 use mpi_oct_m
48 use parser_oct_m
49 use phase_oct_m
54 use space_oct_m
64 use types_oct_m
65 use unit_oct_m
68 use xc_cam_oct_m
69
70 implicit none
71
72 private
73 public :: &
93
94 type ace_t
95 integer :: nst
96 real(real64), allocatable :: dchi(:,:,:,:)
97 complex(real64), allocatable :: zchi(:,:,:,:)
98 type(wfs_elec_t), allocatable :: chib(:)
99 ! one batch per k-point (kpt%start:kpt%end), used to
100 ! apply the operator with GEMMs while keeping the
101 ! wavefunctions resident on the GPU. dchi/zchi above
102 ! remain the reference host copy.
103 contains
104 procedure :: init => ace_init
105 procedure :: end => ace_end
106 procedure :: write_info => ace_write_info
107 end type ace_t
108
109
111 type(states_elec_t), public, pointer :: st => null()
112 type(xc_cam_t) :: cam
113 type(poisson_t) :: psolver
114 type(singularity_t) :: singul
115 logical :: useACE
116 logical :: with_isdf
117 logical :: compute_single_precision = .false.
118 type(ACE_t) :: ace
119 type(isdf_options_t) :: isdf
120 contains
121 procedure :: write_info => exchange_operator_write_info
122 end type exchange_operator_t
123
124
125 type(fourier_space_op_t) :: coulb
126 ! Saved as we avoid then to recompute it,
127 ! for instance in the case of CAM functionals in isolated systems
128
132 type(states_elec_t) :: st_single_shadow, xst_single_shadow
133 logical :: single_shadows_init = .false.
134 integer :: single_shadows_np = 0
135
136 real(real64), parameter, private :: TOL_EXX_WEIGHT = 1.0e-3_real64
137
138contains
139
141 subroutine ace_init(this, namespace, st)
142 class(ACE_t), intent(inout) :: this
143 type(namespace_t), intent(in) :: namespace
144 type(states_elec_t), intent(in ) :: st
145
146 push_sub(ace_init)
147
148 !%Variable ACESize
149 !%Type integer
150 !%Default All states
151 !%Section Hamiltonian
152 !%Description
153 !% (Experimental) The number of ACE projection vectors (i.e. the size of the test-orbital set) and hence the dimension of the
154 !% subspace on which the low-rank ACE operator is (approximately) exact. By default, Octopus sets this to the
155 !% number of states requested for a calculation (all states), which is essential when the band gap is of interest.
156 !% For development purposes, if only occupied states are required, the user can set this value manually.
157 !% For more information, see Lin, J. Chem. Theory Comput. 2016, 12, 2242.
158 !%End
159 call parse_variable(namespace, 'ACESize', st%nst, this%nst)
160
161 if (this%nst > st%nst) then
162 call messages_input_error(namespace, 'ACESize', "Exceeds the total number of states available")
163 endif
164
165 if (this%nst < st%nst) then
166 call messages_experimental("Adaptively-compressed exchange defined with a subset of states", namespace=namespace)
167 endif
168
169 if (this%nst * st%smear%el_per_state < st%qtot) then
170 write(message(1),'(a)') "ACESize should at least equal the number of occupied states."
171 call messages_warning(1, namespace=namespace)
172 endif
173
174 ! dchi/zchi are allocated at their point of use because at this point there is
175 ! nothing to indicate whether one needs dchi or zchi
176
177 pop_sub(ace_init)
178
179 end subroutine ace_init
180
182 subroutine ace_end(this)
183 class(ACE_t), intent(inout) :: this
184
185 integer :: ik
186
187 push_sub(ace_end)
188
189 this%nst = 0
190 safe_deallocate_a(this%dchi)
191 safe_deallocate_a(this%zchi)
193 if (allocated(this%chib)) then
194 do ik = lbound(this%chib, 1), ubound(this%chib, 1)
195 call this%chib(ik)%end()
196 end do
197 safe_deallocate_a(this%chib)
198 end if
200 pop_sub(ace_end)
202 end subroutine ace_end
203
204 subroutine ace_write_info(this, namespace)
205 class(ACE_t), intent(in) :: this
206 type(namespace_t), intent(in) :: namespace
210 call messages_print_var_value("Dimension of the subspace in which the low-rank ACE operator is"// &
211 & " approximately exact (ACESize)", this%nst, namespace=namespace)
215 end subroutine ace_write_info
217 subroutine exchange_operator_init(this, namespace, space, st, der, mc, stencil, kpoints, cam)
218 type(exchange_operator_t), intent(inout) :: this
219 type(namespace_t), intent(in) :: namespace
220 class(space_t), intent(in) :: space
221 type(states_elec_t), intent(in) :: st
222 type(derivatives_t), intent(in) :: der
223 type(multicomm_t), intent(in) :: mc
224 type(stencil_t), intent(in) :: stencil
225 type(kpoints_t), intent(in) :: kpoints
226 type(xc_cam_t), intent(in) :: cam
230 !%Variable AdaptivelyCompressedExchange
231 !%Type logical
232 !%Default true
233 !%Section Hamiltonian
234 !%Description
235 !% If set to yes, Octopus will use the adaptively compressed exchange
236 !% operator (ACE) for HF and hybrid calculations, as defined in
237 !% Lin, J. Chem. Theory Comput. 2016, 12, 2242.
238 !%
239 !% This is currently ignored for TheoryLevel = rdmft
240 !%End
241 call parse_variable(namespace, 'AdaptivelyCompressedExchange', .true., this%useACE)
242 call messages_print_var_value('AdaptivelyCompressedExchange', this%useACE)
243
244 !%Variable ExchangeSinglePrecision
245 !%Type logical
246 !%Default no
247 !%Section Hamiltonian
248 !%Description
249 !% If set to yes, the computation of the exchange potentials in
250 !% <tt>exchange_operator_compute_potentials</tt> is performed in single
251 !% precision: the local states are copied to a single-precision shadow and
252 !% the codensities, the Poisson solves and the accumulation are all done in
253 !% single precision, before the result is converted back to double precision.
254 !% This trades some accuracy for speed and reduced memory and communication
255 !% traffic. State-, k-point- and domain-parallel runs are all supported.
256 !%
257 !% Since the whole Poisson solver of the exchange operator is then set up in single
258 !% precision, this requires <tt>AdaptivelyCompressedExchange = yes</tt>, <tt>ACEWithISDF = no</tt>
259 !% and a batch-capable FFT Poisson solver (the CPU FFTW solver or cuFFT/rocFFT for GPUs; the
260 !% multipole-corrected kernel and the non-FFT solvers have no single-precision variant).
261 !% It is incompatible with RDMFT, with the BerkeleyGW output and with the two-body
262 !% matrix-element output, which need the exchange operator in double precision.
263 !%
264 !% Both cube types are supported. The FFT cube is sized once, when the Hamiltonian is
265 !% built, so a run whose ground state is real (a finite or Gamma-only system) keeps a
266 !% real cube even after a time propagation has made the states complex. The complex
267 !% codensities are then transformed as their real and imaginary parts separately, in
268 !% single precision just as in double.
269 !%End
270 call parse_variable(namespace, 'ExchangeSinglePrecision', .false., this%compute_single_precision)
271 call messages_print_var_value('ExchangeSinglePrecision', this%compute_single_precision)
272
273 !%Variable ACEWithISDF
274 !%Type logical
275 !%Default no
276 !%Section ISDF
277 !%Description
278 !% If set to yes, Octopus will use interpolative separable density fitting (ISDF)
279 !% to accelerate the calculation of adaptively compressed exchange in hybrid
280 !% functionals. For more details, please refer to J.Chem.TheoryComput.2017, 13, 5420-5431.
281 !% ISDF is currently only implemented for spin-unpolarized, molecular systems.
282 !%End
283 call parse_variable(namespace, 'ACEWithISDF', .false., this%with_isdf)
284
285 if (this%with_isdf .and. .not. this%useACE) then
286 call messages_input_error(namespace, 'ACEWithISDF', &
287 '"ACEWithISDF = yes" must be used with "AdaptivelyCompressedExchange = yes"')
288 endif
289
290 ! Objs initialised by exchange constructor
291 if (this%useACE) then
292 call this%ace%init(namespace, st)
293 if (this%with_isdf) call this%isdf%init(namespace, space, der%mesh, this%ace%nst)
294 endif
295 call singularity_init(this%singul, namespace, space, st, kpoints)
296 ! exchange_operator_compute_potentials solves the codensities of a whole state block in one
297 ! batched call, so size the cube to hold one block. The active count per call (psib%nst) may be
298 ! smaller than the capacity (the last/partial block), and solvers that cannot batch fall back to
299 ! a per-function loop; both are handled inside X(poisson_solve_batch).
300 call poisson_init(this%psolver, namespace, space, der, mc, stencil, st%qtot, &
301 force_serial = .true., verbose = .false., force_cmplx = .not. states_are_real(st), &
302 fft_batch_size = st%block_size, single_precision = this%compute_single_precision)
303
304 ! Single precision requires a batch-capable solver: there is no single-precision
305 ! variant of the non-FFT solvers nor of the multipole-corrected FFT kernel, so the
306 ! per-function fallback of X(poisson_solve_batch) has no single-precision solver to
307 ! call. poisson_is_batch_capable covers both the host and the accelerated FFT path
308 ! (poisson_is_device_batch_capable implies it).
309 ! ACE is required as well: the solver above is now single precision, and without ACE
310 ! the Hamiltonian application (exchange_operator_apply_standard) would use that very
311 ! same solver in double precision. ISDF also solves with it in double precision.
312 if (this%compute_single_precision .and. &
313 .not. (this%useACE .and. .not. this%with_isdf .and. poisson_is_batch_capable(this%psolver))) then
314 call messages_not_implemented("ExchangeSinglePrecision without a batched FFT exchange path " // &
315 "(needs AdaptivelyCompressedExchange = yes, ACEWithISDF = no and an FFT Poisson solver " // &
316 "with a batch-capable kernel)", namespace=namespace)
317 end if
318
319 ! Objs initialised by the caller
320 this%cam = cam
321
323 end subroutine exchange_operator_init
324
325 subroutine exchange_operator_reinit(this, cam, st)
326 type(exchange_operator_t), intent(inout) :: this
327 type(xc_cam_t), intent(in ) :: cam
328 type(states_elec_t), target, optional, intent(in ) :: st
329
331
332 if (present(st)) then
333 this%st => st
334 end if
335
336 this%cam = cam
337
339 end subroutine exchange_operator_reinit
340
341 subroutine exchange_operator_end(this)
342 type(exchange_operator_t), intent(inout) :: this
343
344 push_sub(exchange_operator_end)
345
346 if (associated(this%st) .and. .not. this%useACE) then
348 call states_elec_end(this%st)
349 safe_deallocate_p(this%st)
350 end if
351 nullify(this%st)
352
353 if (single_shadows_init) then
354 call states_elec_end(st_single_shadow)
355 call states_elec_end(xst_single_shadow)
356 single_shadows_init = .false.
357 single_shadows_np = 0
358 end if
359
360 call this%ace%end()
361 call singularity_end(this%singul)
362 call coulb%end()
363 call poisson_end(this%psolver)
364 call this%isdf%end()
365
366 pop_sub(exchange_operator_end)
367 end subroutine exchange_operator_end
368
369 subroutine exchange_operator_rdmft_occ_apply(this, mesh, hpsib)
370 type(exchange_operator_t), intent(in) :: this
371 type(mesh_t), intent(in) :: mesh
372 class(wfs_elec_t), intent(inout) :: hpsib
373
375
376 ! multiply linear terms in hamiltonian with occupation number
377 ! nonlinear occupation number dependency occurs only in the exchange, which is treated there
378 call batch_scal(mesh%np, this%st%occ(:, hpsib%ik), hpsib)
379
382
383 subroutine exchange_operator_write_info(this, namespace)
384 class(exchange_operator_t), intent(in) :: this
385 type(namespace_t), intent(in) :: namespace
386
388
389 call messages_print_with_emphasis(msg='Exact Exchange', namespace=namespace)
390 call messages_print_var_value("Adaptively compressed exchange", this%useACE, namespace=namespace)
391 if (this%useACE) then
392 call this%ace%write_info(namespace)
393 if (this%with_isdf) then
394 call messages_print_var_value("Density Fitting in ACE with ISDF", this%with_isdf, namespace=namespace)
395 call this%isdf%write_info(namespace)
396 endif
397 endif
398
400
401 end subroutine exchange_operator_write_info
402
403
404#include "undef.F90"
405#include "real.F90"
406#include "exchange_operator_inc.F90"
407
408#include "undef.F90"
409#include "complex.F90"
410#include "exchange_operator_inc.F90"
411
412! The exchange-potential routines are shared by all precisions (one source).
413#include "undef.F90"
414#include "real.F90"
415#include "exchange_operator_potentials_inc.F90"
416
417#include "undef.F90"
418#include "complex.F90"
419#include "exchange_operator_potentials_inc.F90"
421#include "undef.F90"
422#include "real32.F90"
423#include "exchange_operator_potentials_inc.F90"
424
425#include "undef.F90"
426#include "complex32.F90"
427#include "exchange_operator_potentials_inc.F90"
428
430
431!! Local Variables:
432!! mode: f90
433!! coding: utf-8
434!! End:
scale a batch by a constant or vector
Definition: batch_ops.F90:170
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
Definition: messages.F90:182
This module implements batches of mesh functions.
Definition: batch.F90:135
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:118
This module contains interfaces for BLAS routines You should not use these routines directly....
Definition: blas.F90:120
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dexchange_operator_hartree_apply(this, namespace, mesh, st_d, kpoints, exx_coef, psib, hpsib)
subroutine, public dexchange_operator_ace(this, namespace, mesh, st, xst, phase)
Construct the ACE vectors.
subroutine ace_write_info(this, namespace)
subroutine ace_init(this, namespace, st)
Initialize an instance of ACE_t.
subroutine, public zexchange_operator_compute_potentials(this, namespace, space, gr, st, xst, kpoints, F_out)
subroutine, public zexchange_operator_commute_r(this, namespace, mesh, st_d, ik, psi, gpsi)
subroutine, public exchange_operator_init(this, namespace, space, st, der, mc, stencil, kpoints, cam)
subroutine, public exchange_operator_reinit(this, cam, st)
subroutine exchange_operator_write_info(this, namespace)
subroutine, public dexchange_operator_compute_potentials(this, namespace, space, gr, st, xst, kpoints, F_out)
subroutine, public zexchange_operator_single(this, namespace, space, mesh, st_d, kpoints, phase, ist, ik, psi, hpsi, rdmft, force_noace)
subroutine, public dexchange_operator_single(this, namespace, space, mesh, st_d, kpoints, phase, ist, ik, psi, hpsi, rdmft, force_noace)
subroutine ace_end(this)
End an instance of ACE_t.
subroutine, public dexchange_operator_commute_r(this, namespace, mesh, st_d, ik, psi, gpsi)
subroutine, public zexchange_operator_hartree_apply(this, namespace, mesh, st_d, kpoints, exx_coef, psib, hpsib)
subroutine, public exchange_operator_end(this)
subroutine, public zexchange_operator_apply(this, namespace, space, mesh, st_d, kpoints, phase, psib, hpsib, rdmft, force_noace)
subroutine, public dexchange_operator_apply(this, namespace, space, mesh, st_d, kpoints, phase, psib, hpsib, rdmft, force_noace)
subroutine, public zexchange_operator_ace(this, namespace, mesh, st, xst, phase)
Construct the ACE vectors.
real(real64) function, public dexchange_operator_compute_ex(mesh, st, xst)
Compute the exact exchange energy.
subroutine, public exchange_operator_rdmft_occ_apply(this, mesh, hpsib)
real(real64) function, public zexchange_operator_compute_ex(mesh, st, xst)
Compute the exact exchange energy.
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
Definition: fft.F90:120
integer, parameter, public fftlib_accel
Definition: fft.F90:183
This module implements the underlying real-space grid.
Definition: grid.F90:119
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
This module defines functions over batches of mesh functions.
Definition: mesh_batch.F90:118
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:898
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
character(len=512), private msg
Definition: messages.F90:167
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:691
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1040
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
Some general things and nomenclature:
Definition: par_vec.F90:173
subroutine, public poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, force_cmplx, fft_library, fft_batch_size, single_precision)
Definition: poisson.F90:246
logical function, public poisson_is_batch_capable(this)
Whether this solver can transform a whole batch of functions in one call.
Definition: poisson.F90:889
subroutine, public poisson_end(this)
Definition: poisson.F90:719
This module is an helper to perform ring-pattern communications among all states.
subroutine, public singularity_end(this)
subroutine, public singularity_init(this, namespace, space, st, kpoints)
pure logical function, public states_are_real(st)
This module provides routines for communicating all batches in a ring-pattern scheme.
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public states_elec_end(st)
finalize the states_elec_t object
This module provides routines for communicating states when using states parallelization.
subroutine, public states_elec_parallel_remote_access_stop(this)
stop remote memory access for states on other processors
This module defines stencils used in Octopus.
Definition: stencil.F90:137
subroutine, public dsymmetrizer_apply_batch(this, mesh, iop, src, dst)
Symmetrize a whole batch, returning another batch with the same layout.
subroutine, public zsymmetrizer_apply_batch(this, mesh, iop, src, dst)
Symmetrize a whole batch, returning another batch with the same layout.
subroutine, public ssymmetrizer_apply_batch(this, mesh, iop, src, dst)
Symmetrize a whole batch, returning another batch with the same layout.
subroutine, public csymmetrizer_apply_batch(this, mesh, iop, src, dst)
Symmetrize a whole batch, returning another batch with the same layout.
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
This module defines the unit system, used for input and output.
class representing derivatives
Describes mesh distribution to nodes.
Definition: mesh.F90:187
Stores all communicators and groups.
Definition: multicomm.F90:208
The states_elec_t class contains all electronic wave functions.
The class representing the stencil, which is used for non-local mesh operations.
Definition: stencil.F90:165
batches of electronic states
Definition: wfs_elec.F90:143
Coulomb-attenuating method parameters, used in the partitioning of the Coulomb potential into a short...
Definition: xc_cam.F90:141
int true(void)