MCPcopy Create free account
hub / github.com/SZAILAB/MaterialDFT-Demo / resolve_electronic_convergence

Function resolve_electronic_convergence

cpp_core/src/scf.cpp:1432–1494  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1430};
1431
1432ElectronicConvergenceState resolve_electronic_convergence(
1433 double delta_e_ha,
1434 double eval_change_abs_ha,
1435 double residual_inf,
1436 int electronic_step,
1437 bool density_update_delayed,
1438 int imix_effective,
1439 const ScfSettings& settings,
1440 bool has_nonlocal,
1441 const EnergyComponents& energy
1442) {
1443 ElectronicConvergenceState state;
1444 const bool use_ediff = settings.ediff_ha > 0.0 && !settings.use_rho_tol_primary;
1445 // The primary SCF stop metric is exclusive: contract-facing calls use ediff,
1446 // while explicit rho_tol_inf requests opt into the MaterialDFT density criterion.
1447 const bool use_rho_tol = settings.rho_tol_inf > 0.0 && !use_ediff;
1448 state.ediff_met = use_ediff
1449 && std::isfinite(delta_e_ha)
1450 && std::isfinite(eval_change_abs_ha)
1451 && std::max(delta_e_ha, eval_change_abs_ha) < settings.ediff_ha;
1452 state.energy_converged = state.ediff_met;
1453 state.density_converged = use_rho_tol && residual_inf < settings.rho_tol_inf;
1454 bool candidate_converged = state.energy_converged || state.density_converged;
1455 if (should_reset_convergence_for_nonlocal_mismatch(
1456 has_nonlocal,
1457 settings.smearing_sigma_ha,
1458 candidate_converged,
1459 energy.e_nl_mismatch_ha)) {
1460 state = ElectronicConvergenceState{};
1461 candidate_converged = false;
1462 }
1463 if (should_throw_for_nonlocal_mismatch(
1464 has_nonlocal,
1465 settings.smearing_sigma_ha,
1466 settings.rho_tol_inf,
1467 candidate_converged,
1468 energy.e_nl_mismatch_ha)) {
1469 throw std::runtime_error(nonlocal_mismatch_error_message(energy));
1470 }
1471 state.mixing_gate_open = !density_update_delayed || imix_effective == 0;
1472 const int requested_nelmdl_delay_steps = settings.nelmdl == std::numeric_limits<int>::min()
1473 ? std::numeric_limits<int>::max()
1474 : std::abs(settings.nelmdl);
1475 state.nelmdl_gate_open = electronic_step > requested_nelmdl_delay_steps;
1476 const int effective_nelmin = std::min(std::max(1, settings.nelmin), settings.max_iter);
1477 state.nelmin_gate_open = electronic_step >= effective_nelmin;
1478 state.nelm_gate_hit = electronic_step >= settings.max_iter;
1479 state.converged_now = candidate_converged
1480 && state.mixing_gate_open
1481 && state.nelmdl_gate_open
1482 && state.nelmin_gate_open;
1483 if (state.nelm_gate_hit && !state.converged_now) {
1484 state.abort_without_conv = settings.max_iter > 1;
1485 state.stop_reason = "nelm_reached_unconverged";
1486 return state;
1487 }
1488 if (state.converged_now) {
1489 state.stop_reason = state.energy_converged

Callers 1

run_scf_kpoints_hartreeFunction · 0.85

Tested by

no test coverage detected