69 throw std::invalid_argument(
70 "LocalOrbitalHamiltonian::set_domain: number_of_orbitals must be positive");
73 throw std::invalid_argument(
74 "LocalOrbitalHamiltonian::set_domain: the domain must hold at least one lattice "
79 hamiltonian_blocks_.clear();
80 overlap_blocks_.clear();
87 translations_.clear();
88 bloch_sum_weights_.clear();
89 translations_.reserve(lattice_vectors_.size());
90 bloch_sum_weights_.reserve(lattice_vectors_.size());
92 translations_.push_back(entry.translation);
93 bloch_sum_weights_.push_back(entry.bloch_sum_weight);
102 require_block_shapes(blocks,
"set_hamiltonian");
103 hamiltonian_blocks_ = std::move(blocks);
111 require_block_shapes(blocks,
"set_overlap");
112 overlap_blocks_ = std::move(blocks);
116 return !overlap_blocks_.empty();
120 return number_of_orbitals_;
124 return lattice_vectors_;
128 return hamiltonian_blocks_;
132 return overlap_blocks_;
141 if (hamiltonian_blocks_.empty()) {
142 throw std::runtime_error(
143 "LocalOrbitalHamiltonian::hamiltonian_at_kpoint: no Hamiltonian blocks set");
145 return bloch_sum(hamiltonian_blocks_, kpoint);
150 if (overlap_blocks_.empty()) {
151 std::vector<Complex> identity(
static_cast<std::size_t
>(number_of_orbitals_) *
154 for (
int index = 0; index < number_of_orbitals_; index++) {
155 identity[
static_cast<std::size_t
>(index) * number_of_orbitals_ + index] =
160 return bloch_sum(overlap_blocks_, kpoint);
171 if (hamiltonian_blocks_.size() != lattice_vectors_.size()) {
172 throw std::runtime_error(
"LocalOrbitalHamiltonian::maximum_hamiltonian_magnitude_"
173 "beyond: no Hamiltonian blocks set");
176 for (std::size_t vector_index = 0; vector_index < lattice_vectors_.size(); vector_index++) {
177 if (lattice_vectors_[vector_index].cartesian.norm() < minimum_distance) {
180 for (
const Complex& element : hamiltonian_blocks_[vector_index]) {
181 worst = std::max(worst, std::abs(element));
188 [[nodiscard]] std::vector<Complex> bloch_sum(
const std::vector<std::vector<Complex>>& blocks,
191 kpoint, blocks, translations_, bloch_sum_weights_);
194 void require_block_shapes(
const std::vector<std::vector<Complex>>& blocks,
195 const char* what)
const {
196 if (lattice_vectors_.empty()) {
197 throw std::runtime_error(std::string(
"LocalOrbitalHamiltonian::") + what +
198 ": set_domain() has not been called");
200 if (blocks.size() != lattice_vectors_.size()) {
201 throw std::invalid_argument(std::string(
"LocalOrbitalHamiltonian::") + what +
": " +
202 std::to_string(blocks.size()) +
" blocks were given for " +
203 std::to_string(lattice_vectors_.size()) +
206 const std::size_t block_size =
207 static_cast<std::size_t
>(number_of_orbitals_) * number_of_orbitals_;
208 for (std::size_t vector_index = 0; vector_index < blocks.size(); vector_index++) {
209 if (blocks[vector_index].size() != block_size) {
210 throw std::invalid_argument(std::string(
"LocalOrbitalHamiltonian::") + what +
211 ": block " + std::to_string(vector_index) +
" holds " +
212 std::to_string(blocks[vector_index].size()) +
213 " entries, not " + std::to_string(number_of_orbitals_) +
214 " x " + std::to_string(number_of_orbitals_));
219 int number_of_orbitals_ = 0;
220 std::vector<LocalOrbitalLatticeVector> lattice_vectors_;
222 std::vector<IntegerVector3D> translations_;
223 std::vector<Real> bloch_sum_weights_;
224 std::vector<std::vector<Complex>> hamiltonian_blocks_;
225 std::vector<std::vector<Complex>> overlap_blocks_;