37 use,
intrinsic :: iso_fortran_env
78 integer,
public :: es_type
80 real(real64),
public :: tolerance
81 integer,
public :: es_maxiter
86 integer :: it_propagator
87 type(potential_interpolation_t) :: vks_old
88 real(real64),
allocatable :: normalization_energies(:, :)
90 real(real64),
allocatable :: normalization_energies_prev(:, :)
92 logical :: variable_timestep
95 real(real64),
allocatable,
public :: diff(:, :)
96 integer,
public :: matvec
97 integer,
allocatable,
public :: converged(:)
100 type(preconditioner_t),
public :: pre
103 type(subspace_t) :: sdiag
105 integer :: rmmdiis_minimization_iter
107 logical,
public :: folded_spectrum
110 logical,
public :: orthogonalize_to_all
111 integer,
public :: conjugate_direction
112 real(real64),
public :: energy_change_threshold
115 type(eigen_chebyshev_t),
public :: cheby_params
117 type(exponential_t) :: exponential_operator
124 integer,
public,
parameter :: &
133 subroutine eigensolver_init(eigens, namespace, gr, st, hm, mc, space, deactivate_oracle)
134 type(eigensolver_t),
intent(out) :: eigens
135 type(namespace_t),
intent(in) :: namespace
136 type(grid_t),
intent(in) :: gr
137 type(states_elec_t),
intent(in) :: st
138 type(hamiltonian_elec_t),
intent(in) :: hm
139 type(multicomm_t),
intent(in) :: mc
140 class(space_t),
intent(in) :: space
141 logical,
optional,
intent(in) :: deactivate_oracle
143 integer :: default_iter
144 real(real64) :: default_tol
192 message(1) =
"The selected eigensolver is not parallel in states."
193 message(2) =
"Please use the rmmdiis or Chebyshev filtering eigensolvers."
202 select case(eigens%es_type)
217 call parse_variable(namespace,
'CGOrthogonalizeAll', .false., eigens%orthogonalize_to_all)
234 call parse_variable(namespace,
'CGDirection', option__cgdirection__fletcher, eigens%conjugate_direction)
251 call parse_variable(namespace,
'CGEnergyChangeThreshold', 0.1_real64, eigens%energy_change_threshold)
266 call parse_variable(namespace,
'EigensolverImaginaryTime', 0.1_real64, eigens%tau)
269 eigens%tau0 = eigens%tau
274 message(1) =
"Smearing of occupations is incompatible with imaginary time evolution."
300 if (eigens%it_propagator ==
it_expmid)
then
301 call hm%ks_pot%init_interpolation(eigens%vks_old)
302 call hm%ks_pot%run_zero_iter(eigens%vks_old)
312 call parse_variable(namespace,
'ImaginaryTimeVariableTimestep', .false., eigens%variable_timestep)
316 safe_allocate(eigens%normalization_energies(1:st%nst, 1:st%nik))
317 safe_allocate(eigens%normalization_energies_prev(1:st%nst, 1:st%nik))
333 call parse_variable(namespace,
'EigensolverMinimizationIter', 0, eigens%rmmdiis_minimization_iter)
353 eigens%cheby_params%n_lanczos)
394 eigens%cheby_params%optimize_degree)
408 eigens%cheby_params%bound_mixing)
420 eigens%cheby_params%n_iter)
439 eigens%folded_spectrum = .false.
448 default_tol = 1e-7_real64
450 call parse_variable(namespace,
'ConvRelDens', 1e-6_real64, default_tol)
451 default_tol = default_tol / 10.0_real64
453 call parse_variable(namespace,
'EigensolverTolerance', default_tol, eigens%tolerance)
466 call parse_variable(namespace,
'EigensolverMaxIter', default_iter, eigens%es_maxiter)
469 if(eigens%es_maxiter > default_iter)
then
470 call messages_write(
'You have specified a large number of eigensolver iterations (')
473 call messages_write(
'This is not a good idea as it might slow down convergence, even for', new_line = .
true.)
474 call messages_write(
'independent particles, as subspace diagonalization will not be used', new_line = .
true.)
479 if (any(eigens%es_type == (/rs_cg,
rs_rmmdiis/)))
then
483 safe_allocate(eigens%diff(1:st%nst, 1:st%nik))
484 eigens%diff(1:st%nst, 1:st%nik) = 0
486 safe_allocate(eigens%converged(1:st%nik))
487 eigens%converged(1:st%nik) = 0
490 call eigens%sdiag%init(namespace, st)
493 select case(eigens%es_type)
496 mem = (
m_two*eigens%es_maxiter -
m_one)*st%block_size*real(gr%np_part, real64)
500 mem = mem*16.0_real64
505 call messages_write(
' memory. This amount can be reduced by decreasing the value')
507 call messages_write(
' of the variable StatesBlockSize (currently set to ')
525 select case(eigens%es_type)
530 safe_deallocate_a(eigens%converged)
531 safe_deallocate_a(eigens%diff)
533 safe_deallocate_a(eigens%normalization_energies)
534 safe_deallocate_a(eigens%normalization_energies_prev)
541 subroutine eigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter, conv, nstconv)
544 type(
grid_t),
intent(in) :: gr
547 class(
space_t),
intent(in) :: space
549 integer,
intent(in) :: iter
550 logical,
optional,
intent(out) :: conv
551 integer,
optional,
intent(in) :: nstconv
556 logical :: conv_reduced
557 integer :: ist, outcount, lmatvec
558 real(real64),
allocatable :: ldiff(:), leigenval(:)
559 real(real64),
allocatable :: ldiff_out(:), leigenval_out(:)
560 integer,
allocatable ::
lconv(:)
566 if(
present(conv)) conv = .false.
567 if(
present(nstconv))
then
580 call deigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter)
582 call zeigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter)
586 write(stdout,
'(1x)')
589 if(
present(conv)) conv = all(eigens%converged(st%d%kpt%start:st%d%kpt%end) >= nstconv_)
592 if (st%d%kpt%parallel)
then
593 if (
present(conv))
then
594 call st%d%kpt%mpi_grp%allreduce(conv, conv_reduced, 1, mpi_logical, mpi_land)
598 lmatvec = eigens%matvec
599 call st%d%kpt%mpi_grp%allreduce(lmatvec, eigens%matvec, 1, mpi_integer, mpi_sum)
601 safe_allocate(
lconv(1:st%d%kpt%nlocal))
602 lconv(1:st%d%kpt%nlocal) = eigens%converged(st%d%kpt%start:st%d%kpt%end)
603 call lmpi_gen_allgatherv(st%d%kpt%nlocal,
lconv, outcount, eigens%converged, st%d%kpt%mpi_grp)
604 assert(outcount == st%nik)
605 safe_deallocate_a(
lconv)
608 safe_allocate(ldiff(1:st%d%kpt%nlocal))
609 safe_allocate(leigenval(1:st%d%kpt%nlocal))
610 safe_allocate(ldiff_out(1:st%nik))
611 safe_allocate(leigenval_out(1:st%nik))
612 do ist = st%st_start, st%st_end
613 ldiff(1:st%d%kpt%nlocal) = eigens%diff(ist, st%d%kpt%start:st%d%kpt%end)
614 leigenval(1:st%d%kpt%nlocal) = st%eigenval(ist, st%d%kpt%start:st%d%kpt%end)
615 call lmpi_gen_allgatherv(st%d%kpt%nlocal, ldiff, outcount, ldiff_out, st%d%kpt%mpi_grp)
616 eigens%diff(ist, :) = ldiff_out
617 assert(outcount == st%nik)
618 call lmpi_gen_allgatherv(st%d%kpt%nlocal, leigenval, outcount, leigenval_out, st%d%kpt%mpi_grp)
619 st%eigenval(ist, :) = leigenval_out
620 assert(outcount == st%nik)
622 safe_deallocate_a(ldiff)
623 safe_deallocate_a(ldiff_out)
624 safe_deallocate_a(leigenval)
625 safe_deallocate_a(leigenval_out)
642 select case(this%es_type)
659 select case(this%es_type)
670 logical,
intent(in) :: known_lower_bound
672 this%cheby_params%known_lower_bound = known_lower_bound
678#include "eigensolver_inc.F90"
681#include "complex.F90"
682#include "eigensolver_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 default_chebyshev_params
Default Chebyshev input parameters Arguments 1 and 2 taken from 10.1016/j.jcp.2006....
integer, parameter, public it_expmid
integer, parameter, public it_forward_euler
subroutine zeigensolver_run(eigens, namespace, mesh, st, hm, space, ext_partners, iter)
integer, parameter, public rs_evo
subroutine, public eigensolver_init(eigens, namespace, gr, st, hm, mc, space, deactivate_oracle)
subroutine deigensolver_run(eigens, namespace, mesh, st, hm, space, ext_partners, iter)
subroutine eigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter, conv, nstconv)
subroutine eigensolver_set_lower_bound_is_known(this, known_lower_bound)
Set the flag lower_bound_is_known.
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
integer, parameter, public spinors
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 classes and functions for interaction partners.
A module to handle KS potential, without the external potential.
System information (time, memory, sysname)
subroutine, public loct_progress_bar(a, maxcount)
A wrapper around the progress bar, such that it can be silenced without needing to dress the call wit...
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.
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.