34 use,
intrinsic :: iso_fortran_env
73 integer,
public :: es_type
75 real(real64),
public :: tolerance
76 integer,
public :: es_maxiter
78 real(real64) :: imag_time
81 real(real64),
allocatable,
public :: diff(:, :)
82 integer,
public :: matvec
83 integer,
allocatable,
public :: converged(:)
86 type(preconditioner_t),
public :: pre
89 type(subspace_t) :: sdiag
91 integer :: rmmdiis_minimization_iter
93 logical,
public :: folded_spectrum
96 logical,
public :: orthogonalize_to_all
97 integer,
public :: conjugate_direction
98 logical,
public :: additional_terms
99 real(real64),
public :: energy_change_threshold
102 type(eigen_chebyshev_t),
public :: cheby_params
104 type(exponential_t) :: exponential_operator
110 integer,
public,
parameter :: &
121 type(eigensolver_t),
intent(out) :: eigens
122 type(namespace_t),
intent(in) :: namespace
123 type(grid_t),
intent(in) :: gr
124 type(states_elec_t),
intent(in) :: st
125 type(multicomm_t),
intent(in) :: mc
126 class(space_t),
intent(in) :: space
128 integer :: default_iter, default_es
129 real(real64) :: default_tol
168 if(st%parallel_in_states)
then
177 message(1) =
"The selected eigensolver is not parallel in states."
178 message(2) =
"Please use the rmmdiis or Chebyshev filtering eigensolvers."
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.
400 default_tol = 1e-7_real64
402 call parse_variable(namespace,
'ConvRelDens', 1e-6_real64, default_tol)
403 default_tol = default_tol / 10.0_real64
405 call parse_variable(namespace,
'EigensolverTolerance', default_tol, eigens%tolerance)
421 call parse_variable(namespace,
'EigensolverMaxIter', default_iter, eigens%es_maxiter)
424 if(eigens%es_maxiter > default_iter)
then
425 call messages_write(
'You have specified a large number of eigensolver iterations (')
428 call messages_write(
'This is not a good idea as it might slow down convergence, even for', new_line = .
true.)
429 call messages_write(
'independent particles, as subspace diagonalization will not be used', new_line = .
true.)
438 safe_allocate(eigens%diff(1:st%nst, 1:st%nik))
439 eigens%diff(1:st%nst, 1:st%nik) = 0
441 safe_allocate(eigens%converged(1:st%nik))
442 eigens%converged(1:st%nik) = 0
445 call eigens%sdiag%init(namespace, st)
448 select case(eigens%es_type)
451 mem = (
m_two*eigens%es_maxiter -
m_one)*st%block_size*real(gr%np_part, real64)
455 mem = mem*16.0_real64
460 call messages_write(
' memory. This amount can be reduced by decreasing the value')
462 call messages_write(
' of the variable StatesBlockSize (currently set to ')
480 select case(eigens%es_type)
485 safe_deallocate_a(eigens%converged)
486 safe_deallocate_a(eigens%diff)
493 subroutine eigensolver_run(eigens, namespace, gr, st, hm, iter, conv, nstconv)
496 type(
grid_t),
intent(in) :: gr
499 integer,
intent(in) :: iter
500 logical,
optional,
intent(out) :: conv
501 integer,
optional,
intent(in) :: nstconv
504 integer :: ik, ist, nstconv_
506 logical :: conv_reduced
507 integer :: outcount, lmatvec
508 real(real64),
allocatable :: ldiff(:), leigenval(:)
509 real(real64),
allocatable :: ldiff_out(:), leigenval_out(:)
510 integer,
allocatable :: lconv(:)
516 if(
present(conv)) conv = .false.
517 if(
present(nstconv))
then
529 ik_loop:
do ik = st%d%kpt%start, st%d%kpt%end
536 if (.not. eigens%folded_spectrum)
then
538 eigens%converged(ik) = 0
540 if(eigens%diff(ist, ik) < eigens%tolerance)
then
541 eigens%converged(ik) = ist
550 write(stdout,
'(1x)')
553 if(
present(conv)) conv = all(eigens%converged(st%d%kpt%start:st%d%kpt%end) >= nstconv_)
556 if (st%d%kpt%parallel)
then
557 if (
present(conv))
then
558 call st%d%kpt%mpi_grp%allreduce(conv, conv_reduced, 1, mpi_logical, mpi_land)
562 lmatvec = eigens%matvec
563 call st%d%kpt%mpi_grp%allreduce(lmatvec, eigens%matvec, 1, mpi_integer, mpi_sum)
565 safe_allocate(lconv(1:st%d%kpt%nlocal))
566 lconv(1:st%d%kpt%nlocal) = eigens%converged(st%d%kpt%start:st%d%kpt%end)
567 call lmpi_gen_allgatherv(st%d%kpt%nlocal, lconv, outcount, eigens%converged, st%d%kpt%mpi_grp)
568 assert(outcount == st%nik)
569 safe_deallocate_a(lconv)
572 safe_allocate(ldiff(1:st%d%kpt%nlocal))
573 safe_allocate(leigenval(1:st%d%kpt%nlocal))
574 safe_allocate(ldiff_out(1:st%nik))
575 safe_allocate(leigenval_out(1:st%nik))
576 do ist = st%st_start, st%st_end
577 ldiff(1:st%d%kpt%nlocal) = eigens%diff(ist, st%d%kpt%start:st%d%kpt%end)
578 leigenval(1:st%d%kpt%nlocal) = st%eigenval(ist, st%d%kpt%start:st%d%kpt%end)
580 eigens%diff(ist, :) = ldiff_out
581 assert(outcount == st%nik)
582 call lmpi_gen_allgatherv(st%d%kpt%nlocal, leigenval, outcount, leigenval_out, st%d%kpt%mpi_grp)
583 st%eigenval(ist, :) = leigenval_out
584 assert(outcount == st%nik)
586 safe_deallocate_a(ldiff)
587 safe_deallocate_a(ldiff_out)
588 safe_deallocate_a(leigenval)
589 safe_deallocate_a(leigenval_out)
606 select case(this%es_type)
623 select case(this%es_type)
634#include "eigensolver_inc.F90"
635#include "eigen_plan_inc.F90"
636#include "eigen_evolution_inc.F90"
639#include "complex.F90"
640#include "eigensolver_inc.F90"
641#include "eigen_plan_inc.F90"
642#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.
A module to handle KS potential, without the external potential.
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_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)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, 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.
logical function, public parse_is_defined(namespace, name)
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.