Skip to content

Commit 85eaa36

Browse files
return ne_diff
1 parent 3415d35 commit 85eaa36

3 files changed

Lines changed: 22 additions & 10 deletions

File tree

src/dft/dft_ground_state.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ DFT_ground_state::energy_kin_sum_pw() const
6969
for (auto it : kset_.spl_num_kpoints()) {
7070
auto kp = kset_.get<double>(it.i);
7171

72-
#pragma omp parallel for schedule(static) reduction(+:ekin)
72+
#pragma omp parallel for schedule(static) reduction(+ : ekin)
7373
for (int igloc = 0; igloc < kp->num_gkvec_loc(); igloc++) {
7474
auto Gk = kp->gkvec().gkvec_cart(gvec_index_t::local(igloc));
7575

@@ -201,6 +201,8 @@ DFT_ground_state::find(double density_tol__, double energy_tol__, double iter_so
201201
<< "num_dft_iter : " << num_dft_iter__;
202202
ctx_.message(1, __func__, s);
203203

204+
double ne_diff = 0;
205+
204206
for (int iter = 0; iter < num_dft_iter__; iter++) {
205207
PROFILE("sirius::DFT_ground_state::scf_loop|iteration");
206208
std::stringstream s;
@@ -225,7 +227,7 @@ DFT_ground_state::find(double density_tol__, double energy_tol__, double iter_so
225227
ctx_.cfg().iterative_solver().num_steps());
226228
}
227229
/* find band occupancies */
228-
kset_.find_band_occupancies<float>();
230+
ne_diff = kset_.find_band_occupancies<float>();
229231
/* generate new density from the occupied wave-functions */
230232
density_.generate<float>(kset_, ctx_.use_symmetry(), true, true);
231233
#else
@@ -237,7 +239,7 @@ DFT_ground_state::find(double density_tol__, double energy_tol__, double iter_so
237239
result = sirius::diagonalize<double, double>(H0, kset_, iter_solver_tol__,
238240
ctx_.cfg().iterative_solver().num_steps());
239241
/* find band occupancies */
240-
kset_.find_band_occupancies<double>();
242+
ne_diff = kset_.find_band_occupancies<double>();
241243
/* generate new density from the occupied wave-functions */
242244
density_.generate<double>(kset_, ctx_.use_symmetry(), true, true);
243245
}
@@ -356,6 +358,12 @@ DFT_ground_state::find(double density_tol__, double energy_tol__, double iter_so
356358
converged = converged && (rms < density_tol__);
357359
}
358360
if (converged) {
361+
if (std::abs(ne_diff) > 0) {
362+
std::stringstream ss;
363+
ss << "Newton minimization didn't respect correct number of electrons, ne_diff=" << ne_diff;
364+
ss << "\nReduce smearing width!";
365+
RTE_THROW(ss.str());
366+
}
359367
std::stringstream out;
360368
out << std::endl;
361369
out << "converged after " << iter + 1 << " SCF iterations!" << std::endl;

src/k_point/k_point_set.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ bisection_search(F&& f, double a, double b, double tol, int maxstep = 1000)
199199
}
200200

201201
template <typename T>
202-
void
202+
double
203203
K_point_set::find_band_occupancies()
204204
{
205205
PROFILE("sirius::K_point_set::find_band_occupancies");
@@ -209,7 +209,7 @@ K_point_set::find_band_occupancies()
209209
auto band_occ_callback = ctx_.band_occ_callback();
210210
if (band_occ_callback) {
211211
band_occ_callback();
212-
return;
212+
return 0;
213213
}
214214

215215
/* target number of electrons */
@@ -239,7 +239,7 @@ K_point_set::find_band_occupancies()
239239
}
240240

241241
this->sync_band<T, sync_band_t::occupancy>();
242-
return;
242+
return 0;
243243
}
244244

245245
if (ctx_.smearing_width() == 0) {
@@ -298,6 +298,7 @@ K_point_set::find_band_occupancies()
298298
}
299299
this->energy_fermi_ = res_bisection.value();
300300

301+
double ne_diff = 0;
301302
/* for cold and Methfessel Paxton smearing start newton minimization */
302303
if (ctx_.smearing() == smearing::smearing_t::cold || ctx_.smearing() == smearing::smearing_t::methfessel_paxton) {
303304
f = smearing::occupancy(ctx_.smearing(), ctx_.smearing_width());
@@ -313,6 +314,7 @@ K_point_set::find_band_occupancies()
313314
RTE_OUT(ctx_.out()) << "newton iteration converged after " << res_newton.value().iter << " steps\n";
314315
RTE_OUT(ctx_.out()) << "newton iteration ne_diff " << res_newton.value().ne_diff << " steps\n";
315316
}
317+
ne_diff = res_newton.value().ne_diff;
316318
} else {
317319
// Newton has failed, fallback to bisection
318320
if (ctx_.verbosity() >= 2) {
@@ -373,12 +375,14 @@ K_point_set::find_band_occupancies()
373375
band_gap_ = eband[ist].first - eband[ist - 1].second;
374376
}
375377
}
378+
return ne_diff;
376379
}
377380

378-
template void
381+
382+
template double
379383
K_point_set::find_band_occupancies<double>();
380384
#if defined(SIRIUS_USE_FP32)
381-
template void
385+
template double
382386
K_point_set::find_band_occupancies<float>();
383387
#endif
384388

src/k_point/k_point_set.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ class K_point_set
109109
void
110110
sync_band();
111111

112-
/// Find Fermi energy and band occupation numbers.
112+
/// Find Fermi energy and band occupation numbers. Returns ne_diff (Newton protocol)
113113
template <typename T>
114-
void
114+
double
115115
find_band_occupancies();
116116

117117
/// Print basic info to the standard output.

0 commit comments

Comments
 (0)