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 logical,
public :: additional_terms
113 real(real64),
public :: energy_change_threshold
116 type(eigen_chebyshev_t),
public :: cheby_params
118 type(exponential_t) :: exponential_operator
124 integer,
public,
parameter :: &
134 subroutine eigensolver_init(eigens, namespace, gr, st, hm, mc, space, deactivate_oracle)
135 type(eigensolver_t),
intent(out) :: eigens
136 type(namespace_t),
intent(in) :: namespace
137 type(grid_t),
intent(in) :: gr
138 type(states_elec_t),
intent(in) :: st
139 type(hamiltonian_elec_t),
intent(in) :: hm
140 type(multicomm_t),
intent(in) :: mc
141 class(space_t),
intent(in) :: space
142 logical,
optional,
intent(in) :: deactivate_oracle
144 integer :: default_iter, default_es
145 real(real64) :: default_tol
195 if(st%parallel_in_states)
then
201 call parse_variable(namespace,
'Eigensolver', default_es, eigens%es_type)
204 message(1) =
"The selected eigensolver is not parallel in states."
205 message(2) =
"Please use the rmmdiis or Chebyshev filtering eigensolvers."
214 select case(eigens%es_type)
229 call parse_variable(namespace,
'CGOrthogonalizeAll', .false., eigens%orthogonalize_to_all)
246 call parse_variable(namespace,
'CGDirection', option__cgdirection__fletcher, eigens%conjugate_direction)
259 call parse_variable(namespace,
'CGAdditionalTerms', .false., eigens%additional_terms)
260 if(eigens%additional_terms)
then
261 call messages_experimental(
"The additional terms for the CG eigensolver are not tested for all cases.")
279 call parse_variable(namespace,
'CGEnergyChangeThreshold', 0.1_real64, eigens%energy_change_threshold)
295 call parse_variable(namespace,
'EigensolverImaginaryTime', 0.1_real64, eigens%tau)
298 eigens%tau0 = eigens%tau
303 message(1) =
"Smearing of occupations is incompatible with imaginary time evolution."
329 if (eigens%it_propagator ==
it_expmid)
then
330 call hm%ks_pot%init_interpolation(eigens%vks_old)
331 call hm%ks_pot%run_zero_iter(eigens%vks_old)
341 call parse_variable(namespace,
'ImaginaryTimeVariableTimestep', .false., eigens%variable_timestep)
345 safe_allocate(eigens%normalization_energies(1:st%nst, 1:st%nik))
346 safe_allocate(eigens%normalization_energies_prev(1:st%nst, 1:st%nik))
362 call parse_variable(namespace,
'EigensolverMinimizationIter', 0, eigens%rmmdiis_minimization_iter)
379 eigens%cheby_params%n_lanczos)
420 eigens%cheby_params%optimize_degree)
434 eigens%cheby_params%bound_mixing)
446 eigens%cheby_params%n_iter)
465 eigens%folded_spectrum = .false.
474 default_tol = 1e-7_real64
476 call parse_variable(namespace,
'ConvRelDens', 1e-6_real64, default_tol)
477 default_tol = default_tol / 10.0_real64
479 call parse_variable(namespace,
'EigensolverTolerance', default_tol, eigens%tolerance)
492 call parse_variable(namespace,
'EigensolverMaxIter', default_iter, eigens%es_maxiter)
495 if(eigens%es_maxiter > default_iter)
then
496 call messages_write(
'You have specified a large number of eigensolver iterations (')
499 call messages_write(
'This is not a good idea as it might slow down convergence, even for', new_line = .
true.)
500 call messages_write(
'independent particles, as subspace diagonalization will not be used', new_line = .
true.)
509 safe_allocate(eigens%diff(1:st%nst, 1:st%nik))
510 eigens%diff(1:st%nst, 1:st%nik) = 0
512 safe_allocate(eigens%converged(1:st%nik))
513 eigens%converged(1:st%nik) = 0
516 call eigens%sdiag%init(namespace, st)
519 select case(eigens%es_type)
522 mem = (
m_two*eigens%es_maxiter -
m_one)*st%block_size*real(gr%np_part, real64)
526 mem = mem*16.0_real64
531 call messages_write(
' memory. This amount can be reduced by decreasing the value')
533 call messages_write(
' of the variable StatesBlockSize (currently set to ')
551 select case(eigens%es_type)
556 safe_deallocate_a(eigens%converged)
557 safe_deallocate_a(eigens%diff)
559 safe_deallocate_a(eigens%normalization_energies)
560 safe_deallocate_a(eigens%normalization_energies_prev)
567 subroutine eigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter, conv, nstconv)
570 type(
grid_t),
intent(in) :: gr
573 class(
space_t),
intent(in) :: space
575 integer,
intent(in) :: iter
576 logical,
optional,
intent(out) :: conv
577 integer,
optional,
intent(in) :: nstconv
582 logical :: conv_reduced
583 integer :: ist, outcount, lmatvec
584 real(real64),
allocatable :: ldiff(:), leigenval(:)
585 real(real64),
allocatable :: ldiff_out(:), leigenval_out(:)
586 integer,
allocatable ::
lconv(:)
592 if(
present(conv)) conv = .false.
593 if(
present(nstconv))
then
606 call deigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter)
608 call zeigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter)
612 write(stdout,
'(1x)')
615 if(
present(conv)) conv = all(eigens%converged(st%d%kpt%start:st%d%kpt%end) >= nstconv_)
618 if (st%d%kpt%parallel)
then
619 if (
present(conv))
then
620 call st%d%kpt%mpi_grp%allreduce(conv, conv_reduced, 1, mpi_logical, mpi_land)
624 lmatvec = eigens%matvec
625 call st%d%kpt%mpi_grp%allreduce(lmatvec, eigens%matvec, 1, mpi_integer, mpi_sum)
627 safe_allocate(
lconv(1:st%d%kpt%nlocal))
628 lconv(1:st%d%kpt%nlocal) = eigens%converged(st%d%kpt%start:st%d%kpt%end)
630 assert(outcount == st%nik)
631 safe_deallocate_a(
lconv)
634 safe_allocate(ldiff(1:st%d%kpt%nlocal))
635 safe_allocate(leigenval(1:st%d%kpt%nlocal))
636 safe_allocate(ldiff_out(1:st%nik))
637 safe_allocate(leigenval_out(1:st%nik))
638 do ist = st%st_start, st%st_end
639 ldiff(1:st%d%kpt%nlocal) = eigens%diff(ist, st%d%kpt%start:st%d%kpt%end)
640 leigenval(1:st%d%kpt%nlocal) = st%eigenval(ist, st%d%kpt%start:st%d%kpt%end)
642 eigens%diff(ist, :) = ldiff_out
643 assert(outcount == st%nik)
644 call lmpi_gen_allgatherv(st%d%kpt%nlocal, leigenval, outcount, leigenval_out, st%d%kpt%mpi_grp)
645 st%eigenval(ist, :) = leigenval_out
646 assert(outcount == st%nik)
648 safe_deallocate_a(ldiff)
649 safe_deallocate_a(ldiff_out)
650 safe_deallocate_a(leigenval)
651 safe_deallocate_a(leigenval_out)
668 select case(this%es_type)
685 select case(this%es_type)
696#include "eigensolver_inc.F90"
697#include "eigen_plan_inc.F90"
700#include "complex.F90"
701#include "eigensolver_inc.F90"
702#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.