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
193 message(1) =
"The selected eigensolver is not parallel in states."
194 message(2) =
"Please use the rmmdiis or Chebyshev filtering eigensolvers."
203 select case(eigens%es_type)
218 call parse_variable(namespace,
'CGOrthogonalizeAll', .false., eigens%orthogonalize_to_all)
235 call parse_variable(namespace,
'CGDirection', option__cgdirection__fletcher, eigens%conjugate_direction)
252 call parse_variable(namespace,
'CGEnergyChangeThreshold', 0.1_real64, eigens%energy_change_threshold)
267 call parse_variable(namespace,
'EigensolverImaginaryTime', 0.1_real64, eigens%tau)
270 eigens%tau0 = eigens%tau
275 message(1) =
"Smearing of occupations is incompatible with imaginary time evolution."
301 if (eigens%it_propagator ==
it_expmid)
then
302 call hm%ks_pot%init_interpolation(eigens%vks_old)
303 call hm%ks_pot%run_zero_iter(eigens%vks_old)
313 call parse_variable(namespace,
'ImaginaryTimeVariableTimestep', .false., eigens%variable_timestep)
317 safe_allocate(eigens%normalization_energies(1:st%nst, 1:st%nik))
318 safe_allocate(eigens%normalization_energies_prev(1:st%nst, 1:st%nik))
334 call parse_variable(namespace,
'EigensolverMinimizationIter', 0, eigens%rmmdiis_minimization_iter)
354 eigens%cheby_params%n_lanczos)
395 eigens%cheby_params%optimize_degree)
409 eigens%cheby_params%bound_mixing)
421 eigens%cheby_params%n_iter)
440 eigens%folded_spectrum = .false.
449 default_tol = 1e-7_real64
451 call parse_variable(namespace,
'ConvRelDens', 1e-6_real64, default_tol)
452 default_tol = default_tol / 10.0_real64
454 call parse_variable(namespace,
'EigensolverTolerance', default_tol, eigens%tolerance)
467 call parse_variable(namespace,
'EigensolverMaxIter', default_iter, eigens%es_maxiter)
470 if(eigens%es_maxiter > default_iter)
then
471 call messages_write(
'You have specified a large number of eigensolver iterations (')
474 call messages_write(
'This is not a good idea as it might slow down convergence, even for', new_line = .
true.)
475 call messages_write(
'independent particles, as subspace diagonalization will not be used', new_line = .
true.)
480 if (any(eigens%es_type == (/rs_cg,
rs_rmmdiis/)))
then
484 safe_allocate(eigens%diff(1:st%nst, 1:st%nik))
485 eigens%diff(1:st%nst, 1:st%nik) = 0
487 safe_allocate(eigens%converged(1:st%nik))
488 eigens%converged(1:st%nik) = 0
491 call eigens%sdiag%init(namespace, st)
494 select case(eigens%es_type)
497 mem = (
m_two*eigens%es_maxiter -
m_one)*st%block_size*real(gr%np_part, real64)
501 mem = mem*16.0_real64
506 call messages_write(
' memory. This amount can be reduced by decreasing the value')
508 call messages_write(
' of the variable StatesBlockSize (currently set to ')
526 select case(eigens%es_type)
531 safe_deallocate_a(eigens%converged)
532 safe_deallocate_a(eigens%diff)
534 safe_deallocate_a(eigens%normalization_energies)
535 safe_deallocate_a(eigens%normalization_energies_prev)
542 subroutine eigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter, conv, nstconv)
545 type(
grid_t),
intent(in) :: gr
548 class(
space_t),
intent(in) :: space
550 integer,
intent(in) :: iter
551 logical,
optional,
intent(out) :: conv
552 integer,
optional,
intent(in) :: nstconv
557 logical :: conv_reduced
558 integer :: ist, outcount, lmatvec
559 real(real64),
allocatable :: ldiff(:), leigenval(:)
560 real(real64),
allocatable :: ldiff_out(:), leigenval_out(:)
561 integer,
allocatable ::
lconv(:)
567 if(
present(conv)) conv = .false.
568 if(
present(nstconv))
then
581 call deigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter)
583 call zeigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter)
587 write(stdout,
'(1x)')
590 if(
present(conv)) conv = all(eigens%converged(st%d%kpt%start:st%d%kpt%end) >= nstconv_)
593 if (st%d%kpt%parallel)
then
594 if (
present(conv))
then
595 call st%d%kpt%mpi_grp%allreduce(conv, conv_reduced, 1, mpi_logical, mpi_land)
599 lmatvec = eigens%matvec
600 call st%d%kpt%mpi_grp%allreduce(lmatvec, eigens%matvec, 1, mpi_integer, mpi_sum)
602 safe_allocate(
lconv(1:st%d%kpt%nlocal))
603 lconv(1:st%d%kpt%nlocal) = eigens%converged(st%d%kpt%start:st%d%kpt%end)
604 call lmpi_gen_allgatherv(st%d%kpt%nlocal,
lconv, outcount, eigens%converged, st%d%kpt%mpi_grp)
605 assert(outcount == st%nik)
606 safe_deallocate_a(
lconv)
609 safe_allocate(ldiff(1:st%d%kpt%nlocal))
610 safe_allocate(leigenval(1:st%d%kpt%nlocal))
611 safe_allocate(ldiff_out(1:st%nik))
612 safe_allocate(leigenval_out(1:st%nik))
613 do ist = st%st_start, st%st_end
614 ldiff(1:st%d%kpt%nlocal) = eigens%diff(ist, st%d%kpt%start:st%d%kpt%end)
615 leigenval(1:st%d%kpt%nlocal) = st%eigenval(ist, st%d%kpt%start:st%d%kpt%end)
616 call lmpi_gen_allgatherv(st%d%kpt%nlocal, ldiff, outcount, ldiff_out, st%d%kpt%mpi_grp)
617 eigens%diff(ist, :) = ldiff_out
618 assert(outcount == st%nik)
619 call lmpi_gen_allgatherv(st%d%kpt%nlocal, leigenval, outcount, leigenval_out, st%d%kpt%mpi_grp)
620 st%eigenval(ist, :) = leigenval_out
621 assert(outcount == st%nik)
623 safe_deallocate_a(ldiff)
624 safe_deallocate_a(ldiff_out)
625 safe_deallocate_a(leigenval)
626 safe_deallocate_a(leigenval_out)
643 select case(this%es_type)
660 select case(this%es_type)
671 logical,
intent(in) :: known_lower_bound
673 this%cheby_params%known_lower_bound = known_lower_bound
679#include "eigensolver_inc.F90"
682#include "complex.F90"
683#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)
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
pure subroutine eigensolver_set_lower_bound_is_known(this, known_lower_bound)
Set the flag lower_bound_is_known.
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.
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.