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
123 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, default_es
144 real(real64) :: default_tol
194 if(st%parallel_in_states)
then
203 message(1) =
"The selected eigensolver is not parallel in states."
204 message(2) =
"Please use the rmmdiis or Chebyshev filtering eigensolvers."
213 select case(eigens%es_type)
228 call parse_variable(namespace,
'CGOrthogonalizeAll', .false., eigens%orthogonalize_to_all)
245 call parse_variable(namespace,
'CGDirection', option__cgdirection__fletcher, eigens%conjugate_direction)
262 call parse_variable(namespace,
'CGEnergyChangeThreshold', 0.1_real64, eigens%energy_change_threshold)
278 call parse_variable(namespace,
'EigensolverImaginaryTime', 0.1_real64, eigens%tau)
281 eigens%tau0 = eigens%tau
286 message(1) =
"Smearing of occupations is incompatible with imaginary time evolution."
312 if (eigens%it_propagator ==
it_expmid)
then
313 call hm%ks_pot%init_interpolation(eigens%vks_old)
314 call hm%ks_pot%run_zero_iter(eigens%vks_old)
324 call parse_variable(namespace,
'ImaginaryTimeVariableTimestep', .false., eigens%variable_timestep)
328 safe_allocate(eigens%normalization_energies(1:st%nst, 1:st%nik))
329 safe_allocate(eigens%normalization_energies_prev(1:st%nst, 1:st%nik))
345 call parse_variable(namespace,
'EigensolverMinimizationIter', 0, eigens%rmmdiis_minimization_iter)
365 eigens%cheby_params%n_lanczos)
406 eigens%cheby_params%optimize_degree)
420 eigens%cheby_params%bound_mixing)
432 eigens%cheby_params%n_iter)
451 eigens%folded_spectrum = .false.
460 default_tol = 1e-7_real64
462 call parse_variable(namespace,
'ConvRelDens', 1e-6_real64, default_tol)
463 default_tol = default_tol / 10.0_real64
465 call parse_variable(namespace,
'EigensolverTolerance', default_tol, eigens%tolerance)
478 call parse_variable(namespace,
'EigensolverMaxIter', default_iter, eigens%es_maxiter)
481 if(eigens%es_maxiter > default_iter)
then
482 call messages_write(
'You have specified a large number of eigensolver iterations (')
485 call messages_write(
'This is not a good idea as it might slow down convergence, even for', new_line = .
true.)
486 call messages_write(
'independent particles, as subspace diagonalization will not be used', new_line = .
true.)
495 safe_allocate(eigens%diff(1:st%nst, 1:st%nik))
496 eigens%diff(1:st%nst, 1:st%nik) = 0
498 safe_allocate(eigens%converged(1:st%nik))
499 eigens%converged(1:st%nik) = 0
502 call eigens%sdiag%init(namespace, st)
505 select case(eigens%es_type)
508 mem = (
m_two*eigens%es_maxiter -
m_one)*st%block_size*real(gr%np_part, real64)
512 mem = mem*16.0_real64
517 call messages_write(
' memory. This amount can be reduced by decreasing the value')
519 call messages_write(
' of the variable StatesBlockSize (currently set to ')
537 select case(eigens%es_type)
542 safe_deallocate_a(eigens%converged)
543 safe_deallocate_a(eigens%diff)
545 safe_deallocate_a(eigens%normalization_energies)
546 safe_deallocate_a(eigens%normalization_energies_prev)
553 subroutine eigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter, conv, nstconv)
556 type(
grid_t),
intent(in) :: gr
559 class(
space_t),
intent(in) :: space
561 integer,
intent(in) :: iter
562 logical,
optional,
intent(out) :: conv
563 integer,
optional,
intent(in) :: nstconv
568 logical :: conv_reduced
569 integer :: ist, outcount, lmatvec
570 real(real64),
allocatable :: ldiff(:), leigenval(:)
571 real(real64),
allocatable :: ldiff_out(:), leigenval_out(:)
572 integer,
allocatable ::
lconv(:)
578 if(
present(conv)) conv = .false.
579 if(
present(nstconv))
then
592 call deigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter)
594 call zeigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter)
598 write(stdout,
'(1x)')
601 if(
present(conv)) conv = all(eigens%converged(st%d%kpt%start:st%d%kpt%end) >= nstconv_)
604 if (st%d%kpt%parallel)
then
605 if (
present(conv))
then
606 call st%d%kpt%mpi_grp%allreduce(conv, conv_reduced, 1, mpi_logical, mpi_land)
610 lmatvec = eigens%matvec
611 call st%d%kpt%mpi_grp%allreduce(lmatvec, eigens%matvec, 1, mpi_integer, mpi_sum)
613 safe_allocate(
lconv(1:st%d%kpt%nlocal))
614 lconv(1:st%d%kpt%nlocal) = eigens%converged(st%d%kpt%start:st%d%kpt%end)
615 call lmpi_gen_allgatherv(st%d%kpt%nlocal,
lconv, outcount, eigens%converged, st%d%kpt%mpi_grp)
616 assert(outcount == st%nik)
617 safe_deallocate_a(
lconv)
620 safe_allocate(ldiff(1:st%d%kpt%nlocal))
621 safe_allocate(leigenval(1:st%d%kpt%nlocal))
622 safe_allocate(ldiff_out(1:st%nik))
623 safe_allocate(leigenval_out(1:st%nik))
624 do ist = st%st_start, st%st_end
625 ldiff(1:st%d%kpt%nlocal) = eigens%diff(ist, st%d%kpt%start:st%d%kpt%end)
626 leigenval(1:st%d%kpt%nlocal) = st%eigenval(ist, st%d%kpt%start:st%d%kpt%end)
627 call lmpi_gen_allgatherv(st%d%kpt%nlocal, ldiff, outcount, ldiff_out, st%d%kpt%mpi_grp)
628 eigens%diff(ist, :) = ldiff_out
629 assert(outcount == st%nik)
630 call lmpi_gen_allgatherv(st%d%kpt%nlocal, leigenval, outcount, leigenval_out, st%d%kpt%mpi_grp)
631 st%eigenval(ist, :) = leigenval_out
632 assert(outcount == st%nik)
634 safe_deallocate_a(ldiff)
635 safe_deallocate_a(ldiff_out)
636 safe_deallocate_a(leigenval)
637 safe_deallocate_a(leigenval_out)
654 select case(this%es_type)
671 select case(this%es_type)
682#include "eigensolver_inc.F90"
683#include "eigen_plan_inc.F90"
686#include "complex.F90"
687#include "eigensolver_inc.F90"
688#include "eigen_plan_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)
integer, parameter, public rs_cg
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
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.
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.