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)
362 eigens%cheby_params%n_lanczos)
403 eigens%cheby_params%optimize_degree)
417 eigens%cheby_params%bound_mixing)
429 eigens%cheby_params%n_iter)
448 eigens%folded_spectrum = .false.
457 default_tol = 1e-7_real64
459 call parse_variable(namespace,
'ConvRelDens', 1e-6_real64, default_tol)
460 default_tol = default_tol / 10.0_real64
462 call parse_variable(namespace,
'EigensolverTolerance', default_tol, eigens%tolerance)
475 call parse_variable(namespace,
'EigensolverMaxIter', default_iter, eigens%es_maxiter)
478 if(eigens%es_maxiter > default_iter)
then
479 call messages_write(
'You have specified a large number of eigensolver iterations (')
482 call messages_write(
'This is not a good idea as it might slow down convergence, even for', new_line = .
true.)
483 call messages_write(
'independent particles, as subspace diagonalization will not be used', new_line = .
true.)
492 safe_allocate(eigens%diff(1:st%nst, 1:st%nik))
493 eigens%diff(1:st%nst, 1:st%nik) = 0
495 safe_allocate(eigens%converged(1:st%nik))
496 eigens%converged(1:st%nik) = 0
499 call eigens%sdiag%init(namespace, st)
502 select case(eigens%es_type)
505 mem = (
m_two*eigens%es_maxiter -
m_one)*st%block_size*real(gr%np_part, real64)
509 mem = mem*16.0_real64
514 call messages_write(
' memory. This amount can be reduced by decreasing the value')
516 call messages_write(
' of the variable StatesBlockSize (currently set to ')
534 select case(eigens%es_type)
539 safe_deallocate_a(eigens%converged)
540 safe_deallocate_a(eigens%diff)
542 safe_deallocate_a(eigens%normalization_energies)
543 safe_deallocate_a(eigens%normalization_energies_prev)
550 subroutine eigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter, conv, nstconv)
553 type(
grid_t),
intent(in) :: gr
556 class(
space_t),
intent(in) :: space
558 integer,
intent(in) :: iter
559 logical,
optional,
intent(out) :: conv
560 integer,
optional,
intent(in) :: nstconv
565 logical :: conv_reduced
566 integer :: ist, outcount, lmatvec
567 real(real64),
allocatable :: ldiff(:), leigenval(:)
568 real(real64),
allocatable :: ldiff_out(:), leigenval_out(:)
569 integer,
allocatable ::
lconv(:)
575 if(
present(conv)) conv = .false.
576 if(
present(nstconv))
then
589 call deigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter)
591 call zeigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter)
595 write(stdout,
'(1x)')
598 if(
present(conv)) conv = all(eigens%converged(st%d%kpt%start:st%d%kpt%end) >= nstconv_)
601 if (st%d%kpt%parallel)
then
602 if (
present(conv))
then
603 call st%d%kpt%mpi_grp%allreduce(conv, conv_reduced, 1, mpi_logical, mpi_land)
607 lmatvec = eigens%matvec
608 call st%d%kpt%mpi_grp%allreduce(lmatvec, eigens%matvec, 1, mpi_integer, mpi_sum)
610 safe_allocate(
lconv(1:st%d%kpt%nlocal))
611 lconv(1:st%d%kpt%nlocal) = eigens%converged(st%d%kpt%start:st%d%kpt%end)
613 assert(outcount == st%nik)
614 safe_deallocate_a(
lconv)
617 safe_allocate(ldiff(1:st%d%kpt%nlocal))
618 safe_allocate(leigenval(1:st%d%kpt%nlocal))
619 safe_allocate(ldiff_out(1:st%nik))
620 safe_allocate(leigenval_out(1:st%nik))
621 do ist = st%st_start, st%st_end
622 ldiff(1:st%d%kpt%nlocal) = eigens%diff(ist, st%d%kpt%start:st%d%kpt%end)
623 leigenval(1:st%d%kpt%nlocal) = st%eigenval(ist, st%d%kpt%start:st%d%kpt%end)
625 eigens%diff(ist, :) = ldiff_out
626 assert(outcount == st%nik)
627 call lmpi_gen_allgatherv(st%d%kpt%nlocal, leigenval, outcount, leigenval_out, st%d%kpt%mpi_grp)
628 st%eigenval(ist, :) = leigenval_out
629 assert(outcount == st%nik)
631 safe_deallocate_a(ldiff)
632 safe_deallocate_a(ldiff_out)
633 safe_deallocate_a(leigenval)
634 safe_deallocate_a(leigenval_out)
651 select case(this%es_type)
668 select case(this%es_type)
679#include "eigensolver_inc.F90"
680#include "eigen_plan_inc.F90"
683#include "complex.F90"
684#include "eigensolver_inc.F90"
685#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.
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.