Loading...
Searching...
No Matches
init.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * KohnShamSCFIterator — Kohn-Sham DFT cycle.
5 *
6 * Owns charge density, effective potential, XC functional, mixer, occupations,
7 * and the fixed Kohn-Sham iteration order. Configuration is provided via
8 * KohnShamSCFIteratorConfig which extends SCFIteratorConfig.
9 */
10
11#include <algorithm>
12#include <chrono>
13#include <memory>
14#include <stdexcept>
15#include <string>
16#include <vector>
17
18#include "io/logger.hpp"
37
38namespace q3 {
39
41 // === Kohn-Sham level ===
43 std::string mixing_mode = "broyden";
46 std::string mixing_preconditioning = "default";
48 std::string smearing = "none";
50 int methfessel_paxton_order = 1; // used only by Methfessel-Paxton smearing
51 std::string dispersion_correction = "none"; // "none" or "d3bj"
52 Real total_charge = 0.0; // electrons removed (QE tot_charge convention)
53 std::vector<HubbardSpecification> hubbard; // DFT+U (Dudarev); empty = no correction
54 /// First-iteration occupation-eigenvalue overrides; empty = no seeding.
55 std::vector<HubbardStartingEigenvalue> hubbard_starting_eigenvalues;
56 /// Iterations for which the seeded occupation matrix is held; 0 = first iteration only.
58 /**
59 * "atomic" (raw pseudo-atomic orbitals) or "ortho-atomic" (Lowdin-orthogonalized
60 * over the full system-wide orbital set) -- see InputData::hubbard_projector_type.
61 */
62 std::string hubbard_projector_type = "atomic";
63
64 // === Planewave level ===
65 const KPointsGrid* kpoint_grid = nullptr;
67 Real charge_density_energy_cutoff = 0.0; // Ry (0 → auto = 4 × wfc cutoff)
68 int number_of_bands = 0; // 0 → auto
69 std::string diagonalization_method = "davidson";
71 /**
72 * false (default) = FFTW_MEASURE (fastest, but per-process-timed and so
73 * not bit-reproducible run to run); true = FFTW_ESTIMATE (deterministic).
74 * See InputData::use_deterministic_fft_planning and TODOs.md §2.3.
75 */
77 /**
78 * false (default) = the faster, approximate 2 x ecutwfc wavefunction FFT grid;
79 * true = the exact grid (4 x ecutwfc, as pw.x sizes it). See
80 * InputData::use_exact_wavefunction_grid.
81 */
83 /**
84 * true = use no symmetry at all. The k-point mesh is left unreduced by
85 * build_global_kpoint_grid_from_input, and the iterator then leaves the density
86 * unsymmetrized too, so a full-zone run is the raw-mesh answer (QE's nosym + noinv)
87 * rather than the symmetrized-mesh one. See InputData::disable_symmetry.
88 */
89 bool disable_symmetry = false;
90
91 // === Pseudopotential level ===
93 std::string calculation = "self_consistent_field";
94 /**
95 * Initial magnetization per species (parallel to the crystal's species list,
96 * values in [-1, 1]; may be shorter — missing entries mean 0; empty = unset).
97 */
98 std::vector<Real> starting_magnetization;
99 /**
100 * Initial magnetization per atom (parallel to the crystal's atoms, values in
101 * [-1, 1]); empty = unset. When set it takes precedence over the per-species
102 * `starting_magnetization`.
103 */
105 std::vector<std::pair<std::string, Vector3D>> band_path;
107 std::string nonlocal_stress_derivative_method = "analytical";
108
109 // === Implementation selectors ===
110 std::string basis_type = "planewave";
111 std::string representation_type = "pseudopotential";
112
113 /**
114 * === Parallelism (optional) ===
115 * null means serial; set to an active PlanewaveExecutionPolicy for pool-based k-point
116 * parallelism.
117 */
119};
120
122 public:
125 , config_(std::move(config))
126 , exchange_correlation_functional_(config_.exchange_correlation_functional)
127 , mixing_mode_(config_.mixing_mode)
128 , mixing_beta_(config_.mixing_beta)
129 , mixing_history_size_(config_.mixing_history_size)
130 , mixing_preconditioning_(config_.mixing_preconditioning)
131 , mixing_q0_(config_.mixing_q0)
132 , smearing_(config_.smearing)
133 , smearing_width_(config_.smearing_width)
134 , methfessel_paxton_order_(config_.methfessel_paxton_order) {
135 if (mixing_preconditioning_ == "default") {
136 if (smearing_ != "none") {
137 mixing_preconditioning_ = "kerker";
138 } else {
140 }
141 }
142 /**
143 * Validate here, where "default" has just been resolved and before any
144 * representation exists to build a preconditioner from. An unrecognized
145 * value used to fall through to a `== "kerker"` test further down and
146 * silently disable preconditioning: `preconditioning: kerkar` cost a
147 * slower run and produced no diagnostic to explain it.
148 */
150 throw std::runtime_error("Unknown mixing preconditioner: '" + mixing_preconditioning_ +
151 "'. Supported values: 'default', 'none', 'kerker', "
152 "'local-tf'.");
153 }
154 }
155
156 ~KohnShamSCFIterator() override = default;
157
158 // Stored configuration — must be declared before fields that reference it in the ctor.
160
161 // Configuration fields — initialized from config_ in the constructor.
163 std::string mixing_mode_;
168 std::string smearing_;
171
172 /// One row per SCF iteration, in order; the source for per-iteration companion outputs.
179
180 [[nodiscard]] const std::vector<ScfIterationRecord>& scf_history() const {
181 return scf_history_;
182 }
183
184 virtual const KohnShamEnergies& energies() const = 0;
186
187 [[nodiscard]] Real total_energy() const override {
188 return energies().total();
189 }
190 [[nodiscard]] const XCFunctional& exchange_correlation() const {
191 return *exchange_correlation_;
192 }
193
194 [[nodiscard]] const std::vector<Complex>& charge_density_g() const {
195 return charge_density_g_;
196 }
197 [[nodiscard]] const std::vector<Real>& charge_density_real() const {
198 return charge_density_real_[0];
199 }
200 [[nodiscard]] const std::vector<Real>& charge_density_for_spin(int spin_index) const {
201 return charge_density_real_[spin_index];
202 }
203 [[nodiscard]] const std::vector<Real>& real_space_potential() const {
204 return real_space_potential_[0];
205 }
206 [[nodiscard]] const std::vector<Real>& potential_for_spin(int spin_index) const {
207 return real_space_potential_[spin_index];
208 }
209 [[nodiscard]] const std::vector<Complex>& total_potential_g() const {
210 return total_potential_g_;
211 }
212 [[nodiscard]] const std::vector<Complex>& exchange_correlation_potential_g() const {
214 }
215
216 /**
217 * Access the crystal structure owned or referenced by this iterator.
218 */
219 [[nodiscard]] Crystal& crystal_structure() const {
220 return *crystal_structure_;
221 }
222
223 /**
224 * Load a pre-computed effective potential directly into real_space_potential_.
225 *
226 * Used by the NSCF flavor to inject V_eff loaded from a v2 checkpoint
227 * instead of computing it from scratch via compute_effective_potential_from_density().
228 * Must be called after iterator construction but before run().
229 */
230 void load_effective_potential(std::vector<std::vector<Real>> effective_potential) {
231 real_space_potential_ = std::move(effective_potential);
233 }
234
235 void load_charge_density(std::vector<std::vector<Real>> charge_density) {
236 charge_density_real_ = std::move(charge_density);
239 }
240
241 /**
242 * Offer a density to start from, as a previous geometry's saved one is
243 * offered (startingpot = 'file'). Unlike load_charge_density(), which asks
244 * for exactly that density, an offer this run's grid cannot take is
245 * declined, and the SCF starts from overlapping atoms instead; one it can
246 * take is rescaled to this system's electron count, since the cell may
247 * have changed since it was saved.
248 */
249 void offer_starting_charge_density(std::vector<std::vector<Real>> charge_density) {
250 charge_density_real_ = std::move(charge_density);
253 }
254
255 protected:
256 [[nodiscard]] const KohnShamSCFIteratorConfig& config() const {
257 return config_;
258 }
259
260 std::vector<Complex> charge_density_g_;
261 std::vector<std::vector<Real>> charge_density_real_;
262 std::vector<std::vector<Real>> real_space_potential_;
263 std::vector<Complex> total_potential_g_;
264
265 /**
266 * The same potential per spin channel, un-averaged.
267 *
268 * `total_potential_g_` above is the spin average, which the nonlocal D was
269 * historically built from. That is exact for a non-magnetic cell and wrong
270 * for a magnetic one, because D_ij = D_ion + ∫v_eff·Q_ij inherits v_eff's
271 * spin dependence. Empty on paths that never filled it, in which case
272 * consumers fall back to the average.
273 */
274 std::vector<std::vector<Complex>> total_potential_g_by_spin_;
276
277 /**
278 * True when V_eff has been injected via load_effective_potential().
279 * When set, update_effective_potential() must not overwrite real_space_potential_.
280 */
283 /// Set by offer_starting_charge_density(): a density that need not fit.
285
286 std::unique_ptr<XCFunctional> exchange_correlation_;
287 std::unique_ptr<Mixer> mixer_;
288 std::unique_ptr<SmearingScheme> smearing_scheme_;
289
290 // KS-level iteration state
293 std::vector<ScfIterationRecord> scf_history_;
296
297 /**
298 * The eigenvalue threshold the diagonalizer runs at: the schedule's value,
299 * held at the floor below which the solvers resolve no further change.
300 */
304
305 void initialize() override {
307 density_residual_ = 1.0;
308
313
314 auto timer_start = std::chrono::high_resolution_clock::now();
316 auto timer_repr = std::chrono::high_resolution_clock::now();
319 auto timer_charge = std::chrono::high_resolution_clock::now();
321 auto timer_wfc = std::chrono::high_resolution_clock::now();
322
323 /**
324 * Keep the atomic superposition density as the input for the first SCF iteration,
325 * matching QE's ordering — potential from the atomic superposition, then wavefunction
326 * initialization from that potential, then the SCF loop. The effective potential
327 * from the atomic density was already computed during initialize_single_particle_states().
328 * Do NOT reconstruct density from wavefunctions here — doing so creates a nearly
329 * self-consistent wfc-based density that gives the Broyden mixer a near-zero first
330 * residual, corrupting its history and causing ~30 extra iterations.
331 */
332
333 log::debug(" Init timing breakdown:");
334 log::debug(" representation: {:.1f} ms",
335 std::chrono::duration<double, std::milli>(timer_repr - timer_start).count());
336 log::debug(" charge_density+mixer: {:.1f} ms",
337 std::chrono::duration<double, std::milli>(timer_charge - timer_repr).count());
338 log::debug(" wfc_init: {:.1f} ms",
339 std::chrono::duration<double, std::milli>(timer_wfc - timer_charge).count());
340
341 SCFIterator::initialize(); // prints SCF banner
342 }
343
344 void perform_iteration() override {
345 auto timer_iter_start = std::chrono::high_resolution_clock::now();
346 auto mixing_input_density = input_density_for_mixing();
347
348 // 1. Solve single-particle states using the current potential
350 auto timer_prep_end = std::chrono::high_resolution_clock::now();
353 auto timer_solve_end = std::chrono::high_resolution_clock::now();
356 auto timer_occupations_end = std::chrono::high_resolution_clock::now();
357
358 // 2. Construct new density from wavefunctions
360 auto timer_density_end = std::chrono::high_resolution_clock::now();
362 auto timer_symm_end = std::chrono::high_resolution_clock::now();
363
364 /**
365 * 3. Compute double-counting correction using the CURRENT potential
366 * (V_Hxc built from previous iteration's mixed density) and the NEW output density.
367 * This is the band-energy double-counting term as QE defines it:
368 * deband = -Σ ρ_out(r) · V_Hxc(r)
369 */
372
373 // 4. Compute residual and check convergence
374 density_residual_ = compute_density_residual(mixing_input_density);
375
376 /**
377 * 4a. First-iteration re-diagonalization (matching QE's SCF loop):
378 * If the density residual is smaller than the estimated diagonalization error,
379 * the eigenvalue threshold was too loose — re-diag with a tighter threshold.
380 * This is critical for avoiding the false fixed-point trap in small systems.
381 *
382 * The error estimate is the threshold the diagonalization actually ran
383 * at, times the electron count, as in QE's electrons_scf
384 * (PW/src/electrons.f90), and only a diagonalization that ran looser
385 * than the residual now asks for is repeated. A self-consistent run's
386 * first diagonalization runs at the loose initial threshold, so this is
387 * the 1e-2 rule it always was. A non-self-consistent pass has already
388 * run at the floor: there the "tighter" threshold was 0.1 dr2 / N,
389 * 7.8e-4 Ry for silicon's two irreducible k-points, and the repeat
390 * loosened the pass it was meant to sharpen -- and, seeding each
391 * k-point from the one before, left the second up to 4.4e-5 Ry off in
392 * its occupied bands.
393 */
395 const Real threshold_used = diagonalization_threshold();
396 Real diagonalization_error_estimate =
397 threshold_used * std::max(1.0, number_of_electrons());
398 Real tighter_threshold =
399 std::max(0.1 * density_residual_ / std::max(1.0, number_of_electrons()),
401 if (density_residual_ < diagonalization_error_estimate &&
402 tighter_threshold < threshold_used) {
403 log::info(" Re-diagonalizing with tighter threshold "
404 "(dr2={:.2e} < tr2_min={:.2e})",
406 diagonalization_error_estimate);
408
409 /**
410 * Re-compute with tighter tolerance using the SAME potential
411 * (matching QE, which restarts the SCF step without mixing
412 * before the re-diagonalization)
413 */
414 set_diagonalizer_tolerance(tighter_threshold);
415
419
420 // Recompute density/energy with the improved wavefunctions
426 density_residual_ = compute_density_residual(mixing_input_density);
427
428 // Reset mixer history — the coarse first-iteration data is misleading
429 mixer_->reset();
430 }
431 }
432 auto timer_residual_end = std::chrono::high_resolution_clock::now();
433
434 auto log_iteration_timing = [&](auto timer_mix_end, auto timer_potential_end) {
435 log::debug(" Iteration timing breakdown:");
436 log::debug(" prepare_hamiltonian: {:.1f} ms",
437 std::chrono::duration<double, std::milli>(timer_prep_end - timer_iter_start)
438 .count());
439 log::debug(" solve_states: {:.1f} ms",
440 std::chrono::duration<double, std::milli>(timer_solve_end - timer_prep_end)
441 .count());
443 " update_occupations: {:.1f} ms",
444 std::chrono::duration<double, std::milli>(timer_occupations_end - timer_solve_end)
445 .count());
447 " construct_density: {:.1f} ms",
448 std::chrono::duration<double, std::milli>(timer_density_end - timer_occupations_end)
449 .count());
450 log::debug(" symmetrize_density: {:.1f} ms",
451 std::chrono::duration<double, std::milli>(timer_symm_end - timer_density_end)
452 .count());
454 " deband+residual: {:.1f} ms",
455 std::chrono::duration<double, std::milli>(timer_residual_end - timer_symm_end)
456 .count());
457 log::debug(" mix+sync: {:.1f} ms",
458 std::chrono::duration<double, std::milli>(timer_mix_end - timer_residual_end)
459 .count());
461 " update_potential: {:.1f} ms",
462 std::chrono::duration<double, std::milli>(timer_potential_end - timer_mix_end)
463 .count());
465 " total_iteration: {:.1f} ms",
466 std::chrono::duration<double, std::milli>(timer_potential_end - timer_iter_start)
467 .count());
470 };
471
473
475 log_iteration_timing(timer_residual_end, timer_residual_end);
476 return; // Don't mix — will be handled by finalize()
477 }
478
479 // 5. Mix density to get next input density
480 mix_density(mixing_input_density);
481
483 auto timer_mix_end = std::chrono::high_resolution_clock::now();
484
485 /**
486 * 6. Update effective potential from the MIXED density (single call per iteration).
487 * This produces V_Hxc for the next iteration's Hamiltonian AND provides
488 * E_Hartree and E_XC evaluated at the mixed density.
489 */
491 auto timer_pot_end = std::chrono::high_resolution_clock::now();
492
493 /**
494 * 7. Compute delta_escf: first-order energy correction for using mixed
495 * density rather than output density in E_Hartree and E_XC.
496 * delta_escf = -Σ_r (ρ_mixed(r) - ρ_out(r)) · V_Hxc^mixed(r)
497 * (matches QE's SCF-correction term of the same name)
498 */
499 Real delta_escf = compute_delta_escf_correction();
500
501 /**
502 * The total energy reported is:
503 * E = E_band + deband + E_Hartree(mixed) + E_XC(mixed)
504 * + E_Ewald + E_smearing(-TS) + delta_escf
505 * which gives a variational estimate using the output density. The -TS
506 * term is added by PlanewaveKohnShamEnergies::total(), not here; it is
507 * zero unless smearing is configured. Every term above is present in
508 * total(), so this line and that function must be kept in step.
509 */
511
512 log_iteration_timing(timer_mix_end, timer_pot_end);
513 }
514
515 bool is_iteration_converged() const override {
517 }
518
524
525 void report_iteration() override {
526 if (iteration_ == 1) {
529 } else {
530 Real delta_energy = energies().total() - total_energy_previous_;
531 log_iteration_energy(delta_energy);
532 }
534 }
535
536 /// Single source of truth for the per-iteration energy/convergence log line.
537 void log_iteration_energy(Real delta_energy) {
538 log::info(
539 " iteration # {:3d} Etot = {:14.9f} Ry delta(E) = {:.2e} dr2 = {:.2e}",
541 energies().total(),
542 delta_energy,
544 /**
545 * Recorded here rather than at the call sites so the history and the
546 * printed line can never disagree — a per-iteration output that says
547 * something different from stdout is worse than none.
548 */
549 scf_history_.push_back({iteration_, energies().total(), delta_energy, density_residual_});
550 }
551
552 void report_convergence() override {
553 Real delta_energy = energies().total() - total_energy_previous_;
554 log_iteration_energy(delta_energy);
555
556 log::info("");
557 log::info(" convergence achieved after {} iterations", iteration_);
558
560 }
561
562 void report_non_convergence() override {
563 /**
564 * A non-self-consistent pass is one diagonalization by design, so
565 * stopping after it is not a failure to converge. The warning made
566 * every NSCF log read as though the run had failed.
567 */
568 if (config_.calculation == "non_self_consistent_field") {
569 log::info(" non-self-consistent pass complete");
570 return;
571 }
572 log::warn("");
573 log::warn(" WARNING: SCF did not converge after {} iterations", maximum_iterations_);
574 log::info(" total energy = {:14.9f}", energies().total());
575 log::info("");
576 }
577
578 virtual void initialize_representation() = 0;
579 virtual void initialize_charge_density() = 0;
581 virtual void initiate_mixer() = 0;
582
583 virtual std::vector<std::vector<Real>> input_density_for_mixing() const = 0;
584 virtual void update_effective_potential() = 0;
585 virtual void prepare_hamiltonian() {}
587 virtual void set_diagonalizer_tolerance(Real tolerance) = 0;
589 virtual void update_occupations() = 0;
591 virtual void symmetrize_density() = 0;
593 const std::vector<std::vector<Real>>& input_density_for_mixing) const = 0;
594 virtual void mix_density(const std::vector<std::vector<Real>>& input_density_for_mixing) = 0;
595
596 /**
597 * Hook for representations that keep an auxiliary density (e.g. the smooth
598 * pre-augmentation density of ultrasoft pseudopotential_set). No-op by default.
599 */
601 virtual void snapshot_output_density() = 0;
603
605
606 /**
607 * Compute the first-order energy correction for evaluating E_Hartree
608 * and E_XC at the mixed density instead of the output density.
609 *
610 * delta_escf = -Σ_r (ρ_mixed(r) - ρ_out(r)) · V_Hxc^mixed(r) · (Ω/N)
611 *
612 * Matches QE's SCF-correction term of the same name. Must be called AFTER
613 * update_effective_potential() has been applied to the mixed density
614 * and AFTER snapshot_output_density() has saved the output density.
615 */
617
618 /**
619 * Compute sub-components (e.g. band energy, entropy) needed for total().
620 * Default no-op; override in representations that compute eagerly.
621 */
623
625
626 /**
627 * Representation-specific tail of the convergence report (eigenvalues,
628 * magnetization, final energy breakdown). Generic banner lives in report_convergence().
629 */
630 virtual void report_convergence_details() = 0;
631
632 virtual int number_of_bands() const = 0;
633 virtual Real number_of_electrons() const = 0;
634 virtual int number_of_kpoint_states() const = 0;
635};
636
637} // namespace q3
virtual void mix_density(const std::vector< std::vector< Real > > &input_density_for_mixing)=0
virtual void synchronize_smooth_density_from_mixed()
Definition init.hpp:600
void load_effective_potential(std::vector< std::vector< Real > > effective_potential)
Definition init.hpp:230
virtual void restore_density_at_convergence()=0
virtual void prepare_hamiltonian()
Definition init.hpp:585
const std::vector< Complex > & total_potential_g() const
Definition init.hpp:209
~KohnShamSCFIterator() override=default
const KohnShamSCFIteratorConfig & config() const
Definition init.hpp:256
virtual void update_occupations()=0
const std::vector< Real > & charge_density_real() const
Definition init.hpp:197
Real total_energy() const override
Definition init.hpp:187
virtual void report_first_iteration_details()=0
std::string smearing_
Definition init.hpp:168
std::unique_ptr< XCFunctional > exchange_correlation_
Definition init.hpp:286
virtual Real compute_density_residual(const std::vector< std::vector< Real > > &input_density_for_mixing) const =0
Real diagonalization_threshold() const
Definition init.hpp:301
void load_charge_density(std::vector< std::vector< Real > > charge_density)
Definition init.hpp:235
virtual void report_convergence_details()=0
std::vector< Complex > exchange_correlation_potential_g_
Definition init.hpp:275
virtual void symmetrize_density()=0
virtual int number_of_kpoint_states() const =0
virtual void initiate_mixer()=0
std::vector< Complex > total_potential_g_
Definition init.hpp:263
void perform_iteration() override
Definition init.hpp:344
std::unique_ptr< Mixer > mixer_
Definition init.hpp:287
std::string exchange_correlation_functional_
Definition init.hpp:162
std::unique_ptr< SmearingScheme > smearing_scheme_
Definition init.hpp:288
Crystal & crystal_structure() const
Definition init.hpp:219
virtual void set_diagonalization_tolerance(int iteration)=0
bool first_iteration_rediag_done_
Definition init.hpp:294
const std::vector< Complex > & charge_density_g() const
Definition init.hpp:194
bool has_preloaded_charge_density_
Definition init.hpp:282
virtual void initialize_representation()=0
virtual void solve_single_particle_states()=0
virtual Real compute_double_counting_correction() const =0
std::vector< std::vector< Real > > charge_density_real_
Definition init.hpp:261
virtual const KohnShamEnergies & energies() const =0
virtual std::vector< std::vector< Real > > input_density_for_mixing() const =0
const std::vector< Complex > & exchange_correlation_potential_g() const
Definition init.hpp:212
void initialize() override
Base implementation prints the SCF banner. Children call SCFIterator::initialize() last.
Definition init.hpp:305
void report_non_convergence() override
Definition init.hpp:562
virtual void snapshot_output_density()=0
virtual void compute_energy_components()
Definition init.hpp:622
virtual void initialize_charge_density()=0
void log_iteration_energy(Real delta_energy)
Single source of truth for the per-iteration energy/convergence log line.
Definition init.hpp:537
const std::vector< Real > & potential_for_spin(int spin_index) const
Definition init.hpp:206
bool has_preloaded_effective_potential_
Definition init.hpp:281
std::vector< Complex > charge_density_g_
Definition init.hpp:260
KohnShamSCFIteratorConfig config_
Definition init.hpp:159
virtual void initialize_single_particle_states()=0
const XCFunctional & exchange_correlation() const
Definition init.hpp:190
void offer_starting_charge_density(std::vector< std::vector< Real > > charge_density)
Definition init.hpp:249
void finalize() override
Definition init.hpp:519
void report_convergence() override
Definition init.hpp:552
virtual Real compute_delta_escf_correction() const =0
void report_iteration() override
Definition init.hpp:525
std::string mixing_mode_
Definition init.hpp:163
virtual void set_diagonalizer_tolerance(Real tolerance)=0
const std::vector< ScfIterationRecord > & scf_history() const
Definition init.hpp:180
virtual int number_of_bands() const =0
const std::vector< Real > & real_space_potential() const
Definition init.hpp:203
virtual KohnShamEnergies & energies_mutable()=0
std::vector< ScfIterationRecord > scf_history_
Definition init.hpp:293
std::vector< std::vector< Real > > real_space_potential_
Definition init.hpp:262
std::string mixing_preconditioning_
Definition init.hpp:166
KohnShamSCFIterator(KohnShamSCFIteratorConfig config)
Definition init.hpp:123
virtual void construct_density_from_states()=0
virtual void update_effective_potential()=0
bool preloaded_charge_density_is_a_starting_guess_
Set by offer_starting_charge_density(): a density that need not fit.
Definition init.hpp:284
const std::vector< Real > & charge_density_for_spin(int spin_index) const
Definition init.hpp:200
bool is_iteration_converged() const override
Definition init.hpp:515
std::vector< std::vector< Complex > > total_potential_g_by_spin_
Definition init.hpp:274
virtual Real number_of_electrons() const =0
Crystal * crystal_structure_
Definition init.hpp:103
Real convergence_threshold_
Definition init.hpp:104
virtual void initialize()
Base implementation prints the SCF banner. Children call SCFIterator::initialize() last.
Definition init.hpp:122
int iteration() const
Definition init.hpp:39
int number_of_spin_components() const
Definition init.hpp:45
int maximum_iterations_
Definition init.hpp:105
static std::unique_ptr< XCFunctional > create(const std::string &name, int number_of_spin_components=1)
Definition factory.hpp:35
Abstract base class for XC functionals.
Definition init.hpp:23
std::unique_ptr< Mixer > create(const std::string &mode, Real mixing_parameter=0.7, int history_depth=8)
Create a charge density mixer by name ("broyden", "linear", or "anderson").
Definition factory.hpp:28
bool is_supported(const std::string &name)
The names create() accepts, for validation and error messages.
Definition factory.hpp:44
void debug(spdlog::format_string_t< Args... > fmt, Args &&... args)
Definition logger.hpp:179
void warn(spdlog::format_string_t< Args... > fmt, Args &&... args)
Definition logger.hpp:187
void info(spdlog::format_string_t< Args... > fmt, Args &&... args)
Definition logger.hpp:183
constexpr double minimum_eigenvalue_tolerance
double Real
std::unique_ptr< SmearingScheme > create_smearing(const std::string &name, Real smearing_width=0.0, int methfessel_paxton_order=1)
Factory for smearing schemes.
Definition factory.hpp:29
Real total() const override
Return the total energy as the sum of all component fields.
Definition init.hpp:21
Real double_counting_correction
Definition init.hpp:16
std::vector< Real > starting_magnetization
Definition init.hpp:98
std::string hubbard_projector_type
Definition init.hpp:62
const KPointsGrid * kpoint_grid
Definition init.hpp:65
std::vector< std::pair< std::string, Vector3D > > band_path
Definition init.hpp:105
std::vector< Real > atomic_starting_magnetization
Definition init.hpp:104
std::vector< HubbardSpecification > hubbard
Definition init.hpp:53
std::string mixing_preconditioning
Definition init.hpp:46
std::string exchange_correlation_functional
Definition init.hpp:42
std::string nonlocal_stress_derivative_method
Definition init.hpp:107
std::vector< HubbardStartingEigenvalue > hubbard_starting_eigenvalues
First-iteration occupation-eigenvalue overrides; empty = no seeding.
Definition init.hpp:55
std::string diagonalization_method
Definition init.hpp:69
std::string dispersion_correction
Definition init.hpp:51
const execution::ExecutionPolicy * execution_policy
Definition init.hpp:118
const PseudopotentialSet * pseudopotential_set
Definition init.hpp:92
std::string representation_type
Definition init.hpp:111
int hubbard_fixed_occupation_iterations
Iterations for which the seeded occupation matrix is held; 0 = first iteration only.
Definition init.hpp:57
One row per SCF iteration, in order; the source for per-iteration companion outputs.
Definition init.hpp:173
void log_resident_checkpoint_debug(const std::string &label)
Definition counters.hpp:187
static ProfilingCounters & instance()
Definition counters.hpp:220
void release_unused_heap(const std::string &label)
Definition counters.hpp:169