ampsci
c++ program for high-precision atomic structure calculations of single-valence systems
Feynman.hpp
1 #pragma once
2 #include "HF/HartreeFock.hpp"
3 #include "MBPT/RDMatrix.hpp"
4 #include "Maths/Grid.hpp"
5 #include "Wavefunction/DiracSpinor.hpp"
6 #include <memory>
7 #include <vector>
8 
9 namespace MBPT {
10 
11 // FeynmanOptions class
12 
15 enum class HoleParticle { exclude, include, include_k0 };
16 
18 enum class Screening { exclude, include, only };
19 
20 struct FeynmanOptions {
21  Screening screening{Screening::exclude};
22  HoleParticle hole_particle{HoleParticle::exclude};
23  int max_l_internal{6};
24  double omre{-0.3};
25  double w0{0.05};
26  double w_ratio{1.5};
27  // int n_min_core{1};
28 };
29 
31 enum class GreenStates { both, core, excited };
32 
33 //------------------------------------------------------------------------------
35 class Feynman {
36 
37  // Pointer to HF potential, and HF core
38  const HF::HartreeFock *m_HF;
39  // Pointer to shared radial grid (full grid)
40  std::shared_ptr<const Grid> m_grid;
41  // Parameters of the sub-grid: initial/final points, stride
42  std::size_t m_i0, m_stride, m_subgrid_points;
43 
44  // maximum kappa_index appearing in the core
45  int m_max_ki_core;
46  // maximum kappa index to include for internal lines
47  int m_max_ki;
48  // maximum multipolarity, k
49  int m_max_k;
50  // Lowest n to polarise in polarisation operator
51  int m_min_core_n;
52  // real part of frequency for integration
53  double m_omre;
54  // Stores imaginary frequency grid (setup post-construction)
55  Grid m_wgrid;
56 
57  // Option: include hole-particle interaction into polarisation operator
58  bool m_hole_particle;
59  // Option to include higher-k in hp interaction
60  bool m_include_higher_order_hp;
61  // Include screening correction to Coulomb line in Q*Pi*Q => Q*Pi*X*Q
62  bool m_screen_Coulomb;
63  // _only_ include screening correction in Q*Pi*Q => Q*Pi*[X-1]*Q
64  bool m_only_screen;
65 
66  // Coulomb operator; include right integration measure
67  // q_ij := (r>^k/r<^{k+1}) * dr_j
68  std::vector<ComplexGMatrix> m_qk{};
69  // Left integration measure:
70  ComplexGMatrix m_dri;
71  // Right integration measure:
72  ComplexGMatrix m_drj;
73 
74  // Core projection operators (one for each core state)
75  std::vector<ComplexGMatrix> m_pa{};
76  // Hartree-Fock Exchange matrix (one for each happa)
77  std::vector<GMatrix> m_Vx_kappa{};
78 
79  // Effective Q*Pi*Q operator: for each imaginary omega, and each k
80  std::vector<std::vector<ComplexGMatrix>> m_qpiq_wk{};
81 
82  // For now, just for testing: switch between complex green methods
83  bool m_Complex_green_method = false;
84 
85 public:
94  Feynman(const HF::HartreeFock *vHF, std::size_t i0, std::size_t stride,
95  std::size_t size, const FeynmanOptions &options, int n_min_core,
96  bool verbose = true);
97 
98  bool screening() const { return m_screen_Coulomb; }
99  bool hole_particle() const { return m_hole_particle; }
100 
102  std::size_t stride() const { return m_stride; }
103 
104  int n_min() const { return m_min_core_n; }
105  double omre() const { return m_omre; }
106  double w0() const { return m_wgrid.r0(); }
107  double wratio() const { return m_wgrid.r(1) / m_wgrid.r(0); }
108  int lmax() const { return Angular::lFromIndex(m_max_ki); }
109 
111  ComplexGMatrix green(int kappa, std::complex<double> en,
112  GreenStates states) const;
113 
115  ComplexGMatrix polarisation_k(int k, std::complex<double> omega,
116  bool hole_particle) const;
117 
119  GMatrix Sigma_direct(int kappa_v, double en_v,
120  std::optional<int> k = {}) const;
121 
123  const ComplexGMatrix &get_qk(int k) const { return m_qk.at(std::size_t(k)); }
124 
126  const GMatrix &get_Vx_kappa(int kappa) const {
127  return m_Vx_kappa.at(std::size_t(Angular::indexFromKappa(kappa)));
128  }
129 
130 private:
131  // hack: checks if n_min_core is OK, updates if not
132  void check_min_n();
133  // forms Qk matrices, as well as dri, drj
134  void form_qk();
135  // Forms core projection operators
136  void form_pa();
137  // Forms HF exchange potential matrix
138  void form_vx();
139  // Sets up imaginary frequency grid
140  Grid form_w_grid(double w0, double wratio) const;
141  // Constructs the Q*Pi*Q Matrix along w grid, for each k
142  void form_qpiq();
143 
144  // Screening factor X = [1 + i qk*pik]^-1
145  ComplexGMatrix X_screen(const ComplexGMatrix &pik,
146  const ComplexGMatrix &qk) const;
147 
148  // Forms single "Green's function" contribution f*|ket><bra|
149  // (f is usually 1/(e-en))
150  ComplexGMatrix green_single(const DiracSpinor &ket, const DiracSpinor &bra,
151  const std::complex<double> f) const;
152 
153  // Forms full Hartree-Fock green's function. If Fc_hp is given,
154  // includes hole-particle contribution (Fc is polarised core state).
155  // Uses Dyson method to extend to complex energies.
156  ComplexGMatrix green_hf(int kappa, std::complex<double> en,
157  const DiracSpinor *Fc_hp = nullptr) const;
158 
159  // Forms full Hartree-Fock green's function. If Fc_hp is given,
160  // includes hole-particle contribution (Fc is polarised core state).
161  // Uses "Complex Dirac" method for complex energies.
162  ComplexGMatrix green_hf_v2(int kappa, std::complex<double> en,
163  const DiracSpinor *Fc_hp = nullptr) const;
164 
165  // Given Gr(wr), and wi (wr is real), returns Gr(wr + i*wi)
166  ComplexGMatrix green_to_complex(const ComplexGMatrix &Gr,
167  double om_imag) const;
168 
169  // Green's function, only due to core states
170  ComplexGMatrix green_core(int kappa, std::complex<double> en) const;
171 
172  // Greens function, only due to excited states (by orthog to core)
173  ComplexGMatrix green_excited(int kappa, std::complex<double> en,
174  const DiracSpinor *Fc_hp = nullptr) const;
175 
176  // Forces Green's fn to be orthog. to core
177  ComplexGMatrix orthogonalise_wrt_core(const ComplexGMatrix &g_in,
178  int kappa) const;
179 
180  // Given Dirac solutions regular at 0 (x0) and infinity (xI), forms "local"
181  // Green's function
182  GMatrix construct_green_g0(const DiracSpinor &x0, const DiracSpinor &xI,
183  const double w) const;
184 
185  // Given Dirac solutions regular at 0 (x0 + i*Ix0) and infinity (xI + i*IxI),
186  // forms "local" Green's function (complex).
187  ComplexGMatrix construct_green_g0(const DiracSpinor &x0,
188  const DiracSpinor &Ix0,
189  const DiracSpinor &xI,
190  const DiracSpinor &IxI,
191  const std::complex<double> w) const;
192 
193  // Calculates hole-particle potential (1-P)Vhp(1-P)
194  GMatrix calculate_Vhp(int kappa, const DiracSpinor &Fc) const;
195 
196  [[nodiscard]] const ComplexGMatrix &get_dri() const { return m_dri; }
197  [[nodiscard]] const ComplexGMatrix &get_drj() const { return m_drj; }
198 
199 public:
200  Feynman &operator=(const Feynman &) = default;
201  Feynman(const Feynman &) = default;
202  ~Feynman() = default;
203 };
204 
205 } // namespace MBPT
Stores radial Dirac spinor: F_nk = (f, g)
Definition: DiracSpinor.hpp:41
Holds grid, including type + Jacobian (dr/du)
Definition: Grid.hpp:31
auto r0() const
Minium (first) grid point.
Definition: Grid.hpp:58
const std::vector< double > & r() const
Grid points, r.
Definition: Grid.hpp:75
Solves relativistic Hartree-Fock equations for core and valence. Optionally includes Breit and QED ef...
Definition: HartreeFock.hpp:70
Class to construct Feynman diagrams, Green's functions and polarisation op.
Definition: Feynman.hpp:35
const GMatrix & get_Vx_kappa(int kappa) const
Returns (ref to) radial exchange matrix Vx_kappa. Nb: includes dri*drj.
Definition: Feynman.hpp:126
ComplexGMatrix polarisation_k(int k, std::complex< double > omega, bool hole_particle) const
Polarisation operator pi^k(w), for multipolarity k.
Definition: Feynman.cpp:462
ComplexGMatrix green(int kappa, std::complex< double > en, GreenStates states) const
Calculates Green's function for kappa, and complex energy.
Definition: Feynman.cpp:205
std::size_t stride() const
Returns stride used for sub-grid.
Definition: Feynman.hpp:102
Feynman(const HF::HartreeFock *vHF, std::size_t i0, std::size_t stride, std::size_t size, const FeynmanOptions &options, int n_min_core, bool verbose=true)
Construct Feynman diagram.
Definition: Feynman.cpp:15
GMatrix Sigma_direct(int kappa_v, double en_v, std::optional< int > k={}) const
Calculate Direct part of correlation potential.
Definition: Feynman.cpp:591
const ComplexGMatrix & get_qk(int k) const
Returns (reference to) q^k (radial) matrix. Note: includes drj.
Definition: Feynman.hpp:123
constexpr int lFromIndex(int i)
returns l, given kappa_index
Definition: Wigner369j.hpp:59
constexpr int indexFromKappa(int ka)
returns kappa_index, given kappa
Definition: Wigner369j.hpp:49
Many-body perturbation theory.
Definition: CI_Integrals.hpp:9
GreenStates
Which states to include in Green's function:
Definition: Feynman.hpp:31
Screening
Options for including Screening.
Definition: Feynman.hpp:18
HoleParticle
Options for including hole-particle interaction. include mean all k; include_k0 means k=0 term only.
Definition: Feynman.hpp:15