High-precision calculations for one- and two-valence atomic systems
TDHFcomplex.hpp
1#pragma once
2#include "TDHF.hpp"
3#include <complex>
4#include <string>
5#include <utility>
6#include <vector>
7
8namespace ExternalField {
9
10/*!
11 @brief TDHF (RPA) core polarisation above ionisation threshold(s): the open
12 channels are solved with the outgoing-wave boundary condition, so the
13 corrections and the corrected matrix elements are complex.
14
15 @details
16 As @ref TDHF, for a frequency above the ionisation threshold of one or more
17 core orbitals,
18
19 \f[
20 \en^a_+ = \en_a + \omega > 0.
21 \f]
22
23 Every X (+) channel of such an orbital is open, and describes the ejected
24 electron. For it, the solution of the TDHF equation regular at the origin is
25 not unique (the continuum orbital at en_+ may be added freely);
26 the physical solution is the purely outgoing wave at large r,
27 which is complex.
28
29 All other channels (closed orbitals, and every Y (-) partner) are bound,
30 and are solved as in TDHF.
31 Through dV every correction is complex: the real and imaginary parts
32 are stored as separate sets (m_X, m_Y and m_Xi, m_Yi) and iterated
33 together. Below every threshold the imaginary sets are exactly zero and the
34 class reproduces TDHF.
35
36 In dV the (-) corrections enter as complex conjugates, so the Y sets store
37 \f$ (\varphi_-)^* \f$ and the (real-linear) dV builder of TDHF applies to
38 each set unchanged; the external field drives the real set only, and the
39 two sets couple solely through the outgoing boundary condition.
40
41 \par Open channels
42 The ejected electron moves in the field of the residual ion: the
43 self-interaction of one electron in the ionised orbital,
44 \f$ V^a_0 = y^0_{aa} + X_a \f$ (direct and one-electron exchange), is moved
45 from the HF Hamiltonian into the source. This is an exact rearrangement:
46 the channel Hamiltonian has the correct -1/r tail, and the source is short
47 ranged (the y^0_aa term cancels, pointwise, the 1/r tail of the a term of
48 dV phi_a).
49
50 With the real regular and irregular solutions F_reg, F_irr of the local
51 channel Hamiltonian at en_+ (F_reg + i F_irr is outgoing), the standing-wave
52 solve returns \f$ \varphi_P \to K F_{\rm irr} \f$, and the outgoing solution
53 is \f$ \varphi_+ = \varphi_P - iK F_{\rm reg} \f$.
54
55 With the non-local
56 exchange iterated in the source, F_reg is replaced by the exchange-dressed
57 regular solution \f$ F^{\rm HF} \to F_{\rm reg} + K_{\rm ex} F_{\rm irr} \f$
58 (built once per channel per omega), and
59
60 \f[ K_+ = \frac{K}{1 + iK_{\rm ex}}, \f]
61
62 and
63
64 \f[
65 \varphi_+ = \varphi_P - iK_+F^{\rm HF}
66 \to -iK_+\left(F_{\rm reg} + iF_{\rm irr}\right).
67 \f]
68
69 For a complex source, phi_P is two real standing-wave solves
70 (@ref solveContinuumMixedState).
71
72 \par Iteration
73 The TDHF map is linear in the corrections, and damped iteration diverges
74 near resonances (autoionising resonances, omega ~ en_b - en_a). The
75 self-consistency is therefore driven by Anderson mixing
76 (@ref anderson_coefficients) of the whole state, all corrections together
77 with the channel amplitudes K_+ (linear in the state), which converges
78 wherever the linear problem is non-singular.
79
80 \par Usage
81 As TDHF: @ref solve_core (omega), then
82 - @ref A_phys: the ionisation amplitude of each open channel,
83 \f$ A = K_+^* / \pi \f$, in @ref channel_list order. |A| replaces
84 \f$ |\redmatel{\en\kappa}{t}{a}| \f$ in cross-sections (energy-normalised
85 continuum states); the conjugate is the conventional normalisation of
86 the final state to incoming waves. The phase is relative to the regular
87 solution of the local channel potential: the relative phase of two
88 operators in the same channel is physical, absolute phases and phases
89 between channels are not.
90 - @ref dV_complex (Fa, Fb): the complex \f$ \redmatel{a}{\delta V}{b} \f$;
91 equals TDHF::dV below every threshold.
92*/
93class TDHFcntm : public TDHF {
94
95public:
96 //! Constructs for operator h_plus (with optional h_minus); see
97 //! @ref TDHF::TDHF.
98 TDHFcntm(const DiracOperator::TensorOperator *const h_plus,
99 const HF::HartreeFock *const hf,
100 const DiracOperator::TensorOperator *const h_minus = nullptr);
101
102 //! Open channel: core-orbital index, ejected-electron kappa, and its
103 //! energy en = en_a + omega
104 struct Channel {
105 std::size_t i_core;
106 int kappa;
107 double en;
108 };
109
110 /*!
111 @brief Solves the (complex) TDHF equations self-consistently at omega.
112 @param omega Frequency (atomic units); its magnitude is used.
113 @param max_its Maximum number of iterations; 1 gives the first-order
114 (outgoing-wave) correction.
115 @param print If true, write convergence progress to screen.
116 @details Re-solving at the same omega warm-starts from the previous
117 solution; the continuum data of the open channels is rebuilt only when
118 omega changes.
119 */
120 void solve_core(double omega, int max_its = 100, bool print = true) override;
121
122 //! Clears the corrections and the continuum channel data
123 void clear() override;
124
125 //! Open channels at the omega of the last solve_core(), in @ref A_phys
126 //! order; empty before solve_core(), or if no channel is open
127 std::vector<Channel> channel_list() const;
128
129 //! Ionisation amplitude A = K_+^*/pi of every open channel (see class
130 //! description), in @ref channel_list order. Requires solve_core().
131 std::vector<std::complex<double>> A_phys() const;
132
133 //! A (see @ref A_phys) of the channel of core orbital Fa with
134 //! ejected-electron kappa; zero if that channel is closed
135 std::complex<double> A_phys(const DiracSpinor &Fa, int kappa) const;
136
137 /*!
138 @brief Reduced matrix element of the (complex) induced potential,
139 \f$ \redmatel{a}{\delta V}{b} \f$, or the conjugate
140 \f$ \redmatel{a}{\delta V^\dagger}{b} \f$ if en_b > en_a; as
141 @ref TDHF::dV, complex.
142 @details Real, and equal to TDHF, below every threshold. For a continuum
143 bra (en_a > 0), Fa must be the energy-normalised continuum state of hole
144 Fb in the V^{N-1} potential (direct y^0_bb and one-electron exchange of
145 Fb removed); the source then includes the hole term V^b_0 phi of the
146 rearranged channel equation, so that <Fa||t||b> + dV_complex(Fa, Fb) is
147 the outgoing-wave amplitude, |A| of @ref A_phys in the phase reference
148 of Fa.
149 */
150 std::complex<double> dV_complex(const DiracSpinor &Fa,
151 const DiracSpinor &Fb) const;
152
153 //! Real part of @ref dV_complex, for bound Fa and Fb (exact below every
154 //! threshold, where the class acts as TDHF). For a continuum state use
155 //! dV_complex.
156 double dV(const DiracSpinor &Fa, const DiracSpinor &Fb) const override;
157 using TDHF::dV;
158
159private:
160 // Imaginary parts of the corrections, indexed as m_X / m_Y (the real
161 // parts). The Y sets store conj(Y) (see class description).
162 std::vector<std::vector<DiracSpinor>> m_Xi{};
163 std::vector<std::vector<DiracSpinor>> m_Yi{};
164
165 // Continuum data of one (core orbital x channel) at fixed omega: whether
166 // the channel is open (en_+ > 0 and resolvable on the grid); the
167 // homogeneous pair Freg/Firr at en_+ in the local channel potential
168 // (vlocal - y^0_aa + U_KS); the exchange-dressed regular solution
169 // F^HF ~ Freg + K_ex Firr; and the outgoing amplitude K_+ of the latest
170 // solve. Indexed as m_X.
171 struct ContinuumChannel {
172 bool open{false};
173 DiracSpinor Freg;
174 DiracSpinor Firr;
175 DiracSpinor Fhf;
176 double K_ex{0.0};
177 std::complex<double> K{0.0};
178 };
179 std::vector<std::vector<ContinuumChannel>> m_channels{};
180 // The omega m_channels was built at (rebuilt when it changes)
181 double m_omega{-1.0};
182
183 // (Re)shapes the imaginary sets to m_X / m_Y, zeroed
184 void zero_imaginary_sets();
185
186 // Builds m_channels for omega: for each open channel the pair Freg/Firr,
187 // then F^HF and K_ex
188 void prepare_channels(double omega);
189
190 // (i_core, i_channel) of the channel of core orbital Fb with kappa
191 std::pair<std::size_t, std::size_t> channel_index(const DiracSpinor &Fb,
192 int kappa) const;
193
194 // One (undamped) application of the complex TDHF map to the stored
195 // corrections, all (core orbital x channel x X/Y) solves task-flattened;
196 // returns the convergence measure {eps, worst channel}
197 std::pair<double, std::string> tdhf_core_it_complex(double omega);
198
199 // Outgoing-wave solve of one open X channel: real and imaginary parts of
200 // the previous iterate in, new iterate out; K_+ written to the channel
201 void solve_channel_outgoing(DiracSpinor *X_re, DiracSpinor *X_im,
202 ContinuumChannel *channel, const DiracSpinor &Fb,
203 const DiracSpinor &hFb, const DiracSpinor &dV_re,
204 const DiracSpinor &dV_im, double omega,
205 double eps_ms) const;
206
207 // Bound channel (closed orbital, or the Y partner of an ionised orbital),
208 // as TDHF. hFb may be nullptr (no external-field source: the imaginary
209 // part).
210 void solve_channel_bound(DiracSpinor *dF_beta, const DiracSpinor &Fb,
211 const DiracSpinor *hFb, const DiracSpinor &dV_src,
212 double omega, dPsiType XorY, double eps_ms) const;
213
214 // The hole term V^a_0 chi = (y^0_aa + X_a) chi of ionised orbital Fa: the
215 // one-electron self-interaction moved from the Hamiltonian of the open
216 // channels into their source
217 DiracSpinor hole_compensation(const DiracSpinor &Fa,
218 const DiracSpinor &chi) const;
219
220 // Convergence measure of one iteration: bound channels, the relative L2
221 // change of (X_re, X_im) over the norm of ALL X channels (a negligible
222 // bound remnant must not gate the iteration); open channels,
223 // |dK_+|^2 / max(|K_+|^2, floor). K_old indexed as m_channels.
224 std::pair<double, std::string> eps_complex(
225 const std::vector<std::vector<DiracSpinor>> &Xs_re,
226 const std::vector<std::vector<DiracSpinor>> &Xs_im,
227 const std::vector<std::vector<std::complex<double>>> &K_old) const;
228
229 // The full state (all corrections, real and imaginary, and the channel
230 // amplitudes) as one real vector, and back: the Anderson iterate
231 std::vector<double> state_vector() const;
232 void set_state(const std::vector<double> &state);
233
234public:
235 TDHFcntm &operator=(const TDHFcntm &) = delete;
236 TDHFcntm(const TDHFcntm &) = default;
237 ~TDHFcntm() = default;
238};
239
240} // 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:44
Uses TDHF to include core-polarisation (RPA) corrections to matrix elements of an external field oper...
Definition TDHF.hpp:59
double dV(const DiracSpinor &Fa, const DiracSpinor &Fb, bool conj) const
Returns reduced matrix element , or the conjugate if conj=true.
Definition TDHF.cpp:398
TDHF (RPA) core polarisation above ionisation threshold(s): the open channels are solved with the out...
Definition TDHFcomplex.hpp:93
void solve_core(double omega, int max_its=100, bool print=true) override
Solves the (complex) TDHF equations self-consistently at omega.
Definition TDHFcomplex.cpp:138
std::complex< double > dV_complex(const DiracSpinor &Fa, const DiracSpinor &Fb) const
Reduced matrix element of the (complex) induced potential, , or the conjugate if en_b > en_a; as TDH...
Definition TDHFcomplex.cpp:576
double dV(const DiracSpinor &Fa, const DiracSpinor &Fb) const override
Real part of dV_complex, for bound Fa and Fb (exact below every threshold, where the class acts as TD...
Definition TDHFcomplex.cpp:599
TDHFcntm(const DiracOperator::TensorOperator *const h_plus, const HF::HartreeFock *const hf, const DiracOperator::TensorOperator *const h_minus=nullptr)
Constructs for operator h_plus (with optional h_minus); see TDHF::TDHF.
Definition TDHFcomplex.cpp:22
std::vector< std::complex< double > > A_phys() const
Ionisation amplitude A = K_+^*‍/pi of every open channel (see class description), in channel_list ord...
Definition TDHFcomplex.cpp:551
std::vector< Channel > channel_list() const
Open channels at the omega of the last solve_core(), in A_phys order; empty before solve_core(),...
Definition TDHFcomplex.cpp:523
void clear() override
Clears the corrections and the continuum channel data.
Definition TDHFcomplex.cpp:39
Open channel: core-orbital index, ejected-electron kappa, and its energy en = en_a + omega.
Definition TDHFcomplex.hpp:104
Solves relativistic Hartree-Fock equations for core and valence. Optionally includes Breit and QED ef...
Definition HartreeFock.hpp:111
Core-polarisation (RPA) corrections to matrix elements of an external field.
Definition MatrixElements.hpp:9
dPsiType
Selects the perturbed orbital: X = varphi_+, Y = varphi_-.
Definition CorePolarisation.hpp:115