80 throw std::runtime_error(
81 "NonSelfConsistentFieldFlavor: 'kpoints_list' is required in the input "
82 "for calculation type 'non_self_consistent_field'.");
86 const std::string effective_potential_checkpoint_path =
87 save_directory +
"/effective-potential.q3cp";
93 bool loaded_successfully = effective_potential_checkpoint.
load(
94 effective_potential_checkpoint_path, effective_potential_snapshot);
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.");
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).");
110 log::info(
" NSCF: loaded effective potential from '{}'",
111 effective_potential_checkpoint_path);
112 log::info(
" NSCF: diagonalizing at {} explicit k-points",
133 " NSCF: Davidson working basis {} times the band count, not the default {}: "
134 "a single pass below that can miss eigenvalues",
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 "
148 auto* planewave_iterator =
150 if (!planewave_iterator) {
151 throw std::runtime_error(
152 "NonSelfConsistentFieldFlavor: expected a planewave pseudopotential iterator.");
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.");
180 planewave_iterator->load_effective_potential(
193 if (planewave_iterator->requires_one_center_occupations()) {
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.");
202 planewave_iterator->load_one_center_occupations(
216 planewave_iterator->set_diagonalizer_tolerance_for_nscf(
218 planewave_iterator->set_diagonalizer_maximum_iterations_for_nscf(
247 auto mean_field_state = planewave_iterator->result();
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,
265 mean_field_state.exchange_correlation_potential_g =
266 planewave_iterator->valence_exchange_correlation_potential_g_of(
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);
285 generated::Results results =
new_results(
"non_self_consistent_field");
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());
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());
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)"
328 planewave_iterator->crystal_structure(), planewave_iterator->pseudopotential_set());
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);
340 const int number_of_orbitals =
static_cast<int>(orbital_projections.labels.size());
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;
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,
359 planewave_iterator->number_of_plane_waves(physical_kpoint_index),
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());
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 =
382 number_of_bands * number_of_orbitals);
383 for (std::size_t state_index = 0; state_index < global_projections.size();
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);
394 results.properties.orbital_projections = orbital_projections;