42 const Crystal& crystal_structure,
44 const std::map<std::string, std::vector<int>>& trial_shells = {})
45 : pseudopotential_set_(pseudopotential_set) {
46 const std::vector<std::vector<bool>> kept =
47 kept_shells(crystal_structure, pseudopotential_set, trial_shells);
49 const std::vector<AtomicOrbitalLabel> every_label =
51 for (std::size_t row = 0; row < every_label.size(); row++) {
55 kept_rows_.push_back(
static_cast<int>(row));
56 orbital_labels_.push_back(label);
59 number_of_rendered_orbitals_ =
static_cast<int>(every_label.size());
60 centers_crystal_.reserve(orbital_labels_.size());
61 for (
const AtomicOrbitalLabel& label : orbital_labels_) {
65 pseudopotential_set, crystal_structure.
cell_volume(), q_spacing_, number_of_q_points_);
69 return static_cast<int>(orbital_labels_.size());
72 [[nodiscard]]
const std::vector<AtomicOrbitalLabel>&
orbital_labels()
const {
73 return orbital_labels_;
77 int number_of_plane_waves,
78 const std::vector<int>& g_vector_indices,
79 const Crystal& crystal_structure,
82 std::vector<std::vector<Complex>>& orbitals)
const override {
84 std::vector<std::vector<Complex>> rendered;
86 number_of_plane_waves,
92 atomic_wavefunction_table_,
95 every_shell ? orbitals : rendered);
99 orbitals.resize(kept_rows_.size());
100 for (std::size_t orbital = 0; orbital < kept_rows_.size(); orbital++) {
101 orbitals[orbital] = std::move(rendered[kept_rows_[orbital]]);
107 return centers_crystal_;
113 " pseudo-atomic orbitals from the pseudopotentials' atomic wavefunctions";
116 " left out by control.interpolation.trial_shells";
130 [[nodiscard]]
static std::vector<std::vector<bool>>
131 kept_shells(
const Crystal& crystal_structure,
133 const std::map<std::string, std::vector<int>>& trial_shells) {
134 std::vector<std::vector<bool>> kept(pseudopotential_set.
size());
135 std::map<std::string, int> type_of_species;
136 for (
int atom_index = 0; atom_index < crystal_structure.
number_of_atoms(); atom_index++) {
137 type_of_species.emplace(crystal_structure.
element(atom_index),
140 for (std::size_t type_index = 0; type_index < kept.size(); type_index++) {
141 kept[type_index].assign(pseudopotential_set[type_index].wavefunctions_atomic.size(),
144 for (
const auto& [species, shells] : trial_shells) {
145 const auto found = type_of_species.find(species);
146 if (found == type_of_species.end()) {
147 throw std::invalid_argument(
"control.interpolation.trial_shells names " + species +
148 ", which is not a species of this material.");
150 const auto& wavefunctions = pseudopotential_set[found->second].wavefunctions_atomic;
151 std::vector<bool> named(wavefunctions.size(),
false);
152 for (
const int shell : shells) {
153 if (shell < 0 || shell >=
static_cast<int>(wavefunctions.size())) {
154 throw std::invalid_argument(
155 "control.interpolation.trial_shells." + species +
" lists shell " +
156 std::to_string(shell) +
", but its pseudopotential lists " +
157 std::to_string(wavefunctions.size()) +
" atomic wavefunctions.");
159 if (wavefunctions[shell].occupations < 0.0) {
160 throw std::invalid_argument(
"control.interpolation.trial_shells." + species +
161 " lists shell " + std::to_string(shell) +
162 ", which its pseudopotential marks not to be used "
163 "as an orbital (a negative "
164 "occupation, or a radial function of zero norm).");
168 kept[found->second] = named;
173 const PseudopotentialSet& pseudopotential_set_;
174 std::vector<AtomicOrbitalLabel> orbital_labels_;
176 std::vector<int> kept_rows_;
178 int number_of_rendered_orbitals_ = 0;
179 std::vector<std::vector<std::vector<Real>>> atomic_wavefunction_table_;
180 std::vector<Vector3D> centers_crystal_;
181 Real q_spacing_ = 0.01;
182 int number_of_q_points_ = 900;
void build(int kpoint_index, int number_of_plane_waves, const std::vector< int > &g_vector_indices, const Crystal &crystal_structure, const KPointsGrid &kpoint_grid, const PlanewaveBasis &planewave_basis, std::vector< std::vector< Complex > > &orbitals) const override
void build_atomic_orbitals_g_space(int kpoint_index, int number_of_plane_waves, const std::vector< int > &g_vector_indices, const Crystal &crystal_structure, const KPointsGrid &kpoint_grid, const PlanewaveBasis &planewave_basis, const PseudopotentialSet &pseudopotential_set, const std::vector< std::vector< std::vector< Real > > > &atomic_wavefunction_table, Real q_spacing, int number_of_q_points, std::vector< std::vector< Complex > > &orbitals)