Loading...
Searching...
No Matches
non_self_consistent_field.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * NonSelfConsistentFieldFlavor — NSCF calculation flavor.
5 *
6 * Runs a single-pass diagonalization at a user-specified list of k-points.
7 * Requires a v2 checkpoint from a prior SCF calculation to load V_eff.
8 *
9 * Workflow:
10 * 1. Load effective potential V_eff from <prefix>.save/effective-potential.q3cp.
11 * 2. Construct an iterator with the explicit kpoints_list from InputData.
12 * 3. Inject V_eff via load_effective_potential() (bypasses SCF reconstruction).
13 * 4. Set maximum_iterations = 1 so the iterator performs a single diagonalization.
14 * 5. Run the iterator.
15 * 6. Return eigenvalues + occupations as results.json's own struct.
16 *
17 * The results contain the eigenvalues (and, since the shared
18 * per-iteration flow always calls update_occupations(), occupations too) at
19 * all requested k-points, but no total energy (which is meaningless for a
20 * non-self-consistent calculation). Occupations reflect a Fermi bisection
21 * over *this run's* k-point set, not the original SCF's -- reliable for a
22 * proper dense k-grid, not for a non-uniform set like a band path.
23 */
24
25#include <algorithm>
26#include <array>
27#include <memory>
28#include <stdexcept>
29#include <string>
30#include <vector>
31
33#include "io/logger.hpp"
37#include "io/output/results.hpp"
49
50namespace q3 {
51
52/**
53 * The Davidson working basis a non-self-consistent pass runs with.
54 *
55 * A single pass keeps what the solver returns, and below four times the band
56 * count it can return a spectrum with an eigenvalue missing -- see the
57 * constant. A default below that is raised; a factor the deck named is kept,
58 * since it is a memory choice its author made, and the caller warns.
59 */
60inline int non_self_consistent_field_davidson_basis_expansion_factor(int factor, bool set_by_deck) {
61 if (set_by_deck) {
62 return factor;
63 }
64 return std::max(factor,
66}
67
69 public:
70 /**
71 * `iterator_factory` carries the entry point's execution policy (see
72 * IteratorFactory); empty runs serially on the CPU.
73 */
74 explicit NonSelfConsistentFieldFlavor(IteratorFactory iterator_factory = {})
75 : iterator_factory_(std::move(iterator_factory)) {}
76
77 protected:
78 generated::Results run_calculation(const InputData& input) override {
79 if (input.kpoints_list.empty()) {
80 throw std::runtime_error(
81 "NonSelfConsistentFieldFlavor: 'kpoints_list' is required in the input "
82 "for calculation type 'non_self_consistent_field'.");
83 }
84
85 const std::string save_directory = input.output_directory + "/" + input.prefix + ".save";
86 const std::string effective_potential_checkpoint_path =
87 save_directory + "/effective-potential.q3cp";
88
89 // ─── Step 1: Load V_eff from checkpoint ──────────────────────────────
90 KohnShamQuantumSystemSnapshot effective_potential_snapshot;
91 Q3PlanewaveKohnShamQuantumSystemCheckpoint effective_potential_checkpoint;
92
93 bool loaded_successfully = effective_potential_checkpoint.load(
94 effective_potential_checkpoint_path, effective_potential_snapshot);
95
96 if (!loaded_successfully) {
97 throw std::runtime_error(
98 "NonSelfConsistentFieldFlavor: failed to load effective-potential checkpoint at '" +
99 effective_potential_checkpoint_path +
100 "'. Run a self_consistent_field calculation first to generate it.");
101 }
102
103 if (effective_potential_snapshot.effective_potential_real.empty()) {
104 throw std::runtime_error(
105 "NonSelfConsistentFieldFlavor: effective-potential checkpoint at '" +
106 effective_potential_checkpoint_path +
107 "' does not contain V_eff (may be a v1 checkpoint — re-run SCF to generate v2).");
108 }
109
110 log::info(" NSCF: loaded effective potential from '{}'",
111 effective_potential_checkpoint_path);
112 log::info(" NSCF: diagonalizing at {} explicit k-points",
113 static_cast<int>(input.kpoints_list.size()));
114
115 /**
116 * ─── Step 2: Build iterator with explicit k-points ────────────────────
117 * Set maximum_iterations = 1 so the base iterate() loop runs exactly once
118 * (performs initialization + one diagonalization pass).
119 */
120 InputData nscf_input = input;
121 nscf_input.maximum_iterations = 1;
122 /**
123 * Use the same convergence threshold as the SCF run (irrelevant for NSCF
124 * since we do only one iteration, but must be set to avoid division by zero).
125 */
126 nscf_input.convergence_threshold = 1.0e-16;
127 const int requested_factor = nscf_input.davidson_basis_expansion_factor;
130 requested_factor, nscf_input.davidson_basis_expansion_factor_set_by_deck);
131 if (nscf_input.davidson_basis_expansion_factor != requested_factor) {
132 log::info(
133 " NSCF: Davidson working basis {} times the band count, not the default {}: "
134 "a single pass below that can miss eigenvalues",
136 requested_factor);
137 } else if (requested_factor <
139 log::warn("NSCF: method.scf.davidson.basis_expansion_factor is {}, below {}; a single "
140 "pass at that working basis can miss eigenvalues while every residual "
141 "test passes",
142 requested_factor,
144 }
145
146 auto iterator = create_iterator(nscf_input, iterator_factory_);
147
148 auto* planewave_iterator =
149 dynamic_cast<PlanewavePseudopotentialKohnShamSCFIterator*>(iterator.get());
150 if (!planewave_iterator) {
151 throw std::runtime_error(
152 "NonSelfConsistentFieldFlavor: expected a planewave pseudopotential iterator.");
153 }
154
155 /**
156 * The potential below is loaded whole, onto every rank, as the SCF
157 * saved it. That fits a rank holding whole k-points -- one rank per
158 * pool, the topology the SCF itself needs to write the checkpoint at
159 * all -- and nothing else: ranks sharing a pool split the density grid
160 * between them, and nothing scatters a whole grid onto that split. Asked
161 * after the iterator exists, because building it is where a pool count
162 * above the k-point count is clamped back into shared pools.
163 */
164 if (!planewave_iterator->execution_policy().each_process_owns_whole_kpoints()) {
165 throw std::runtime_error(
166 "NonSelfConsistentFieldFlavor: ranks share a k-point pool here, and a "
167 "non-self-consistent run needs one rank per pool: it loads the SCF's "
168 "potential whole onto every rank, which ranks splitting the density grid "
169 "cannot take. Run it with --pools equal to the rank count (at most the number "
170 "of k-points listed), or with fewer ranks.");
171 }
172
173 /**
174 * ─── Step 3: Inject preloaded V_eff ──────────────────────────────────
175 * load_effective_potential() sets has_preloaded_effective_potential_ = true,
176 * which prevents update_effective_potential() from overwriting it during
177 * initialize_single_particle_states(). Instead, only the G-space FFT is
178 * done to populate total_potential_g_ (needed by prepare_hamiltonian()).
179 */
180 planewave_iterator->load_effective_potential(
181 effective_potential_snapshot.effective_potential_real);
182
183 /**
184 * ─── Step 3a: Hand over the PAW on-site occupations ───────────────────
185 * A PAW dataset's D carries a one-centre term built from ρ_ij, which the
186 * SCF refreshes each time it constructs a density. This run
187 * diagonalizes before it constructs any, so without the converged ρ_ij
188 * that term is empty and every eigenvalue is wrong -- copper's 3s by
189 * 103 eV. A checkpoint written before the occupations were stored cannot
190 * supply them, and a result built without them is refused rather than
191 * returned.
192 */
193 if (planewave_iterator->requires_one_center_occupations()) {
194 if (effective_potential_snapshot.one_center_occupations.empty()) {
195 throw std::runtime_error(
196 "NonSelfConsistentFieldFlavor: checkpoint at '" +
197 effective_potential_checkpoint_path +
198 "' carries no PAW on-site occupations, which the one-centre term of D is "
199 "built from (it predates checkpoint version 3). Re-run the "
200 "self_consistent_field calculation to regenerate it.");
201 }
202 planewave_iterator->load_one_center_occupations(
203 effective_potential_snapshot.one_center_occupations);
204 }
205
206 /**
207 * ─── Step 3b: Set tight diagonalization tolerance ─────────────────────
208 * The SCF iterator uses a loose initial tolerance (1e-2 Ry) for iteration 1,
209 * which is appropriate for SCF where the potential evolves anyway. For NSCF
210 * the potential is frozen and we run only one pass, so we must start with a
211 * tight tolerance to ensure Davidson converges all bands to the true lowest
212 * eigenvalues. Without this, high-index conduction bands at special k-points
213 * (e.g. the 10th band at K in Si: 14.5 eV) can converge to spurious excited
214 * states instead of the correct ground-state eigenvectors.
215 */
216 planewave_iterator->set_diagonalizer_tolerance_for_nscf(
218 planewave_iterator->set_diagonalizer_maximum_iterations_for_nscf(
220
221 // ─── Step 4: Run (single diagonalization pass) ────────────────────────
222 iterator->run();
223
224 /**
225 * ─── Step 4b: Mean-field export (BerkeleyGW, etc.) ─────────────────────
226 * This is the flavor BerkeleyGW normally consumes: an NSCF run with
227 * many empty (conduction) bands beyond what SCF itself needs, at
228 * whatever k-point set input.kpoints_list requests. Format selection
229 * lives in the factory ("none" resolves to the Null object), so
230 * there is no branching on the format name here -- see
231 * io/mean_field_export/init.hpp.
232 *
233 * The exported charge density must be the CONVERGED SCF density from the
234 * checkpoint, not the one this pass leaves on the iterator. Step 4 runs a
235 * single turn of the shared per-iteration flow, which ends in a mixing
236 * step, so the iterator's density is a blend of the atomic-superposition
237 * initial guess and this pass's output -- governed by `mixing.beta`, a
238 * parameter that has no meaning for a non-self-consistent run. Measured on
239 * the silicon example (`beta` 0.3): 12% off the converged density in L2
240 * over the whole G set (19% when the NSCF k-set is the symmetry-reduced
241 * IBZ), against 0.01% once mixing is bypassed -- and, being a *recomputed*
242 * density, it would additionally degrade with a coarse k-set even without
243 * mixing. pw2bgw draws the same line: `write_rhog` writes QE's *saved*
244 * charge density, and recomputing it from the bands is a separate opt-in
245 * diagnostic (`calc_rhog`, reached only via `rhog_nvmin`/`rhog_nvmax`).
246 */
247 auto mean_field_state = planewave_iterator->result();
248 if (effective_potential_snapshot.charge_density_real.empty())
249 throw std::runtime_error(
250 "NonSelfConsistentFieldFlavor: checkpoint at '" +
251 effective_potential_checkpoint_path +
252 "' carries no charge density, so the converged SCF density cannot be "
253 "restored for the mean-field export. Re-run the SCF calculation to "
254 "regenerate the checkpoint.");
255 restore_converged_charge_density(mean_field_state,
256 effective_potential_snapshot.charge_density_real);
257 /**
258 * Vxc(G) likewise belongs to the converged density, and this pass never
259 * computes it at all: the potential came from the checkpoint whole, so
260 * without this the state carries an empty Vxc(G) and BerkeleyGW's
261 * vxc.dat cannot be written. pw2bgw evaluates Vxc from the same saved
262 * density (its `vxc_flag` path), and from the valence part of it: see
263 * valence_exchange_correlation_potential_g_of().
264 */
265 mean_field_state.exchange_correlation_potential_g =
266 planewave_iterator->valence_exchange_correlation_potential_g_of(
267 effective_potential_snapshot.charge_density_real);
268 /**
269 * Which rank (if any) writes is decided by the execution topology --
270 * see export_and_record_mean_field_under_topology()'s comment, which
271 * the MPI entry points reach through this flavor as the SCF's do.
272 */
274 planewave_iterator->execution_policy(),
275 [&mean_field_state, &input] {
276 auto record = build_mean_field_record(mean_field_state);
277 if (input.mean_field_export_kleinman_bylander_projectors)
278 add_kleinman_bylander_projectors_to_mean_field_record(record, mean_field_state);
279 return record;
280 },
281 input,
282 input.output_directory);
283
284 // ─── Step 5: Results ─────────────────────────────────────────────────────
285 generated::Results results = new_results("non_self_consistent_field");
286 /**
287 * An NSCF total energy is meaningless — list it as 0 to signal this.
288 * A single-pass NSCF is always "converged" — there is no iterative convergence
289 * criterion applicable. The SCF iterator reports is_converged()=false because
290 * the KohnShamSCFIterator convergence check requires iteration_>1 (which is
291 * never reached with maximum_iterations=1). Override to true so that the Python
292 * layer does not raise SCFNotConvergedError on a valid NSCF result.
293 */
294 results.runtime_log.converged = true;
295 results.runtime_log.execution = planewave_iterator->execution_policy().execution_record();
297 set_fermi_energy(results, planewave_iterator->quantum_system().fermi_energy());
298
299 /**
300 * Every k-point state of the run, gathered across pools -- each pool
301 * diagonalized only its own share of the list -- in the list's order.
302 */
303 set_record(results, assemble_global_eigenvalues_at_kpoints(*planewave_iterator));
304 const std::size_t number_of_kpoint_states =
305 find_record<generated::EigenvaluesAtKpoints>(results)->values.size();
306 const int number_of_bands = static_cast<int>(planewave_iterator->eigenvalues().cols());
307
308 // ─── Step 6: Atomic-orbital (ortho-atomic/Löwdin) projections (opt-in) ──
309 if (input.compute_projections) {
310 /**
311 * This pool's k-point states: the projections are taken where the
312 * wavefunctions are, then gathered like the eigenvalues above. The
313 * state index is spin-major over the pool's physical k-points, so a
314 * state splits into the physical k-point (G-space basis,
315 * spin-independent) and the state (wavefunction storage,
316 * spin-dependent).
317 */
318 const int local_number_of_kpoint_states =
319 static_cast<int>(planewave_iterator->eigenvalues().rows());
320 const int local_number_of_physical_kpoints =
321 planewave_iterator->kpoint_grid().number_of_kpoints();
322 log::info(" NSCF: computing ortho-atomic projections at {} k-points{}",
323 static_cast<int>(number_of_kpoint_states),
324 planewave_iterator->pseudopotential_set().has_augmentation_charges()
325 ? " in the S metric (ultrasoft/PAW augmentation)"
326 : "");
327 PlanewaveWavefunctionProjectionCalculator projection_calculator(
328 planewave_iterator->crystal_structure(), planewave_iterator->pseudopotential_set());
329
330 generated::ResultsOrbitalProjections orbital_projections;
331 for (const auto& orbital_label : projection_calculator.orbital_labels()) {
332 generated::ResultsOrbitalProjectionsLabelsItem label;
333 label.atom_index = orbital_label.atom_index;
334 label.species_type_index = orbital_label.species_type_index;
335 label.shell_label = orbital_label.shell_label;
336 label.angular_momentum = orbital_label.angular_momentum;
337 label.magnetic_quantum_number = orbital_label.magnetic_quantum_number;
338 orbital_projections.labels.push_back(label);
339 }
340 const int number_of_orbitals = static_cast<int>(orbital_projections.labels.size());
341
342 // One flat [band][orbital] block per local k-point state.
343 std::vector<std::vector<Real>> local_projections(local_number_of_kpoint_states);
344 for (int kpoint_state_index = 0; kpoint_state_index < local_number_of_kpoint_states;
345 kpoint_state_index++) {
346 int physical_kpoint_index = kpoint_state_index % local_number_of_physical_kpoints;
347 /**
348 * Kept alive alongside the operator that reads it: the ultrasoft
349 * overlap holds the matrix by reference.
350 */
351 Matrix<Complex> kleinman_bylander_projectors;
352 std::unique_ptr<OverlapOperator> overlap_operator =
353 build_projection_overlap_operator(
354 *planewave_iterator, physical_kpoint_index, kleinman_bylander_projectors);
355 const std::vector<std::vector<Real>> projections =
356 projection_calculator.compute_projections_at_kpoint(
357 physical_kpoint_index,
358 kpoint_state_index,
359 planewave_iterator->number_of_plane_waves(physical_kpoint_index),
360 number_of_bands,
361 planewave_iterator->g_vector_indices(physical_kpoint_index),
362 planewave_iterator->crystal_structure(),
363 planewave_iterator->kpoint_grid(),
364 planewave_iterator->planewave_basis(),
365 planewave_iterator->pseudopotential_set(),
366 planewave_iterator->quantum_system(),
367 overlap_operator.get());
368 for (const auto& band_projections : projections) {
369 local_projections[kpoint_state_index].insert(
370 local_projections[kpoint_state_index].end(),
371 band_projections.begin(),
372 band_projections.end());
373 }
374 }
375
376 orbital_projections.values.assign(number_of_kpoint_states,
377 std::vector<std::vector<double>>(number_of_bands));
378 if (number_of_orbitals > 0) {
379 const std::vector<std::vector<Real>> global_projections =
380 assemble_global_kpoint_state_blocks(*planewave_iterator,
381 local_projections,
382 number_of_bands * number_of_orbitals);
383 for (std::size_t state_index = 0; state_index < global_projections.size();
384 ++state_index) {
385 for (int band_index = 0; band_index < number_of_bands; ++band_index) {
386 const auto band_begin =
387 global_projections[state_index].begin() +
388 static_cast<std::ptrdiff_t>(band_index) * number_of_orbitals;
389 orbital_projections.values[state_index][band_index].assign(
390 band_begin, band_begin + number_of_orbitals);
391 }
392 }
393 }
394 results.properties.orbital_projections = orbital_projections;
395 }
396
397 // ─── Step 7: interpolation model (opt-in) ──────────────────────────────
398 if (input.interpolation.requested()) {
400 input.interpolation, *planewave_iterator, number_of_bands);
402 }
403
404 return results;
405 }
406
407 private:
408 /**
409 * The overlap operator the atomic-orbital projections must be taken in at
410 * one k-point, or null when the pseudopotentials leave S the identity.
411 *
412 * Ultrasoft and PAW datasets carry augmentation charges, so S = 1 + Σ q_ij
413 * |β_i⟩⟨β_j| and the projection that conserves charge is ⟨φ|S|ψ⟩. Building
414 * that operator needs this k-point's Kleinman-Bylander projector matrix,
415 * which is returned through `kleinman_bylander_projectors` because the
416 * operator holds it by reference and this is the only caller that knows how
417 * long it must live. Dispatching on the pseudopotential set here, rather
418 * than inside the projection calculator, keeps that calculator free of the
419 * question -- the same split build_wannier_interface_record() makes for the
420 * Wannier interface matrices.
421 */
422 [[nodiscard]] static std::unique_ptr<OverlapOperator>
423 build_projection_overlap_operator(const PlanewavePseudopotentialKohnShamSCFIterator& iterator,
424 int physical_kpoint_index,
425 Matrix<Complex>& kleinman_bylander_projectors) {
427 return nullptr;
428 }
429 const NormConservingPlanewaveKohnShamQuantumSystem& quantum_system =
431 /**
432 * create_overlap_operator() reads the same predicate to choose between
433 * the identity and the augmentation overlap, so a disagreement here
434 * would not fail -- it would hand back S = I and write complete-looking
435 * projections in the wrong metric, which is the failure this whole path
436 * exists to remove. Refuse instead, as the Wannier interface builder
437 * does for the same disagreement.
438 */
439 if (!quantum_system.has_ultrasoft()) {
440 throw std::logic_error(
441 "NSCF projections: the pseudopotentials carry augmentation charges but the "
442 "quantum system is not the ultrasoft one; the iterator factory and this flavor "
443 "disagree about the run's pseudopotential type.");
444 }
445 const auto& pseudopotential_basis = quantum_system.pseudopotential_basis();
447 iterator.kpoint_grid()[physical_kpoint_index].coordinates,
448 iterator.crystal_structure(),
449 iterator.planewave_basis(),
450 pseudopotential_basis.pseudopotential_set(),
451 pseudopotential_basis.beta_function_table(),
452 iterator.g_vector_indices(physical_kpoint_index),
453 iterator.number_of_plane_waves(physical_kpoint_index),
454 pseudopotential_basis.total_number_of_projectors(),
455 kleinman_bylander_projectors);
457 quantum_system,
458 kleinman_bylander_projectors,
459 iterator.execution_policy());
460 }
461
462 /**
463 * Replaces `state`'s charge density with the converged SCF density loaded
464 * from the checkpoint, keeping the G-space copy consistent with the
465 * real-space one.
466 *
467 * Both fields are overwritten deliberately. `charge_density_real` is what
468 * the mean-field exporters read, but `charge_density_g` is what the force
469 * and stress calculators read (see forces/planewave/pseudopotential and
470 * stress_tensor/planewave/internal/exchange_correlation), so leaving it
471 * holding the mixed density would plant exactly the same inconsistency one
472 * layer down for whoever computes a property off an NSCF state next.
473 * The G-space density is the spin-SUMMED total, matching how
474 * PlanewaveEffectivePotentialCalculator::compute() derives it.
475 */
476 static void restore_converged_charge_density(
477 NormConservingPlanewaveKohnShamSCFState& state,
478 const std::vector<std::vector<Real>>& converged_charge_density_real) {
479 int local_grid_points = state.planewave_basis->fft_rho().local_grid_points();
480 /**
481 * Checked rather than assumed: the loop below indexes the checkpoint's
482 * arrays by THIS run's grid size, so a checkpoint written at a different
483 * `cutoffs.density` (hence a different charge-density FFT grid) would
484 * otherwise read past the end. Fail with something the user can act on.
485 */
486 for (const auto& spin_density : converged_charge_density_real) {
487 if (static_cast<int>(spin_density.size()) != local_grid_points)
488 throw std::runtime_error(
489 "NonSelfConsistentFieldFlavor: the checkpoint's charge density has " +
490 std::to_string(spin_density.size()) + " grid points but this run's " +
491 "charge-density FFT grid has " + std::to_string(local_grid_points) +
492 ". The NSCF run must use the same cutoffs.density as the SCF run that "
493 "wrote the checkpoint.");
494 }
495 state.charge_density_real = converged_charge_density_real;
496
497 std::vector<Real> total_charge_density_real(local_grid_points, 0.0);
498 for (const auto& spin_density : converged_charge_density_real) {
499 for (int grid_index = 0; grid_index < local_grid_points; ++grid_index) {
500 total_charge_density_real[grid_index] += spin_density[grid_index];
501 }
502 }
503 state.planewave_basis->rho_r_to_g(total_charge_density_real, state.charge_density_g);
504 }
505
506 IteratorFactory iterator_factory_;
507};
508
509} // namespace q3
Crystal & crystal_structure() const
Definition init.hpp:219
NonSelfConsistentFieldFlavor(IteratorFactory iterator_factory={})
generated::Results run_calculation(const InputData &input) override
const std::vector< std::vector< int > > & g_vector_indices() const
Definition init.hpp:280
const KPointsGrid & kpoint_grid() const
Definition init.hpp:209
const execution::PlanewaveExecutionPolicy & execution_policy() const
Definition init.hpp:119
const std::vector< int > & number_of_plane_waves() const
Definition init.hpp:294
const PlanewaveBasis & planewave_basis() const
Definition init.hpp:216
const NormConservingPlanewaveKohnShamQuantumSystem & norm_conserving_quantum_system() const
Definition init.hpp:234
const PseudopotentialSet & pseudopotential_set() const
Definition init.hpp:226
bool has_augmentation_charges() const
Definition set.hpp:129
bool load(const std::string &filename, KohnShamQuantumSystemSnapshot &snapshot) const override
Definition q3.hpp:56
constexpr int non_self_consistent_field_minimum_davidson_basis_expansion_factor
Definition constants.hpp:86
constexpr int non_self_consistent_field_maximum_davidson_iterations
Definition constants.hpp:70
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
int non_self_consistent_field_davidson_basis_expansion_factor(int factor, bool set_by_deck)
generated::EigenvaluesAtKpoints assemble_global_eigenvalues_at_kpoints(const PlanewavePseudopotentialKohnShamSCFIterator &iterator)
void set_record(generated::Results &results, const Record &record)
List record in the results, in place of any record of the same name.
Definition results.hpp:75
generated::Results new_results(const std::string &flavor)
Definition results.hpp:46
void export_and_record_mean_field_under_topology(const execution::PlanewaveExecutionPolicy &execution_policy, RecordBuilder &&build_record, const InputData &input, const std::string &directory)
void set_fermi_energy(generated::Results &results, Real fermi_energy_in_ry)
ESSE's fermi_energy record, in rydberg.
Definition results.hpp:174
void write_and_export_interpolation_record(const InterpolationRecord &record, const InputData &input)
std::function< std::unique_ptr< PlanewaveKohnShamSCFIterator >(const InputData &)> IteratorFactory
Definition factory.hpp:59
std::unique_ptr< OverlapOperator > create_overlap_operator(const Crystal &crystal_structure, const NormConservingPlanewaveKohnShamQuantumSystem &quantum_system, const Matrix< Complex > &kleinman_bylander_potential, const execution::ExecutionPolicy &execution_policy)
Definition factory.hpp:23
void compute_kleinman_bylander_projectors(const Vector3D &k_crystal, const Crystal &crystal_structure, const PlanewaveBasis &planewave_basis, const PseudopotentialSet &pseudopotential_set, const BetaFunctionTable &beta_function_table, const std::vector< int > &g_vector_indices, int number_of_plane_waves, int total_number_of_projectors, Matrix< Complex > &kleinman_bylander_potential)
Definition projector.hpp:36
std::unique_ptr< PlanewaveKohnShamSCFIterator > create_iterator(const InputData &input)
Definition factory.hpp:37
std::vector< std::vector< Real > > assemble_global_kpoint_state_blocks(const PlanewavePseudopotentialKohnShamSCFIterator &iterator, const std::vector< std::vector< Real > > &local_blocks, int values_per_state)
InterpolationRecord capture_interpolation_record(const InterpolationSpecification &specification, PlanewavePseudopotentialKohnShamSCFIterator &iterator, int number_of_bands)
Definition capture.hpp:164
void set_energy_records(generated::Results &results, Real total_energy_in_ry, const PlanewaveKohnShamEnergies &energies)
Definition results.hpp:135
Parsed input data — holds raw values read from input files.
Definition data.hpp:27
std::string prefix
Definition data.hpp:178
int maximum_iterations
Definition data.hpp:33
std::vector< std::pair< Vector3D, Real > > kpoints_list
Definition data.hpp:125
InterpolationSpecification interpolation
Definition data.hpp:248
Real convergence_threshold
Definition data.hpp:32
bool davidson_basis_expansion_factor_set_by_deck
Definition data.hpp:72
int davidson_basis_expansion_factor
Definition data.hpp:66
bool compute_projections
Definition data.hpp:242
std::string output_directory
Definition data.hpp:177
std::vector< std::vector< Real > > effective_potential_real
Definition snapshot.hpp:35
std::vector< Matrix< Real > > one_center_occupations
Definition snapshot.hpp:47
std::vector< std::vector< Real > > charge_density_real
Definition snapshot.hpp:26