Octopus
xc.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
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
21#if defined(HAVE_CUDA)
22#define HAVE_ACCEL 1
23#endif
24
25module xc_oct_m
26 use accel_oct_m
28 use debug_oct_m
33 use global_oct_m
34 use grid_oct_m
35 use io_oct_m
37 use iso_c_binding
38 use, intrinsic :: iso_fortran_env
43 use math_oct_m
44 use mesh_oct_m
47 use mpi_oct_m
49 use parser_oct_m
52 use space_oct_m
55 use types_oct_m
57 use xc_cam_oct_m
58 use xc_f03_lib_m
59#ifdef HAVE_LIBXC_FUNCS
60 use xc_f03_funcs_m
61#endif
62 use xc_fbe_oct_m
65 use xc_lrc_oct_m
66
67 implicit none
68
69 private
70 public :: &
71 xc_t, &
73 xc_init, &
76 xc_end, &
89
90 ! A Structure that contains the quantities needed to compute the functionals
92 real(real64), pointer :: rho(:,:) ! A pointer to the full density
93
94 real(real64), allocatable :: dens(:,:) ! Density (in the local frame of the magnetization)
95 real(real64), allocatable :: gdens(:,:,:) ! Gradient of the density
96 real(real64), allocatable :: ldens(:,:) ! Laplacian of the density
97 real(real64), allocatable :: tau(:,:) ! Kinetic energy density
98
99 type(accel_mem_t) :: dens_buff ! GPU buffer: extracted density in libxc layout (spin_channels x np)
100 type(accel_mem_t) :: zk_buff ! GPU buffer: energy per unit volume
101 type(accel_mem_t) :: dedd_buff ! GPU buffer: dE/dn
102 type(accel_mem_t) :: sigma_buff ! GPU buffer: contracted density gradient (1 or 3 x np)
103 type(accel_mem_t) :: vsigma_buff ! GPU buffer: dE/dsigma
104 type(accel_mem_t) :: tau_buff ! GPU buffer: kinetic energy density (spin_channels x np)
105 type(accel_mem_t) :: ldens_buff ! GPU buffer: Laplacian of the density (spin_channels x np)
106 type(accel_mem_t) :: dedtau_buff ! GPU buffer: dE/dtau
107 type(accel_mem_t) :: dedldens_buff ! GPU buffer: dE/dlaplacian
108
109 ! Persistent pinned (page-locked) host staging buffers in libxc layout.
110 real(real64), pointer, contiguous :: hbuf_dens(:,:) => null()
111 real(real64), pointer, contiguous :: hbuf_sigma(:,:) => null()
112 real(real64), pointer, contiguous :: hbuf_ldens(:,:) => null()
113 real(real64), pointer, contiguous :: hbuf_tau(:,:) => null()
114 real(real64), pointer, contiguous :: hbuf_zk(:) => null()
115 real(real64), pointer, contiguous :: hbuf_dedd(:,:) => null()
116 real(real64), pointer, contiguous :: hbuf_vsigma(:,:) => null()
117 real(real64), pointer, contiguous :: hbuf_dedldens(:,:) => null()
118 real(real64), pointer, contiguous :: hbuf_dedtau(:,:) => null()
119
120 ! Density correction buffers: populated before XC if corrections are needed on GPU.
121 type(accel_mem_t) :: buff_rho_core ! GPU copy of st%rho_core (np)
122 type(accel_mem_t) :: buff_frozen_rho ! GPU copy of st%frozen_rho (np x nspin)
123 integer :: frozen_rho_np = 0 ! leading dimension of frozen_rho on CPU (= gr%np)
124 real(real64) :: amaldi_factor = m_one ! Amaldi scaling factor applied to dens_buff (1.0 if inactive)
125 ! True when dens_buff was pre-populated from st%buff_density by xc_update_internal_quantities.
126 ! False when xc_compute_vxc must upload CPU l_dens to dens_buff each block.
127 logical :: dens_buff_prefilled = .false.
128 end type internal_quantities_t
129
130
131 type xc_t
132 private
133 integer, public :: family
134 integer, public :: flags
135 integer, public :: kernel_family
136 type(xc_functional_t), public :: functional(2,2)
138
139 type(xc_functional_t), public :: kernel(2,2)
140 type(xc_cam_t), public :: cam
141 type(xc_lrc_t), public :: lrc
142
143 logical, public :: use_gi_ked
144 integer, public :: xc_density_correction
145 logical, public :: xcd_optimize_cutoff
146 real(real64), public :: xcd_ncutoff
147 logical, public :: xcd_minimum
148 logical, public :: xcd_normalize
149 logical, public :: parallel
150 logical, public :: xc_on_host
151
152 type(internal_quantities_t), public :: quantities
153
154 contains
155 procedure :: compute_exchange => xc_compute_exchange
156
157 end type xc_t
158
160 real(real64), public, parameter :: xc_tiny = 1.0e-12_real64
161
162 integer, public, parameter :: &
163 LR_NONE = 0, &
164 lr_x = 1
165
166contains
167
168 ! ---------------------------------------------------------
169 subroutine xc_write_info(xcs, iunit, namespace)
170 type(xc_t), intent(in) :: xcs
171 integer, optional, intent(in) :: iunit
172 type(namespace_t), optional, intent(in) :: namespace
173
174 integer :: ifunc
175
176 push_sub(xc_write_info)
177
178 write(message(1), '(a)') "Exchange-correlation:"
179 call messages_info(1, iunit=iunit, namespace=namespace)
180
181 do ifunc = func_x, func_c
182 call xc_functional_write_info(xcs%functional(ifunc, 1), iunit, namespace)
183 end do
184
185 if (abs(xcs%cam%alpha) + abs(xcs%cam%beta) > m_epsilon) then
186 write(message(1), '(1x)')
187 write(message(2), '(a,f8.5)') "Exact exchange mixing = ", xcs%cam%alpha
188 write(message(3), '(a,f8.5)') "Exact exchange for short-range beta = ", xcs%cam%beta
189 write(message(4), '(a,f8.5)') "Exact exchange range-separate omega = ", xcs%cam%omega
190 call messages_info(4, iunit=iunit, namespace=namespace)
191 end if
193
195 end subroutine xc_write_info
197 ! ---------------------------------------------------------
198 subroutine xc_write_fxc_info(xcs, iunit, namespace)
199 type(xc_t), intent(in) :: xcs
200 integer, optional, intent(in) :: iunit
201 type(namespace_t), optional, intent(in) :: namespace
203 integer :: ifunc
204
207 write(message(1), '(a)') "Exchange-correlation kernel:"
208 call messages_info(1, iunit=iunit, namespace=namespace)
210 do ifunc = func_x, func_c
211 call xc_functional_write_info(xcs%kernel(ifunc, 1), iunit, namespace)
212 end do
214 pop_sub(xc_write_fxc_info)
215 end subroutine xc_write_fxc_info
218 ! ---------------------------------------------------------
219 subroutine xc_init_device_support(xcs, namespace)
220 type(xc_t), intent(inout) :: xcs
221 type(namespace_t), intent(in) :: namespace
223 push_sub(xc_init_device_support)
224
225 xcs%xc_on_host = .not. xc_is_using_device(namespace)
230 ! ---------------------------------------------------------
232 logical function xc_is_using_device(namespace)
233 type(namespace_t), intent(in) :: namespace
235 logical :: xc_force_cpu
237 push_sub(xc_is_using_device)
239 !%Variable XCForceFunctionalsOnCPU
240 !%Type logical
241 !%Default no
242 !%Section Hamiltonian::XC
243 !%Description
244 !% By setting this variable to <tt>yes</tt>, you force Octopus to evaluate XC functionals
245 !% on the CPU, even if CUDA/HIP support is available.
246 !%End
247 call parse_variable(namespace, 'XCForceFunctionalsOnCPU', .false., xc_force_cpu)
248
249#if defined(HAVE_LIBXC_DEVICE) && defined(HAVE_ACCEL)
251 if (accel_is_enabled()) then
252 xc_is_using_device = .not. xc_force_cpu
253 end if
254#elif defined(HAVE_LIBXC_DEVICE) && !defined(HAVE_ACCEL)
255 if(.not. xc_force_cpu) then
256 call messages_warning("Libxc has device support but no accelerator support is enabled in Octopus.", namespace=namespace)
257 end if
258 xc_is_using_device = .false.
259#else
260 xc_is_using_device = .false.
261#endif
262
263 pop_sub(xc_is_using_device)
265
266 ! ---------------------------------------------------------
267 subroutine xc_init(xcs, namespace, ndim, periodic_dim, nel, x_id, c_id, xk_id, ck_id, hartree_fock, ispin)
268 type(xc_t), intent(out) :: xcs
269 type(namespace_t), intent(in) :: namespace
270 integer, intent(in) :: ndim
271 integer, intent(in) :: periodic_dim
272 real(real64), intent(in) :: nel
273 integer, intent(in) :: x_id
274 integer, intent(in) :: c_id
275 integer, intent(in) :: xk_id
276 integer, intent(in) :: ck_id
277 logical, intent(in) :: hartree_fock
278 integer, intent(in) :: ispin
279
280 integer :: isp, xc_major, xc_minor, xc_micro
281 logical :: ll
282 type(block_t) :: blk
283 type(xc_cam_t) :: cam_ext
284 logical :: cam_ext_set
285
286 push_sub(xc_init)
287
288 call xc_f03_version(xc_major, xc_minor, xc_micro)
289
290 xcs%family = 0
291 xcs%flags = 0
292 xcs%kernel_family = 0
294 call parse()
295
296 call xc_lrc_init(xcs%lrc, namespace, ndim, periodic_dim)
297
298 call xc_init_device_support(xcs, namespace)
299
300 ! 1D/2D functionals (e.g. lda_x_1d_soft) call xc_integrate() which uses malloc() inside
301 ! GPU kernels. With large meshes this exhausts the CUDA device heap (cudaErrorIllegalAddress).
302 if (ndim /= 3) xcs%xc_on_host = .true.
303
304 !we also need XC functionals that do not depend on the current
305 !get both spin-polarized and unpolarized
306
307 ! TODO: check that nel should not be spin polarized here
308 do isp = 1, 2
309
310 call xc_functional_init(xcs%functional(func_x, isp), namespace, x_id, ndim, nel, isp, xcs%xc_on_host)
311 call xc_functional_init(xcs%functional(func_c, isp), namespace, c_id, ndim, nel, isp, xcs%xc_on_host)
312
313 call xc_functional_init(xcs%kernel(func_x, isp), namespace, xk_id, ndim, nel, isp, xcs%xc_on_host)
314 call xc_functional_init(xcs%kernel(func_c, isp), namespace, ck_id, ndim, nel, isp, xcs%xc_on_host)
315
316 end do
317
318 xcs%family = ior(xcs%family, xcs%functional(func_x,1)%family)
319 xcs%family = ior(xcs%family, xcs%functional(func_c,1)%family)
320
321 xcs%flags = ior(xcs%flags, xcs%functional(func_x,1)%flags)
322 xcs%flags = ior(xcs%flags, xcs%functional(func_c,1)%flags)
323
324 xcs%kernel_family = ior(xcs%kernel_family, xcs%kernel(func_x,1)%family)
325 xcs%kernel_family = ior(xcs%kernel_family, xcs%kernel(func_c,1)%family)
326
328 if (xc_is_not_size_consistent(xcs, namespace) .and. periodic_dim > 0) then
329 message(1) = "Cannot perform a periodic calculation with a functional"
330 message(2) = "that depends on the number of electrons."
331 call messages_fatal(2, namespace=namespace)
332 end if
333
334 ! Take care of hybrid functionals (they appear in the correlation functional)
335 xcs%cam = cam_null
336
337 ll = (hartree_fock) &
338 .or.(xcs%functional(func_x,1)%id == xc_oep_x) &
339 .or. family_is_hybrid(xcs)
340 if (ll) then
341 if ((xcs%functional(func_x,1)%id /= 0).and.(xcs%functional(func_x,1)%id /= xc_oep_x)) then
342 message(1) = "You cannot use an exchange functional when performing"
343 message(2) = "a Hartree-Fock calculation or using a hybrid functional."
344 call messages_fatal(2, namespace=namespace)
345 end if
346
347 if (periodic_dim == ndim) then
348 call messages_experimental("Fock operator (Hartree-Fock, OEP, hybrids) in fully periodic systems", namespace=namespace)
349 end if
350
351 ! get the mixing coefficient for hybrids
352 if (family_is_hybrid(xcs)) then
353 if (cam_ext_set) call set_hybrid_params(xcs, namespace, cam_ext)
354 call xc_f03_hyb_cam_coef(xcs%functional(func_c,1)%conf, xcs%cam%omega, &
355 xcs%cam%alpha, xcs%cam%beta)
356 call xc_f03_hyb_cam_coef(xcs%functional(func_c,2)%conf, xcs%cam%omega, &
357 xcs%cam%alpha, xcs%cam%beta)
358 else
359 ! we are doing Hartree-Fock plus possibly a correlation functional
360 xcs%cam = cam_exact_exchange
361 end if
362
363 ! reset certain variables
364 xcs%functional(func_x,1)%family = xc_family_oep
365 xcs%functional(func_x,1)%id = xc_oep_x
366 xcs%functional(func_x,2)%family = xc_family_oep
367 xcs%functional(func_x,2)%id = xc_oep_x
368 if (.not. hartree_fock) then
369 xcs%family = ior(xcs%family, xc_family_oep)
370 end if
371 end if
372
373 if (in_family(xcs%family, [xc_family_lca])) then
374 call messages_not_implemented("LCA current functionals", namespace) ! not even in libxc!
375 end if
376
377 call messages_obsolete_variable(namespace, 'MGGAimplementation')
378 call messages_obsolete_variable(namespace, 'CurrentInTau', 'XCUseGaugeIndependentKED')
379
380 if (xcs%functional(func_x, 1)%id == xc_mgga_x_tb09 .and. periodic_dim /= 3) then
381 message(1) = "mgga_x_tb09 functional can only be used for 3D periodic systems"
382 call messages_fatal(1, namespace=namespace)
383 end if
384
385 if (family_is_mgga(xcs%family) .or. family_is_nc_mgga(xcs%family)) then
386 !%Variable XCUseGaugeIndependentKED
387 !%Type logical
388 !%Default yes
389 !%Section Hamiltonian::XC
390 !%Description
391 !% If true, when evaluating the XC functional, a term including the (paramagnetic or total) current
392 !% is added to the kinetic-energy density such as to make it gauge-independent.
393 !% Applies only to meta-GGA (and hybrid meta-GGA) functionals.
394 !%End
395 call parse_variable(namespace, 'XCUseGaugeIndependentKED', .true., xcs%use_gi_ked)
396 end if
397
398 pop_sub(xc_init)
399
400 contains
401
402 subroutine parse()
403
404 push_sub(xc_init.parse)
405
406 ! the values of x_id, c_id, xk_id, and c_id are read outside the routine
407
408 !%Variable XCDensityCorrection
409 !%Type integer
410 !%Default none
411 !%Section Hamiltonian::XC::DensityCorrection
412 !%Description
413 !% This variable controls the long-range correction of the XC
414 !% potential using the <a href=http://arxiv.org/abs/1107.4339>XC density representation</a>.
415 !%Option none 0
416 !% No correction is applied.
417 !%Option long_range_x 1
418 !% The correction is applied to the exchange potential.
419 !%End
420 call parse_variable(namespace, 'XCDensityCorrection', lr_none, xcs%xc_density_correction)
421
422 if (xcs%xc_density_correction /= lr_none) then
423 call messages_experimental('XC density correction', namespace=namespace)
424
425 if(ispin /= unpolarized) then
426 call messages_not_implemented('XCDensityCorrection with SpinComponents /= unpolarized', namespace)
427 end if
428
429 !%Variable XCDensityCorrectionOptimize
430 !%Type logical
431 !%Default true
432 !%Section Hamiltonian::XC::DensityCorrection
433 !%Description
434 !% When enabled, the density cutoff will be
435 !% optimized to replicate the boundary conditions of the exact
436 !% XC potential. If the variable is set to no, the value of
437 !% the cutoff must be given by <tt>XCDensityCorrectionCutoff</tt>
438 !% variable.
439 !%End
440 call parse_variable(namespace, 'XCDensityCorrectionOptimize', .true., xcs%xcd_optimize_cutoff)
441
442 !%Variable XCDensityCorrectionCutoff
443 !%Type float
444 !%Default 0.0
445 !%Section Hamiltonian::XC::DensityCorrection
446 !%Description
447 !% The value of the cutoff applied to the XC density.
448 !%End
449 call parse_variable(namespace, 'XCDensityCorrectionCutoff', m_zero, xcs%xcd_ncutoff)
450
451 !%Variable XCDensityCorrectionMinimum
452 !%Type logical
453 !%Default true
454 !%Section Hamiltonian::XC::DensityCorrection
455 !%Description
456 !% When enabled, the cutoff optimization will
457 !% return the first minimum of the <math>q_{xc}</math> function if it does
458 !% not find a value of -1 (<a href=http://arxiv.org/abs/1107.4339>details</a>).
459 !% This is required for atoms or small
460 !% molecules, but may cause numerical problems.
461 !%End
462 call parse_variable(namespace, 'XCDensityCorrectionMinimum', .true., xcs%xcd_minimum)
463
464 !%Variable XCDensityCorrectionNormalize
465 !%Type logical
466 !%Default true
467 !%Section Hamiltonian::XC::DensityCorrection
468 !%Description
469 !% When enabled, the correction will be
470 !% normalized to reproduce the exact boundary conditions of
471 !% the XC potential.
472 !%End
473 call parse_variable(namespace, 'XCDensityCorrectionNormalize', .true., xcs%xcd_normalize)
474
475 end if
476
477 !%Variable ParallelXC
478 !%Type logical
479 !%Default true
480 !%Section Execution::Parallelization
481 !%Description
482 !% When enabled, additional parallelization
483 !% will be used for the calculation of the XC functional.
484 !%End
485 call messages_obsolete_variable(namespace, 'XCParallel', 'ParallelXC')
486 call parse_variable(namespace, 'ParallelXC', .true., xcs%parallel)
487
488
489 !%Variable HybridCAMParameters
490 !%Type block
491 !%Section Hamiltonian::XC
492 !%Description
493 !% This variable specifies the <math>\alpha, \beta, \omega</math> parameters
494 !% for CAM-type hybrid functionals. Octopus applies exact exchange with the
495 !% attenuated interaction
496 !% <math>\alpha/r + \beta\,{\rm erfc}(\omega r)/r</math>, or equivalently
497 !% <math>4\pi/G^2 [\alpha + \beta(1-\exp(-G^2/(4\omega^2)))]</math> in
498 !% reciprocal space. Thus <math>\alpha</math> is the full-range exact-exchange
499 !% fraction, and <math>\beta</math> is the additional short-range screened
500 !% exact-exchange fraction. Defaults are zero.
501 !%
502 !% HSE06 corresponds to:
503 !% <tt>%HybridCAMParameters
504 !% 0.0 | 0.25 | 0.11
505 !% %</tt>
506 !% The parameters <tt>0.25 | 0.0 | 0.11</tt> instead define a 25% full-range
507 !% hybrid and are not equivalent to HSE06.
508 !%End
509 cam_ext = cam_null
510
511 cam_ext_set = parse_block(namespace, 'HybridCamParameters', blk) == 0
512 if (cam_ext_set) then
513 call parse_block_float(blk, 0, 0, cam_ext%alpha)
514 call parse_block_float(blk, 0, 1, cam_ext%beta)
515 call parse_block_float(blk, 0, 2, cam_ext%omega)
516 call parse_block_end(blk)
517 end if
518
519 if (cam_ext_set) then
520 call cam_ext%print(namespace, msg="Info: Setting external CAM parameters")
521 endif
522
523 pop_sub(xc_init.parse)
524 end subroutine parse
525
526 end subroutine xc_init
527
528
529 ! ---------------------------------------------------------
530 subroutine xc_end(xcs)
531 type(xc_t), intent(inout) :: xcs
532
533 integer :: isp
534
535 push_sub(xc_end)
536
537 do isp = 1, 2
538 call xc_functional_end(xcs%functional(func_x, isp))
539 call xc_functional_end(xcs%functional(func_c, isp))
540 call xc_functional_end(xcs%kernel(func_x, isp))
541 call xc_functional_end(xcs%kernel(func_c, isp))
542 end do
543 xcs%family = 0
544 xcs%flags = 0
545
546 ! Free the persistent host staging buffers (see internal_quantities_t), allocated
547 ! with the hardware-aware allocator in xc_compute_vxc.
548 if (associated(xcs%quantities%hbuf_dens)) then
549 call deallocate_hardware_aware(c_loc(xcs%quantities%hbuf_dens(1,1)), size(xcs%quantities%hbuf_dens, kind=int64)*8_int64)
550 nullify(xcs%quantities%hbuf_dens)
551 end if
552 if (associated(xcs%quantities%hbuf_sigma)) then
553 call deallocate_hardware_aware(c_loc(xcs%quantities%hbuf_sigma(1,1)), size(xcs%quantities%hbuf_sigma, kind=int64)*8_int64)
554 nullify(xcs%quantities%hbuf_sigma)
555 end if
556 if (associated(xcs%quantities%hbuf_ldens)) then
557 call deallocate_hardware_aware(c_loc(xcs%quantities%hbuf_ldens(1,1)), size(xcs%quantities%hbuf_ldens, kind=int64)*8_int64)
558 nullify(xcs%quantities%hbuf_ldens)
559 end if
560 if (associated(xcs%quantities%hbuf_tau)) then
561 call deallocate_hardware_aware(c_loc(xcs%quantities%hbuf_tau(1,1)), size(xcs%quantities%hbuf_tau, kind=int64)*8_int64)
562 nullify(xcs%quantities%hbuf_tau)
563 end if
564 if (associated(xcs%quantities%hbuf_zk)) then
565 call deallocate_hardware_aware(c_loc(xcs%quantities%hbuf_zk(1)), size(xcs%quantities%hbuf_zk, kind=int64)*8_int64)
566 nullify(xcs%quantities%hbuf_zk)
567 end if
568 if (associated(xcs%quantities%hbuf_dedd)) then
569 call deallocate_hardware_aware(c_loc(xcs%quantities%hbuf_dedd(1,1)), size(xcs%quantities%hbuf_dedd, kind=int64)*8_int64)
570 nullify(xcs%quantities%hbuf_dedd)
571 end if
572 if (associated(xcs%quantities%hbuf_vsigma)) then
573 call deallocate_hardware_aware(c_loc(xcs%quantities%hbuf_vsigma(1,1)), size(xcs%quantities%hbuf_vsigma, kind=int64)*8_int64)
574 nullify(xcs%quantities%hbuf_vsigma)
575 end if
576 if (associated(xcs%quantities%hbuf_dedldens)) then
577 call deallocate_hardware_aware(c_loc(xcs%quantities%hbuf_dedldens(1,1)), &
578 size(xcs%quantities%hbuf_dedldens, kind=int64)*8_int64)
579 nullify(xcs%quantities%hbuf_dedldens)
580 end if
581 if (associated(xcs%quantities%hbuf_dedtau)) then
582 call deallocate_hardware_aware(c_loc(xcs%quantities%hbuf_dedtau(1,1)), size(xcs%quantities%hbuf_dedtau, kind=int64)*8_int64)
583 nullify(xcs%quantities%hbuf_dedtau)
584 end if
585
586 pop_sub(xc_end)
587 end subroutine xc_end
588
589 ! ---------------------------------------------------------
594 logical pure function xc_is_orbital_dependent(xcs)
595 type(xc_t), intent(in) :: xcs
596
597 xc_is_orbital_dependent = family_is_hybrid(xcs) .or. &
598 in_family(xcs%functional(func_x,1)%family, [xc_family_oep]) .or. &
599 in_family(xcs%family, [xc_family_mgga, xc_family_nc_mgga])
600
601 end function xc_is_orbital_dependent
602
603 ! ---------------------------------------------------------
605 pure logical function family_is_gga(family, only_collinear)
606 integer, intent(in) :: family
607 logical, optional, intent(in) :: only_collinear
608
609 if(optional_default(only_collinear, .false.)) then
610 family_is_gga = in_family(family, [xc_family_gga, xc_family_hyb_gga, &
611 xc_family_mgga, xc_family_hyb_mgga, xc_family_libvdwxc])
612 else
613 family_is_gga = in_family(family, [xc_family_gga, xc_family_hyb_gga, &
614 xc_family_mgga, xc_family_hyb_mgga, xc_family_libvdwxc, xc_family_nc_mgga])
615 end if
616 end function family_is_gga
617
618 !----------------------------------------------------------------------
623 pure logical function family_is_supported(family)
624 integer, intent(in) :: family
625
626 family_is_supported = in_family(family, [xc_family_lda, xc_family_hyb_lda, xc_family_gga, xc_family_hyb_gga, &
627 xc_family_mgga, xc_family_hyb_mgga, xc_family_libvdwxc])
628 end function family_is_supported
629
630 ! ---------------------------------------------------------
632 pure logical function family_is_mgga(family, only_collinear)
633 integer, intent(in) :: family
634 logical, optional, intent(in) :: only_collinear
635
636 if(optional_default(only_collinear, .false.)) then
637 family_is_mgga = in_family(family, [xc_family_mgga, xc_family_hyb_mgga])
638 else
639 family_is_mgga = in_family(family, [xc_family_mgga, xc_family_hyb_mgga, xc_family_nc_mgga])
640 end if
641 end function family_is_mgga
642
643 pure logical function family_is_nc_mgga(family)
644 integer, intent(in) :: family
645
646 family_is_nc_mgga = bitand(family, xc_family_nc_mgga) /= 0
647 end function family_is_nc_mgga
648
649 ! ---------------------------------------------------------
651 logical pure function family_is_mgga_with_exc(xcs)
652 type(xc_t), intent(in) :: xcs
653
654 integer :: ixc
655
657 do ixc = 1, 2
658 if (in_family(xcs%functional(ixc, 1)%family, [xc_family_mgga, xc_family_hyb_mgga, xc_family_nc_mgga]) &
659 .and. xc_functional_is_energy_functional(xcs%functional(ixc, 1))) then
661 end if
662 end do
663 end function family_is_mgga_with_exc
664
666 logical pure function family_is_hybrid(xcs)
667 type(xc_t), intent(in) :: xcs
668
669 integer :: ixc
670
671 family_is_hybrid = .false.
672 do ixc = 1, 2
673 if (in_family(xcs%functional(ixc, 1)%family, [xc_family_hyb_lda, xc_family_hyb_gga, xc_family_hyb_mgga])) then
675 end if
676 end do
677 end function family_is_hybrid
679 pure logical function in_family(family, xc_families)
680 integer, intent(in) :: family
681 integer, intent(in) :: xc_families(:)
682
683 in_family = bitand(family, sum(xc_families)) /= 0
684 end function in_family
685
687 logical function xc_compute_exchange(xc, theory_level)
688 class(xc_t), intent(in) :: xc
689 integer, intent(in) :: theory_level
690
691 integer, parameter :: exchange_theory_level(3) = [hartree, hartree_fock, rdmft]
692
693 push_sub(xc_compute_exchange)
694
695 xc_compute_exchange = any(exchange_theory_level == theory_level) .or. &
696 (theory_level == generalized_kohn_sham_dft .and. family_is_hybrid(xc)) .or. &
697 (xc%functional(func_x, 1)%id == xc_oep_x_slater) .or. &
698 (bitand(xc%family, xc_family_oep) /= 0)
699
700 pop_sub(xc_compute_exchange)
701
702 end function xc_compute_exchange
703
704 ! ---------------------------------------------------------
706 subroutine set_hybrid_params(xcs, namespace, cam_ext)
707 type(xc_t), intent(inout) :: xcs
708 type(namespace_t), intent(in) :: namespace
709 type(xc_cam_t), intent(in) :: cam_ext
710
711 real(real64), parameter :: default_alpha_pbe0 = 0.25_real64
712 real(real64) :: parameters(3)
713
714 push_sub(set_hybrid_params)
715
716 ! LibXC expects an array of reals, ordered [alpha, beta, omega]
717 parameters = cam_ext%as_array()
718 xcs%cam%alpha = parameters(1)
719
720 select case(xcs%functional(func_c, 1)%id)
721
722 case(xc_hyb_gga_xc_pbeh, xc_hyb_lda_xc_lda0) ! original PBE0/LDA0 in libxc
723 if(parameters(1) < m_zero) parameters(1) = default_alpha_pbe0
724 call xc_f03_func_set_ext_params(xcs%functional(func_c, 1)%conf, parameters)
725 call xc_f03_func_set_ext_params(xcs%functional(func_c, 2)%conf, parameters)
726 write(message(1), '(a,f6.3,a)') 'Info: Setting mixing parameter (' , parameters(1) ,').'
727 call messages_info(1)
728
729 case(xc_hyb_gga_xc_cam_pbeh, xc_hyb_lda_xc_cam_lda0)
730 xcs%cam%beta = parameters(2)
731 xcs%cam%omega = parameters(3)
732 call xc_f03_func_set_ext_params(xcs%functional(func_c, 1)%conf, parameters)
733 call xc_f03_func_set_ext_params(xcs%functional(func_c, 2)%conf, parameters)
734 ! check parameters
735 call xc_f03_hyb_cam_coef(xcs%functional(func_c,1)%conf, xcs%cam%omega, &
736 xcs%cam%alpha, xcs%cam%beta)
737 call xc_f03_hyb_cam_coef(xcs%functional(func_c,2)%conf, xcs%cam%omega, &
738 xcs%cam%alpha, xcs%cam%beta)
739 call xcs%cam%print(namespace, msg="Setting CAM parameters:")
740
741 case default
742 assert(.false.)
743
744 end select
745
746 pop_sub(set_hybrid_params)
747 end subroutine set_hybrid_params
748
749 ! ---------------------------------------------------------
751 logical function xc_is_not_size_consistent(xcs, namespace)
752 type(xc_t), intent(in) :: xcs
753 type(namespace_t), intent(in) :: namespace
754
755 xc_is_not_size_consistent = xc_functional_is_not_size_consistent(xcs%functional(func_x,1), namespace) &
756 .or. xc_functional_is_not_size_consistent(xcs%functional(func_c,1), namespace)
757 end function xc_is_not_size_consistent
758
759 ! ---------------------------------------------------------
761 logical pure function xc_is_energy_functional(xcs)
762 type(xc_t), intent(in) :: xcs
763 xc_is_energy_functional = xc_functional_is_energy_functional(xcs%functional(func_x,1)) &
764 .or. xc_functional_is_energy_functional(xcs%functional(func_c,1))
765 end function xc_is_energy_functional
766
767end module xc_oct_m
768
769
770!! Local Variables:
771!! mode: f90
772!! coding: utf-8
773!! End:
pure logical function, public accel_is_enabled()
Definition: accel.F90:414
This module contains interfaces for routines in allocate_hardware_aware.c.
subroutine, public deallocate_hardware_aware(array, size)
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
integer, parameter, public unpolarized
Parameters...
real(real64), parameter, public m_zero
Definition: global.F90:200
integer, parameter, public hartree_fock
Definition: global.F90:250
real(real64), parameter, public m_epsilon
Definition: global.F90:216
real(real64), parameter, public m_one
Definition: global.F90:201
This module implements the underlying real-space grid.
Definition: grid.F90:119
Definition: io.F90:116
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
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_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
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1000
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1040
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:623
This module handles spin dimensions of the states and the k-point distribution.
This module defines the unit system, used for input and output.
type(xc_cam_t), parameter, public cam_null
All CAM parameters set to zero.
Definition: xc_cam.F90:151
type(xc_cam_t), parameter, public cam_exact_exchange
Use only Hartree Fock exact exchange.
Definition: xc_cam.F90:154
subroutine, public xc_functional_write_info(functl, iunit, namespace)
Write functional information.
subroutine, public xc_functional_init(functl, namespace, id, ndim, nel, spin_channels, functionals_on_cpu)
integer, parameter, public xc_family_nc_mgga
integer, parameter, public xc_oep_x
Exact exchange.
subroutine, public xc_functional_end(functl)
integer, parameter, public func_c
integer, parameter, public func_x
subroutine, public xc_lrc_init(this, namespace, dim, periodic_dim)
Definition: xc_lrc.F90:146
Definition: xc.F90:120
subroutine, public xc_write_info(xcs, iunit, namespace)
Definition: xc.F90:265
subroutine, public xc_init(xcs, namespace, ndim, periodic_dim, nel, x_id, c_id, xk_id, ck_id, hartree_fock, ispin)
Definition: xc.F90:352
pure logical function, public family_is_mgga(family, only_collinear)
Is the xc function part of the mGGA family.
Definition: xc.F90:717
subroutine set_hybrid_params(xcs, namespace, cam_ext)
Sets external parameters for some hybrid functionals.
Definition: xc.F90:791
pure logical function, public family_is_gga(family, only_collinear)
Is the xc function part of the GGA family.
Definition: xc.F90:690
logical pure function, public family_is_mgga_with_exc(xcs)
Is the xc function part of the mGGA family with an energy functional.
Definition: xc.F90:736
logical function, public xc_is_using_device(namespace)
Check if XC will run on device (parses config and checks availability)
Definition: xc.F90:328
subroutine, public xc_end(xcs)
Definition: xc.F90:615
logical pure function, public xc_is_energy_functional(xcs)
Is one of the x or c functional is not an energy functional.
Definition: xc.F90:846
logical pure function, public family_is_hybrid(xcs)
Returns true if the functional is an hybrid functional.
Definition: xc.F90:751
logical function, public xc_is_not_size_consistent(xcs, namespace)
Is one of the x or c functional is not size consistent.
Definition: xc.F90:836
subroutine, public xc_init_device_support(xcs, namespace)
Definition: xc.F90:315
integer, parameter, public lr_x
Definition: xc.F90:257
pure logical function, public family_is_nc_mgga(family)
Definition: xc.F90:728
logical function xc_compute_exchange(xc, theory_level)
Theory levels and functionals for which exacy exchange is required.
Definition: xc.F90:772
pure logical function, public family_is_supported(family)
Is the xc family internally supported by Octopus.
Definition: xc.F90:708
pure logical function, public in_family(family, xc_families)
Definition: xc.F90:764
subroutine, public xc_write_fxc_info(xcs, iunit, namespace)
Definition: xc.F90:294
logical pure function, public xc_is_orbital_dependent(xcs)
Is the xc family orbital dependent.
Definition: xc.F90:679
Coulomb-attenuating method parameters, used in the partitioning of the Coulomb potential into a short...
Definition: xc_cam.F90:141
int true(void)
subroutine parse()
Definition: xc.F90:487