34 use,
intrinsic :: iso_fortran_env
72 integer,
public :: es_type
74 real(real64),
public :: tolerance
75 integer,
public :: es_maxiter
77 real(real64) :: imag_time
80 real(real64),
allocatable,
public :: diff(:, :)
81 integer,
public :: matvec
82 integer,
allocatable,
public :: converged(:)
85 type(preconditioner_t),
public :: pre
88 type(subspace_t) :: sdiag
90 integer :: rmmdiis_minimization_iter
92 logical,
public :: folded_spectrum
95 logical,
public :: orthogonalize_to_all
96 integer,
public :: conjugate_direction
97 logical,
public :: additional_terms
98 real(real64),
public :: energy_change_threshold
101 type(eigen_chebyshev_t),
public :: cheby_params
103 type(exponential_t) :: exponential_operator
109 integer,
public,
parameter :: &
120 type(eigensolver_t),
intent(out) :: eigens
121 type(namespace_t),
intent(in) :: namespace
122 type(grid_t),
intent(in) :: gr
123 type(states_elec_t),
intent(in) :: st
124 type(multicomm_t),
intent(in) :: mc
125 class(space_t),
intent(in) :: space
127 integer :: default_iter, default_es
128 real(real64) :: default_tol
167 if(st%parallel_in_states)
then
176 message(1) =
"The selected eigensolver is not parallel in states."
177 message(2) =
"Please use the rmmdiis or Chebyshev filtering eigensolvers."
185 default_tol = 1e-7_real64
187 select case(eigens%es_type)
202 call parse_variable(namespace,
'CGOrthogonalizeAll', .false., eigens%orthogonalize_to_all)
219 call parse_variable(namespace,
'CGDirection', option__cgdirection__fletcher, eigens%conjugate_direction)
232 call parse_variable(namespace,
'CGAdditionalTerms', .false., eigens%additional_terms)
233 if(eigens%additional_terms)
then
234 call messages_experimental(
"The additional terms for the CG eigensolver are not tested for all cases.")
252 call parse_variable(namespace,
'CGEnergyChangeThreshold', 0.1_real64, eigens%energy_change_threshold)
270 call parse_variable(namespace,
'EigensolverImaginaryTime', 0.1_real64, eigens%imag_time)
276 message(1) =
"Smearing of occupations is incompatible with imaginary time evolution."
294 call parse_variable(namespace,
'EigensolverMinimizationIter', 0, eigens%rmmdiis_minimization_iter)
311 eigens%cheby_params%n_lanczos)
346 eigens%cheby_params%optimize_degree)
360 eigens%cheby_params%bound_mixing)
372 eigens%cheby_params%n_iter)
391 eigens%folded_spectrum = .false.
399 call parse_variable(namespace,
'EigensolverTolerance', default_tol, eigens%tolerance)
415 call parse_variable(namespace,
'EigensolverMaxIter', default_iter, eigens%es_maxiter)
418 if(eigens%es_maxiter > default_iter)
then
419 call messages_write(
'You have specified a large number of eigensolver iterations (')
422 call messages_write(
'This is not a good idea as it might slow down convergence, even for', new_line = .
true.)
423 call messages_write(
'independent particles, as subspace diagonalization will not be used', new_line = .
true.)
432 safe_allocate(eigens%diff(1:st%nst, 1:st%nik))
433 eigens%diff(1:st%nst, 1:st%nik) = 0
435 safe_allocate(eigens%converged(1:st%nik))
436 eigens%converged(1:st%nik) = 0
439 call eigens%sdiag%init(namespace, st)
442 select case(eigens%es_type)
445 mem = (
m_two*eigens%es_maxiter -
m_one)*st%block_size*real(gr%np_part, real64)
449 mem = mem*16.0_real64
454 call messages_write(
' memory. This amount can be reduced by decreasing the value')
456 call messages_write(
' of the variable StatesBlockSize (currently set to ')
474 select case(eigens%es_type)
479 safe_deallocate_a(eigens%converged)
480 safe_deallocate_a(eigens%diff)
487 subroutine eigensolver_run(eigens, namespace, gr, st, hm, iter, conv, nstconv)
490 type(
grid_t),
intent(in) :: gr
493 integer,
intent(in) :: iter
494 logical,
optional,
intent(out) :: conv
495 integer,
optional,
intent(in) :: nstconv
498 integer :: ik, ist, nstconv_
500 logical :: conv_reduced
501 integer :: outcount, lmatvec
502 real(real64),
allocatable :: ldiff(:), leigenval(:)
503 real(real64),
allocatable :: ldiff_out(:), leigenval_out(:)
504 integer,
allocatable :: lconv(:)
510 if(
present(conv)) conv = .false.
511 if(
present(nstconv))
then
523 ik_loop:
do ik = st%d%kpt%start, st%d%kpt%end
530 if (.not. eigens%folded_spectrum)
then
532 eigens%converged(ik) = 0
534 if(eigens%diff(ist, ik) < eigens%tolerance)
then
535 eigens%converged(ik) = ist
544 write(stdout,
'(1x)')
547 if(
present(conv)) conv = all(eigens%converged(st%d%kpt%start:st%d%kpt%end) >= nstconv_)
550 if (st%d%kpt%parallel)
then
551 if (
present(conv))
then
552 call st%d%kpt%mpi_grp%allreduce(conv, conv_reduced, 1, mpi_logical, mpi_land)
556 lmatvec = eigens%matvec
557 call st%d%kpt%mpi_grp%allreduce(lmatvec, eigens%matvec, 1, mpi_integer, mpi_sum)
559 safe_allocate(lconv(1:st%d%kpt%nlocal))
560 lconv(1:st%d%kpt%nlocal) = eigens%converged(st%d%kpt%start:st%d%kpt%end)
561 call lmpi_gen_allgatherv(st%d%kpt%nlocal, lconv, outcount, eigens%converged, st%d%kpt%mpi_grp)
562 assert(outcount == st%nik)
563 safe_deallocate_a(lconv)
566 safe_allocate(ldiff(1:st%d%kpt%nlocal))
567 safe_allocate(leigenval(1:st%d%kpt%nlocal))
568 safe_allocate(ldiff_out(1:st%nik))
569 safe_allocate(leigenval_out(1:st%nik))
570 do ist = st%st_start, st%st_end
571 ldiff(1:st%d%kpt%nlocal) = eigens%diff(ist, st%d%kpt%start:st%d%kpt%end)
572 leigenval(1:st%d%kpt%nlocal) = st%eigenval(ist, st%d%kpt%start:st%d%kpt%end)
574 eigens%diff(ist, :) = ldiff_out
575 assert(outcount == st%nik)
576 call lmpi_gen_allgatherv(st%d%kpt%nlocal, leigenval, outcount, leigenval_out, st%d%kpt%mpi_grp)
577 st%eigenval(ist, :) = leigenval_out
578 assert(outcount == st%nik)
580 safe_deallocate_a(ldiff)
581 safe_deallocate_a(ldiff_out)
582 safe_deallocate_a(leigenval)
583 safe_deallocate_a(leigenval_out)
600 select case(this%es_type)
617 select case(this%es_type)
628#include "eigensolver_inc.F90"
629#include "eigen_plan_inc.F90"
630#include "eigen_evolution_inc.F90"
633#include "complex.F90"
634#include "eigensolver_inc.F90"
635#include "eigen_plan_inc.F90"
636#include "eigen_evolution_inc.F90"
This module implements batches of mesh functions.
This module implements common operations on batches of mesh functions.
type(debug_t), save, public debug
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
type(eigen_chebyshev_t), public, protected default_chebyshev_params
Default Chebyshev input parameters Arguments 1 and 2 taken from 10.1016/j.jcp.2006....
subroutine eigensolver_run(eigens, namespace, gr, st, hm, iter, conv, nstconv)
subroutine zeigensolver_run(eigens, namespace, mesh, st, hm, iter, ik)
subroutine, public eigensolver_init(eigens, namespace, gr, st, mc, space)
integer, parameter, public rs_evo
integer, parameter, public rs_cg
subroutine deigensolver_run(eigens, namespace, mesh, st, hm, iter, ik)
logical function eigensolver_parallel_in_states(this)
integer, parameter, public rs_chebyshev
logical function eigensolver_has_progress_bar(this)
subroutine, public eigensolver_end(eigens)
integer, parameter, public rs_rmmdiis
subroutine, public exponential_init(te, namespace, full_batch)
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.
This module defines functions over batches of mesh functions.
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
character(len=512), private msg
subroutine, public messages_warning(no_lines, all_nodes, namespace)
subroutine, public messages_obsolete_variable(namespace, name, rep)
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_input_error(namespace, var, details, row, column)
subroutine, public messages_experimental(name, namespace)
This module contains some common usage patterns of MPI routines.
logical function mpi_grp_is_root(grp)
Is the current MPI process of grpcomm, root.
type(mpi_grp_t), public mpi_world
This module handles the communicators for the various parallelization strategies.
subroutine, public preconditioner_end(this)
subroutine, public preconditioner_init(this, namespace, gr, mc, space)
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
integer, parameter, public smear_semiconductor
integer, parameter, public smear_fixed_occ
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
This module provides routines for communicating states when using states parallelization.
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
This module defines the unit system, used for input and output.
type(unit_t), public unit_megabytes
For large amounts of data (natural code units are bytes)
Description of the grid, containing information on derivatives, stencil, and symmetries.
The states_elec_t class contains all electronic wave functions.