25#ifndef __DIAGONALIZE_HPP__
26#define __DIAGONALIZE_HPP__
36 double avg_num_iter{0};
44template <
typename T,
typename F>
48 PROFILE(
"sirius::diagonalize");
50 auto& ctx = H0__.ctx();
51 print_memory_usage(ctx.out(),FILE_LINE);
55 auto& itso = ctx.cfg().iterative_solver();
57 double empy_tol{itsol_tol__};
58 if (itso.type() ==
"davidson") {
59 empy_tol = std::max(itsol_tol__ * ctx.cfg().settings().itsol_tol_ratio(), itso.empty_states_tolerance());
60 RTE_OUT(ctx.out(2)) <<
"iterative solver tolerance (occupied, empty): " << itsol_tol__ <<
" "
61 << itsol_tol__ + empy_tol << std::endl;
67 for (
auto it : kset__.spl_num_kpoints()) {
68 auto kp = kset__.get<T>(it.i);
71 if (ctx.full_potential()) {
72 diagonalize_fp<T>(Hk, *kp, itsol_tol__);
74 if (itso.type() ==
"exact") {
75 if (ctx.gamma_point() || ctx.num_mag_dims() == 3) {
76 RTE_THROW(
"not implemented");
78 for (
int ispn = 0; ispn < ctx.num_spins(); ispn++) {
79 diagonalize_pp_exact<T, std::complex<F>>(ispn, Hk, *kp);
82 if (ctx.gamma_point() && (ctx.so_correction() ==
false)) {
83 result.davidson_result = diagonalize_pp<T, F>(Hk, *kp, itsol_tol__, empy_tol);
85 result.davidson_result = diagonalize_pp<T, std::complex<F>>(Hk, *kp, itsol_tol__, empy_tol);
87 num_dav_iter += result.davidson_result.
niter;
88 converged = converged & result.davidson_result.
converged;
92 kset__.comm().allreduce(&num_dav_iter, 1);
93 kset__.comm().allreduce<bool, mpi::op_t::land>(&converged, 1);
94 ctx.num_itsol_steps(num_dav_iter);
95 result.avg_num_iter =
static_cast<double>(num_dav_iter) / kset__.
num_kpoints();
96 result.converged = converged;
97 if (!ctx.full_potential()) {
98 RTE_OUT(ctx.out(2)) <<
"average number of iterations: " << result.avg_num_iter << std::endl;
102 kset__.
sync_band<T, sync_band_t::energy>();
104 if (ctx.verbosity() >= 2) {
106 s <<
"Lowest band energies" << std::endl;
107 int nbnd = std::min(ctx.cfg().control().num_bands_to_print(), ctx.num_bands());
108 for (
int ik = 0; ik < kset__.
num_kpoints(); ik++) {
109 s <<
"ik:" << std::setw(5) << ik;
110 for (
int j = 0; j < nbnd; j++) {
111 s <<
ffmt(12, 6) << kset__.get<T>(ik)->band_energy(j, 0);
113 if (ctx.num_mag_dims() == 1) {
114 s << std::endl <<
" ";
115 for (
int j = 0; j < nbnd; j++) {
116 s <<
ffmt(12, 6) << kset__.get<T>(ik)->band_energy(j, 1);
121 RTE_OUT(ctx.out(2)) << s.str();
123 print_memory_usage(ctx.out(), FILE_LINE);
Represent the k-point independent part of Hamiltonian.
int num_kpoints() const
Return total number of k-points.
void sync_band()
Sync band energies or occupancies between all MPI ranks.
Floating-point formatting (precision and width).
Diagonalize full-potential LAPW Hamiltonian.
Diagonalize pseudo-potential Hamiltonian.
Contains declaration and partial implementation of sirius::K_point_set class.
Namespace of the SIRIUS library.
auto diagonalize(Hamiltonian0< T > const &H0__, K_point_set &kset__, double itsol_tol__)
Diagonalize KS Hamiltonian for all k-points in the set.
Result of Davidson solver.
bool converged
True if all bands (up and dn) are converged.
int niter
Number of iterations.