ampsci
High-precision calculations for one- and two-valence atomic systems
TDHF.hpp
1#pragma once
2#include "CorePolarisation.hpp"
3#include <string>
4#include <vector>
5class DiracSpinor;
6namespace DiracOperator {
7class TensorOperator;
8}
9namespace MBPT {
10class CorrelationPotential;
11}
12
13namespace HF {
14class HartreeFock;
15class Breit;
16} // namespace HF
17
18namespace ExternalField {
19
20/*!
21 @brief Uses TDHF to include core-polarisation (RPA) corrections to matrix
22 elements of an external field operator.
23
24 @details
25 Solves the TDHF equations for each core orbital \f$ \phi_a \f$,
26 \f[
27 (h_{\rm HF} - \en_a \mp \omega)\varphi^a_\pm
28 = -(t_\pm + \delta V_\pm - \delta\en^a_\pm)\phi_a,
29 \f]
30 self-consistently to determine \f$ \delta V_\pm \f$.
31 See the @ref ExternalField namespace documentation for full physics description.
32
33 Each core orbital acquires both a forward (\f$ \varphi^a_+ \f$, stored as X)
34 and backward (\f$ \varphi^a_- \f$, stored as Y) correction. Both contribute
35 to \f$ \delta V_\pm \f$:
36 \f[
37 \delta V_\pm \phi_i =
38 \sum_a^{\rm core} \left[
39 \matel{\phi_a}{Q}{\varphi^a_+}\phi_i - \matel{\phi_a}{Q}{\phi_i}\varphi^a_+
40 + \matel{\varphi^a_-}{Q}{\phi_a}\phi_i - \matel{\varphi^a_-}{Q}{\phi_i}\phi_a
41 \right].
42 \f]
43 It is via \f$ \delta V_\pm \f$ that the \f$ e^{\pm i\omega t} \f$ terms are mixed.
44
45 \par Construction
46 Requires a pointer to the forward operator (\f$ t_+ \f$), a const
47 @ref HF::HartreeFock object, and an optional pointer to the backward
48 operator (\f$ t_- \f$). If @p h_minus is omitted, \f$ t_- \f$ is taken
49 to be the same pointer as \f$ t_+ \f$.
50 The user is responsible for updating operator frequencies externally
51 before calling solve_core().
52 Note: Only need \f$t_-\f$ for operators that depend on the sign of the frequency (e.g., E1v). Most depend only on magnitude, in which case \f$t_- = t_+^\dag \f$, which is dealt with automatically.
53
54 \par Usage
55 @ref solve_core (omega) solves the TDHF equations for a given frequency.
56 @ref dV (Fa, Fb) then returns the RPA correction to the reduced matrix element
57 \f$ \redmatel{a}{\delta V}{b} \f$.
58*/
59class TDHF : public CorePolarisation {
60
61protected:
62 // dPhi = X exp(-iwt) + Y exp(+iwt)
63 // (H - e - w)X = -(h + dV - de)Phi
64 // (H - e + w)Y = -(h* + dV* - de)Phi
65 // X_c = sum_x X_x,
66 // j(x)=j(c)-k,...,j(c)+k. And: pi(x) = pi(c)*pi(h)
67 std::vector<std::vector<DiracSpinor>> m_X{};
68 std::vector<std::vector<DiracSpinor>> m_Y{};
69 std::vector<std::vector<DiracSpinor>> m_hFcore{};
70 std::vector<std::vector<DiracSpinor>> m_hFcore_minus{};
71 // can just write these to disk! Read them in, continue as per normal
72
73 const HF::HartreeFock *const p_hf;
74 const std::vector<DiracSpinor> m_core;
75 // const std::vector<double> m_Hmag;
76 const double m_alpha;
77 const HF::Breit *const p_VBr;
78 // nb: m_h_plus := m_h is the one in CorePolarisation
79 const DiracOperator::TensorOperator *const m_h_minus;
80
81public:
82 /*!
83 @brief Constructs TDHF for operator h.
84
85 @param h_plus Forward operator \f$ t_+ \f$; must be set to positive
86 frequency before each call to solve_core().
87 @param hf @ref HF::HartreeFock object defining the core.
88 @param h_minus Backward operator \f$ t_- \f$; if nullptr (default), uses
89 @p h_plus. Only needed when the operator is frequency-dependent
90 *and* depends on the **sign** of \f$ \omega \f$ (e.g. E1
91 velocity form). For operators that depend only on
92 \f$ |\omega| \f$ (e.g. M1), the default suffices.
93 */
94 TDHF(const DiracOperator::TensorOperator *const h_plus,
95 const HF::HartreeFock *const hf,
96 const DiracOperator::TensorOperator *const h_minus = nullptr);
97
98 /*!
99 @brief Solves TDHF equations self-consistently for core electrons at frequency omega.
100 @details
101 Iterates the TDHF equations until \f$ \delta V_\pm \f$ converges to within
102 eps_target(), or @p max_its iterations have been performed.
103 Can be re-run at a different frequency without restarting from scratch.
104
105 @param omega External-field frequency \f$ \omega \f$ in atomic units.
106 @param max_its Maximum number of iterations.
107 Set to 1 to get the first-order correction (no damping on
108 first iteration).
109 @param print If true, write convergence progress to screen.
110
111 @note Frequency should be positive; negative is allowed but use with care.
112 Unlike @ref DiagramRPA, TDHF solves for both \f$ \varphi^a_+ \f$ and
113 \f$ \varphi^a_- \f$ simultaneously (see class docs), so a single call
114 covers both contributions to \f$ \delta V_\pm \f$.
115
116 ---
117
118 @note Does not update the frequency of the operator itself; for frequency-dependent
119 operators, update the operator frequency externally before calling.
120 */
121 virtual void solve_core(double omega, int max_its = 100,
122 bool print = true) override;
123
124 virtual Method method() const override { return Method::TDHF; }
125
126 virtual void clear() override final;
127
128 //! Returns reduced matrix element \f$\redmatel{a}{\delta V}{b}\f$,
129 //! or the conjugate \f$\redmatel{a}{\delta V^\dagger}{b}\f$ if conj=true.
130 double dV(const DiracSpinor &Fa, const DiracSpinor &Fb, bool conj) const;
131
132 virtual double dV(const DiracSpinor &Fa,
133 const DiracSpinor &Fb) const override final;
134
135 DiracSpinor dV_rhs(int kappa_n, const DiracSpinor &Fm,
136 bool conj = false) const override;
137
138 //! Returns const ref to dPsi orbitals for given core orbital Fc.
139 const std::vector<DiracSpinor> &get_dPsis(const DiracSpinor &Fc,
140 dPsiType XorY) const;
141 //! Returns const ref to dPsi orbital of given kappa.
142 const DiracSpinor &get_dPsi_x(const DiracSpinor &Fc, dPsiType XorY,
143 const int kappa_x) const;
144
145 /*!
146 @brief Forms \f$\varphi^v_\pm\f$ for valence state Fv (including core pol.):
147 single kappa channel.
148 @details
149 Solves
150 \f[ (h_{\rm HF} + \Sigma - \en_v - \omega)\varphi^v_+
151 = -(t + \delta V - \delta\en^v)\phi_v \f]
152 or
153 \f[ (h_{\rm HF} + \Sigma - \en_v + \omega)\varphi^v_-
154 = -(t^\dagger + \delta V^\dagger - \delta\en^v)\phi_v \f]
155 Returns \f$ \chi_\beta \f$ for given kappa_beta, where
156 \f[ X_{j,m} = (-1)^{j_\beta-m}tjs(j,k,j;-m,0,m)\chi_j \f]
157
158 @param Fv Valence state \f$\phi_v\f$.
159 @param omega Perturbation frequency \f$\omega\f$.
160 @param XorY Selects X or Y solution; see @ref dPsiType.
161 @param kappa_beta Kappa quantum number of the target channel.
162 @param Sigma Optional correlation potential; see @ref MBPT::CorrelationPotential.
163 @param st Bra or ket convention; see @ref StateType.
164 @param incl_dV Include the induced potential \f$\delta V\f$ if true.
165 */
167 solve_dPsi(const DiracSpinor &Fv, const double omega, dPsiType XorY,
168 const int kappa_beta,
169 const MBPT::CorrelationPotential *const Sigma = nullptr,
170 StateType st = StateType::ket, bool incl_dV = true) const;
171
172 //! Forms \f$\varphi^v_\pm\f$ for all kappa channels; see @ref solve_dPsi.
173 std::vector<DiracSpinor>
174 solve_dPsis(const DiracSpinor &Fv, const double omega, dPsiType XorY,
175 const MBPT::CorrelationPotential *const Sigma = nullptr,
176 StateType st = StateType::ket, bool incl_dV = true) const;
177
178 // //! Writes dPsi (f-component) to textfile
179 // void print(const std::string &ofname = "dPsi.txt") const;
180
181private:
182 void initialise_dPsi();
183
184 // Single iteration of TDHF equations
185 std::pair<double, std::string> tdhf_core_it(double omega, double eta_damp);
186 // Forms set of h*Fc for all core orbitals and all projections
187 std::vector<std::vector<DiracSpinor>>
188 form_hFcore(const DiracOperator::TensorOperator *h) const;
189 // Solves the MS equations for all projections, single core state
190 void solve_ms_core(std::vector<DiracSpinor> &dFb, const DiracSpinor &Fb,
191 const std::vector<DiracSpinor> &hFbs, const double omega,
192 dPsiType XorY, double eps_ms = 1.0e-9) const;
193
194public:
195 TDHF &operator=(const TDHF &) = delete;
196 TDHF(const TDHF &) = default;
197 ~TDHF() = default;
198};
199
200} // namespace ExternalField
General tensor operator (virtual base class); all single-particle (one-body) tenosor operators derive...
Definition TensorOperator.hpp:198
Stores radial Dirac spinor: F_nk = (f, g)
Definition DiracSpinor.hpp:42
Virtual base class for core-polarisation (RPA); computes dV corrections.
Definition CorePolarisation.hpp:140
Uses TDHF to include core-polarisation (RPA) corrections to matrix elements of an external field oper...
Definition TDHF.hpp:59
virtual void clear() override final
Clears the internal state back to pre solve_core()
Definition TDHF.cpp:72
const DiracSpinor & get_dPsi_x(const DiracSpinor &Fc, dPsiType XorY, const int kappa_x) const
Returns const ref to dPsi orbital of given kappa.
Definition TDHF.cpp:89
double dV(const DiracSpinor &Fa, const DiracSpinor &Fb, bool conj) const
Returns reduced matrix element , or the conjugate if conj=true.
Definition TDHF.cpp:344
std::vector< DiracSpinor > solve_dPsis(const DiracSpinor &Fv, const double omega, dPsiType XorY, const MBPT::CorrelationPotential *const Sigma=nullptr, StateType st=StateType::ket, bool incl_dV=true) const
Forms for all kappa channels; see solve_dPsi.
Definition TDHF.cpp:98
const std::vector< DiracSpinor > & get_dPsis(const DiracSpinor &Fc, dPsiType XorY) const
Returns const ref to dPsi orbitals for given core orbital Fc.
Definition TDHF.cpp:79
virtual void solve_core(double omega, int max_its=100, bool print=true) override
Solves TDHF equations self-consistently for core electrons at frequency omega.
Definition TDHF.cpp:278
virtual Method method() const override
Returns RPA method.
Definition TDHF.hpp:124
DiracSpinor dV_rhs(int kappa_n, const DiracSpinor &Fm, bool conj=false) const override
Returns [dV_pm * phi_m]_kappa: RHS of TDHF eq., projected onto kappa (see namespace doc)
Definition TDHF.cpp:356
DiracSpinor solve_dPsi(const DiracSpinor &Fv, const double omega, dPsiType XorY, const int kappa_beta, const MBPT::CorrelationPotential *const Sigma=nullptr, StateType st=StateType::ket, bool incl_dV=true) const
Forms for valence state Fv (including core pol.): single kappa channel.
Definition TDHF.cpp:111
Breit potentials for one- (Hartree-Fock Breit) and two-body Breit integrals.
Definition Breit.hpp:88
Solves relativistic Hartree-Fock equations for core and valence. Optionally includes Breit and QED ef...
Definition HartreeFock.hpp:72
Dirac operators: TensorOperator base class and derived implementations for single-particle (one-body)...
Definition GenerateOperator.cpp:6
Core-polarisation (RPA) corrections to matrix elements of an external field.
Definition calcMatrixElements.cpp:14
StateType
Whether the state is a bra or ket.
Definition CorePolarisation.hpp:112
dPsiType
Selects the perturbed orbital: X = varphi_+, Y = varphi_-.
Definition CorePolarisation.hpp:110
Method
Available RPA/core-polarisation methods.
Definition CorePolarisation.hpp:82
Functions and classes for Hartree-Fock.
Definition CI_Integrals.hpp:13
Many-body perturbation theory.
Definition CI_Integrals.hpp:10
void Breit(const IO::InputBlock &input, const Wavefunction &wf)
Breit corrections to HF energies and matrix elements.
Definition Breit.cpp:38