Loading...
Searching...
No Matches
init.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * UltrasoftPlanewaveKohnShamQuantumSystem — ultrasoft pseudopotential
5 * extension.
6 *
7 * Extends NormConservingPlanewaveKohnShamQuantumSystem with:
8 * - Ultrasoft augmentation via UltrasoftPlanewaveBasis (static tables)
9 * - D-matrix access via UltrasoftPlanewaveEffectivePotential
10 *
11 * All static augmentation data (Q-tables, spherical harmonics, Gaunt coefficients)
12 * lives in UltrasoftPlanewaveBasis. The D-matrix is owned by this
13 * class when used as a post-SCF snapshot, or pointed to by a non-owning pointer
14 * during the SCF iteration where the iterator holds the authoritative copy.
15 */
16
17#include <memory>
18#include <stdexcept>
19#include <string>
20#include <vector>
21
28
29namespace q3 {
30
31/**
32 * Ultrasoft pseudopotential quantum system.
33 *
34 * Owns static augmentation data via UltrasoftPlanewaveBasis.
35 * Owns a copy of the effective D-matrix when used as a post-SCF snapshot
36 * (populated by set_nonlocal_effective_potential(const&) in result()).
37 * During SCF iterations the iterator holds the authoritative D-matrix and
38 * wires it in via set_nonlocal_effective_potential(pointer).
39 */
42 public:
45
47 const PlanewaveBasis& planewave_basis,
48 const PseudopotentialSet& pseudopotential_set) override {
49 basis_ = &planewave_basis;
50 auto ultrasoft_basis = std::make_unique<UltrasoftPlanewaveBasis>();
51 ultrasoft_basis->init(crystal_structure, planewave_basis, pseudopotential_set);
54 }
55
56 /**
57 * Access the ultrasoft basis for direct augmentation table queries.
58 */
59 [[nodiscard]] const UltrasoftPlanewaveBasis& ultrasoft_basis() const {
61 }
62
63 /**
64 * This quantum system uses ultrasoft pseudopotentials.
65 */
66 [[nodiscard]] bool has_ultrasoft() const override {
67 return true;
68 }
69
70 /**
71 * Always refuses: augmentation charges bring an overlap operator S, so the
72 * eigenproblem is H ψ = E S ψ. PAW runs use this system too.
73 */
74 void require_identity_overlap(const std::string& purpose) const override {
75 throw std::runtime_error(purpose +
76 " needs norm-conserving pseudopotentials: with ultrasoft or "
77 "PAW datasets the Hamiltonian comes with an overlap operator S, "
78 "which it cannot carry.");
79 }
80
81 /**
82 * Copy the converged non-local effective potential into this object's owned storage.
83 * Used by UltrasoftPlanewaveKohnShamSCFIterator::result() to produce
84 * a self-contained snapshot that does not rely on the iterator's lifetime.
85 */
91
92 /**
93 * Wire in the non-local effective potential via non-owning pointer.
94 * Used during SCF iterations where the iterator owns the authoritative D-matrix.
95 */
97 UltrasoftPlanewaveEffectivePotential* nonlocal_effective_potential) {
98 active_nonlocal_effective_potential_ = nonlocal_effective_potential;
99 }
100
101 [[nodiscard]] Real d_matrix_element(int atom_index,
102 int species_type,
103 int projector_index_i,
104 int projector_index_j,
105 int spin = 0) const override {
109 atom_index, projector_index_i, projector_index_j, spin);
110 }
111 // Fallback to bare D-matrix (NC pseudopotentials or uninitialised state).
112 const auto& basis = pseudopotential_basis();
113 int number_of_channels = basis.number_of_projector_channels(species_type);
114 if (projector_index_i < number_of_channels && projector_index_j < number_of_channels) {
115 int beta_projector_a = basis.projector_to_beta_index(species_type, projector_index_i);
116 int beta_projector_b = basis.projector_to_beta_index(species_type, projector_index_j);
117 if (basis.projector_combined_lm_index(species_type, projector_index_i) ==
118 basis.projector_combined_lm_index(species_type, projector_index_j)) {
119 return basis.bare_d_matrix_element(
120 species_type, beta_projector_a, beta_projector_b);
121 }
122 }
123 return 0.0;
124 }
125
126 protected:
127 /// Non-owning pointer to the ultrasoft-typed basis (owned by parent's unique_ptr).
129
130 /**
131 * Owned copy of the converged effective D-matrix.
132 * Populated only for post-SCF snapshots (via the const-ref overload).
133 */
135
136 /**
137 * Active effective potential pointer. Points to owned_nonlocal_effective_potential_
138 * for snapshots, or to the iterator's member during SCF iterations.
139 */
141};
142
143} // namespace q3
const NormConservingPlanewaveBasis & pseudopotential_basis() const
Definition init.hpp:65
std::unique_ptr< NormConservingPlanewaveBasis > norm_conserving_basis_
NC pseudopotential basis: local potential, beta projectors, core charge, atomic densities.
Definition init.hpp:124
const PlanewaveBasis & basis() const
Definition init.hpp:85
const PlanewaveBasis * basis_
Definition init.hpp:290
Crystal * crystal_structure
void init(const Crystal &crystal_structure, const PlanewaveBasis &planewave_basis, const PseudopotentialSet &pseudopotential_set) override
Definition init.hpp:46
Real element(int atom_index, int projector_index_i, int projector_index_j, int spin=0) const
Definition init.hpp:377
UltrasoftPlanewaveBasis * ultrasoft_planewave_basis_
Non-owning pointer to the ultrasoft-typed basis (owned by parent's unique_ptr).
Definition init.hpp:128
void require_identity_overlap(const std::string &purpose) const override
Definition init.hpp:74
Real d_matrix_element(int atom_index, int species_type, int projector_index_i, int projector_index_j, int spin=0) const override
Definition init.hpp:101
bool has_ultrasoft() const override
Definition init.hpp:66
UltrasoftPlanewaveEffectivePotential owned_nonlocal_effective_potential_
Definition init.hpp:134
~UltrasoftPlanewaveKohnShamQuantumSystem() override=default
UltrasoftPlanewaveEffectivePotential * active_nonlocal_effective_potential_
Definition init.hpp:140
void init(const Crystal &crystal_structure, const PlanewaveBasis &planewave_basis, const PseudopotentialSet &pseudopotential_set) override
Definition init.hpp:46
const UltrasoftPlanewaveBasis & ultrasoft_basis() const
Definition init.hpp:59
void set_nonlocal_effective_potential(const UltrasoftPlanewaveEffectivePotential &nonlocal_effective_potential)
Definition init.hpp:86
void set_nonlocal_effective_potential(UltrasoftPlanewaveEffectivePotential *nonlocal_effective_potential)
Definition init.hpp:96
double Real