Loading...
Searching...
No Matches
guided_phase_branch.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * GuidedPhaseBranch — each diagonal phase on the branch nearest the one a
5 * guiding centre implies:
6 *
7 * phase = Im ln M_nn + 2 pi m, m = round[ (-b . r_guide - Im ln M_nn) / 2pi ]
8 *
9 * which is continuous as the gauge rotates a diagonal element through the
10 * negative real axis, because m steps by one exactly when Im ln steps by
11 * 2 pi the other way. The centres are fixed when this is built and never
12 * move: a branch that followed the gauge would make the functional a
13 * different one at every step of a minimisation.
14 */
15
16#include <cmath>
17#include <complex>
18#include <cstddef>
19#include <stdexcept>
20#include <string>
21#include <utility>
22#include <vector>
23
27
28namespace q3 {
29
31 public:
32 /// `centers_bohr`: one per Wannier function, Cartesian, in the frame and unit of the b-vectors.
33 explicit GuidedPhaseBranch(std::vector<Vector3D> centers_bohr)
34 : centers_bohr_(std::move(centers_bohr)) {
35 if (centers_bohr_.empty()) {
36 throw std::invalid_argument("GuidedPhaseBranch: no guiding centres were given");
37 }
38 }
39
40 void require_serves(int number_of_wannier_functions) const override {
41 if (static_cast<int>(centers_bohr_.size()) != number_of_wannier_functions) {
42 throw std::invalid_argument(
43 "GuidedPhaseBranch: " + std::to_string(centers_bohr_.size()) +
44 " guiding centres were given for " + std::to_string(number_of_wannier_functions) +
45 " Wannier functions");
46 }
47 }
48
49 [[nodiscard]] Real phase_of(const Complex& diagonal_overlap,
50 int wannier_function,
51 const Vector3D& b_vector) const override {
52 const Real phase = std::arg(diagonal_overlap);
53 const Real expected =
54 -b_vector.dot(centers_bohr_[static_cast<std::size_t>(wannier_function)]);
55 return phase + constants::two_pi * std::round((expected - phase) / constants::two_pi);
56 }
57
58 private:
59 std::vector<Vector3D> centers_bohr_;
60};
61
62} // namespace q3
GuidedPhaseBranch(std::vector< Vector3D > centers_bohr)
centers_bohr: one per Wannier function, Cartesian, in the frame and unit of the b-vectors.
void require_serves(int number_of_wannier_functions) const override
Refuses, with std::invalid_argument, a functional of a size this branch cannot serve.
Real phase_of(const Complex &diagonal_overlap, int wannier_function, const Vector3D &b_vector) const override
constexpr Real two_pi
Definition constants.hpp:25
double Real
std::complex< double > Complex
Real dot(const Vector3D &other) const
Definition vector_3d.hpp:59