High-precision calculations for one- and two-valence atomic systems
CI_Integrals.hpp
1#pragma once
2#include "CSF.hpp"
3#include "Coulomb/QkTable.hpp"
4#include "Coulomb/meTable.hpp"
5#include "LinAlg/Matrix.hpp"
6#include "MBPT/Sigma2.hpp" //temp - remove after refactor
7#include <iostream>
8#include <map>
9#include <string>
10#include <utility>
11#include <vector>
12class DiracDiracSpinor;
13namespace MBPT {
14class CorrelationPotential;
15} // namespace MBPT
16namespace HF {
17class Breit;
18}
19
20namespace CI {
21
22//==============================================================================
23/*!
24 @brief Resummed derivative (dSigma/dE) correction to a Sigma_1 matrix
25 element (Kozlov formula).
26 @details
27 Returns the corrected matrix element,
28
29 \f[
30 \Sigma \to \Sigma \left[ 1 - \delta E \, (d\Sigma/dE)/\Sigma \right]^{-1},
31 \f]
32
33 which resums the linear expansion
34 \f$ \Sigma(\epsilon_0 + \delta E) \approx \Sigma + \delta E \, d\Sigma/dE \f$.
35
36 Guard: if the corrected value exceeds \f$ |\Sigma| \f$, then
37 \f$ \delta E \, (d\Sigma/dE) \f$ is approaching \f$ \Sigma \f$ - the pole
38 of the resummed (Pade) form, at
39 \f$ \delta E = \Sigma / (d\Sigma/dE) \f$ - where the
40 expression diverges; the correction is distrusted, and the uncorrected
41 \f$ \Sigma \f$ is returned.
42
43 @param Sigma Matrix element \f$ \langle a|\Sigma_1|b\rangle \f$.
44 @param dSigma Energy derivative, \f$ \langle a|d\Sigma_1/dE|b\rangle \f$.
45 @param dE Energy shift \f$ \delta E \f$ from the energy Sigma_1 was
46 evaluated at.
47 @return Corrected matrix element.
48*/
49double corrected_Sigma(double Sigma, double dSigma, double dE);
50
51/*!
52 @brief Resummed shift of a Sigma_2 integral to a new reference
53 energy E0 (Brillouin-Wigner denominators).
54 @details
55 \f$ S^k \to (S^k)^2 / (S^k - \delta E_0\, dS^k/dE_0) \f$, the same
56 resummation as @ref corrected_Sigma. Exact for a single energy denominator
57 (each term is \f$ N/(D + \delta E_0) \f$), so it holds up much better than
58 the linear expansion when \f$ \delta E_0 \f$ is a sizeable fraction of the
59 denominator.
60
61 Unlike @ref corrected_Sigma there is no guard against the correction
62 enhancing \f$ |S^k| \f$: for \f$ \Sigma_2 \f$ the shift legitimately goes
63 either way. The only guard is on crossing the pole of the resummed form,
64 at \f$ \delta E_0 = S^k / (dS^k/dE_0) \f$ (detected by the denominator
65 changing sign), beyond which the expansion is meaningless: the unshifted
66 \f$ S^k \f$ is returned there.
67
68 @param Sk Integral \f$ S^k \f$, evaluated at the reference E0.
69 @param dSk Derivative \f$ dS^k/dE_0 \f$, at the same reference.
70 @param dE0 Shift from the reference, \f$ E_0 - E_0^{\rm ref} \f$.
71 @return Shifted \f$ S^k \f$.
72*/
73double corrected_Sk(double Sk, double dSk, double dE0);
74
75//==============================================================================
76/*!
77 @brief Derivative (dSigma/dE) correction data for the one-body Sigma_1
78 matrix elements.
79 @details
80 Restores the state dependence of Sigma_1, which is otherwise evaluated at a
81 fixed energy for each kappa. Each one-body matrix element entering a CI
82 matrix element is corrected via @ref corrected_Sigma, with
83
84 \f[
85 \delta E = E_0 - E_\Sigma(\kappa) - \epsilon_{\rm spectator},
86 \f]
87
88 where \f$ E_0 \f$ is the reference total two-electron valence energy,
89 \f$ E_\Sigma(\kappa) \f$ is the energy Sigma_1 was evaluated at, and
90 \f$ \epsilon_{\rm spectator} \f$ is the orbital energy of the spectator
91 electron in the determinant.
92
93 Fill with @ref calculate_dSdE_correction; applied by Hab() (as a correction
94 on top of an h1 table that already includes Sigma_1).
95
96 @note The tables are agnostic to how Sigma_1 is calculated: to use the
97 Feynman (all-orders) Sigma, fill S1 and dS1 from the
98 CorrelationPotential (formSigma at two energies) instead of
99 MBPT::Sigma_vw / MBPT::dSigma_dE_vw.
100*/
102 //! One-body Sigma_1 matrix elements (uncorrected), <a|Sigma_1|b>
104 //! Energy derivative matrix elements, <a|dSigma_1/dE|b>
106 //! Energy Sigma_1 was evaluated at, for each kappa
107 std::map<int, double> e_sigma{};
108 //! Single-particle orbital energies, keyed by nk_index
109 std::map<DiracSpinor::Index, double> en{};
110 //! Reference total two-electron valence energy. 0.0 means "not set": it
111 //! belongs to a single (J, parity), and is found by @ref iterate_E0
112 double E0{0.0};
113
114 [[nodiscard]] bool empty() const { return dS1.empty(); }
115
116 /*!
117 @brief Correction to the one-body matrix element <a|h1|b>, given the
118 spectator orbital.
119 @details
120 Returns \f$ \Sigma_{\rm corrected} - \Sigma \f$, i.e., the amount to add
121 to an h1 matrix element that already includes (uncorrected) Sigma_1.
122 Returns zero for orbitals not in the tables.
123 */
124 [[nodiscard]] double delta_h1(DiracSpinor::Index a, DiracSpinor::Index b,
125 DiracSpinor::Index spectator) const;
126
127 /*!
128 @brief Reads or writes the correction tables to/from a binary file.
129 @details
130 Stores S1, dS1, e_sigma, and en. E0 is not stored: it belongs to a single
131 (J, parity) and is set at solve time (see @ref iterate_E0). On read, the
132 existing tables are replaced.
133
134 @note No settings are stored in the file: the filename identifies the
135 calculation (cf. @ref PsiJPi::read_write).
136
137 @return True on success; false if the file does not exist or cannot be
138 opened (read), or holds no tables.
139 */
140 bool read_write(const std::string &fname, IO::FRW::RoW rw);
141};
142
143/*!
144 @brief Builds the Sigma_1 derivative-correction tables; see
145 @ref Sigma1Correction.
146 @details
147 For each same-kappa pair in @p ci_basis, computes the (uncorrected) Sigma_1
148 matrix element and its energy derivative (central finite difference of
149 MBPT::Sigma_vw). Sigma_1 is evaluated at the energy of the first state of
150 each kappa in @p ci_basis - the same convention as calculate_h1_table(), so
151 the stored S1 matches the Sigma_1 included in the h1 table.
152
153 @param ci_basis Basis states for which table entries are needed.
154 @param s1_basis_core Core states used as internal lines for Sigma_1.
155 @param s1_basis_excited Excited states used as internal lines for Sigma_1.
156 @param qk Table of Coulomb \f$ Q^k \f$ integrals.
157 @return Filled Sigma1Correction tables (E0 left unset; see @ref iterate_E0).
158*/
159[[nodiscard]] Sigma1Correction
160calculate_dSdE_correction(const std::vector<DiracSpinor> &ci_basis,
161 const std::vector<DiracSpinor> &s1_basis_core,
162 const std::vector<DiracSpinor> &s1_basis_excited,
163 const Coulomb::QkTable &qk);
164
165/*!
166 @brief Builds the Sigma_1 derivative-correction tables directly from a
167 correlation potential that holds dSigma/dE matrices.
168 @details
169 Fills S1 from the actual Sigma of the correlation potential
170 (via CorrelationPotential::SigmaFv - so it matches the Sigma_1 in the h1
171 table exactly, whatever the method: Goldstone, Feynman, all-orders), and
172 dS1 from its stored dSigma/dE matrices (see the Correlations option
173 `derivative`). Much faster than the qk-table overload (matrix
174 applications only), and consistent with the all-orders Sigma.
175
176 The reference energies e_sigma are taken from the stored Sigma data (the
177 energy each Sigma matrix was formed at, first entry of each kappa).
178
179 @param ci_basis Basis states for which table entries are needed.
180 @param Sigma Correlation potential; must hold dSigma/dE matrices
181 (see CorrelationPotential::has_derivative()).
182 @return Filled Sigma1Correction tables (E0 left unset; see @ref iterate_E0).
183
184 @note The ladder part (Sigma_L) is included in S1 (via SigmaFv) but has no
185 energy derivative, so it is absent from dS1.
186*/
187[[nodiscard]] Sigma1Correction
188calculate_dSdE_correction(const std::vector<DiracSpinor> &ci_basis,
189 const MBPT::CorrelationPotential &Sigma);
190
191/*!
192 @brief Finds the reference energy E0 for the dSigma/dE correction, for a
193 single (J, parity); returns the CI Hamiltonian built with it.
194 @details
195 E0 is the lowest energy of this (J, parity), which is only known once we
196 have solved - so it is found self-consistently. If @p s1c has no E0 set
197 (i.e., 0.0), the iteration starts from the lowest zeroth-order configuration
198 energy. The first pass builds the
199 CI Hamiltonian at the current E0 and diagonalises it for the lowest level.
200 E0 enters only through the (small) dSigma/dE correction, so the state itself
201 hardly changes from pass to pass: later passes rebuild the Hamiltonian with
202 the updated E0 and take the new E0 as the expectation value of the new
203 Hamiltonian in the (unchanged) state - first-order perturbation theory in
204 the change to the Hamiltonian. Only the first pass is diagonalised.
205
206 @param psi Solved for the lowest level (updated in place).
207 @param s1c Correction tables. E0 belongs to a single (J, parity),
208 while these tables are shared between them, so a local
209 copy is made: @p s1c is left as it was.
210 @param h1 One-body matrix element table (includes Sigma_1).
211 @param qk Coulomb \f$ Q^k \f$ table.
212 @param Bk Pointer to Breit table; ignored if nullptr.
213 @param Sk Pointer to \f$ \Sigma_2 \f$ table; ignored if nullptr.
214 @param hk Average S^k/Q^k ratios; see @ref MBPT::average_hk.
215 @param dSk Pointer to the dS^k/dE0 table (Brillouin-Wigner
216 Sigma_2); ignored if nullptr. Sigma_2 is shifted to
217 the current E0 each pass, so both corrections move
218 together as E0 converges.
219 @param E0_sigma2 Reference E0 that @p Sk and @p dSk were tabulated at.
220 @param outstream Stream for the per-pass output.
221 @return CI Hamiltonian matrix, built with the converged E0.
222*/
224 PsiJPi *psi, const Sigma1Correction &s1c, const Coulomb::meTable<double> &h1,
225 const Coulomb::QkTable &qk, const Coulomb::WkTable *Bk = nullptr,
226 const Coulomb::LkTable *Sk = nullptr, const std::vector<double> &hk = {},
227 const Coulomb::LkTable *dSk = nullptr, double E0_sigma2 = 0.0,
228 std::ostream &outstream = std::cout);
229
230//==============================================================================
231/*!
232 @brief The integral tables required to construct the CI Hamiltonian matrix.
233 @details
234 Everything needed to construct the CI Hamiltonian for any (J, parity), as it
235 was constructed for the CI solutions: the single-particle basis, the one-body
236 matrix elements (which may include \f$ \Sigma_1 \f$), and the two-body
237 Coulomb, Breit and \f$ \Sigma_2 \f$ tables.
238
239 Filled by @ref configuration_interaction and stored in the Wavefunction (see
240 Wavefunction::CI_integrals), so that later calculations can construct CI
241 Hamiltonians - e.g., for the mixed-states equation, @ref solve_mixed_state -
242 without recalculating any integrals.
243
244 @note The Breit and \f$ \Sigma_2 \f$ tables are empty if those corrections
245 were not included; @ref construct_Hci then skips them.
246
247 @note These tables are large (the Coulomb table especially): keeping them for
248 the entire run costs memory.
249*/
250struct Integrals {
251 //! Single-particle basis used for the CI expansion
252 std::vector<DiracSpinor> ci_basis{};
253 //! True if ci_basis are Brueckner (spectrum) states, false if HF basis
254 bool brueckner{false};
255 //! One-body matrix elements, <a|h1|b>; may include Sigma_1
257 //! Two-body Coulomb integrals, Q^k
259 //! Two-body Breit integrals, B^k; empty if not included
261 //! Two-body Sigma_2 integrals, S^k; empty if not included
263 //! Average S^k/Q^k ratios, indexed by k; empty if Sigma_2 is not being
264 //! extrapolated beyond the cis2 basis. Diagrams with no stored S^k then
265 //! use S^k = hk[k] * Q^k. See MBPT::average_hk
266 std::vector<double> hk{};
267 //! Energy derivatives dS^k/dE0 of the Sigma_2 integrals; empty unless the
268 //! Brillouin-Wigner (E0-dependent) Sigma_2 correction is included.
269 //! See CI::corrected_Sk
271 //! Reference E0 that Sk and dSk were tabulated at (Brillouin-Wigner)
272 double E0_sigma2{0.0};
273 //! Derivative (dSigma/dE) correction for Sigma_1; empty if not included
275
276 //! False if the tables were never calculated (e.g., CI was run 'read_only')
277 [[nodiscard]] bool availableQ() const {
278 return !ci_basis.empty() && !h1.empty();
279 }
280};
281
282//==============================================================================
283/*!
284 @brief The result of a CI calculation: the solutions, and the integrals used
285 to construct the CI Hamiltonian.
286 @details
287 Returned by @ref configuration_interaction, and stored in the Wavefunction
288 (see Wavefunction::CIwfs and Wavefunction::CI_integrals). The integrals are
289 kept so that CI Hamiltonians for other (J, parity) may be constructed later
290 without recalculating them - e.g., for the mixed-states equation,
291 @ref solve_mixed_state. See @ref Integrals.
292*/
293struct Solutions {
294 //! One entry per {J, parity} requested
295 std::vector<PsiJPi> levels{};
296 //! Integral tables used to construct the CI Hamiltonians
298};
299
300/*!
301 @brief Antisymmetrised two-body Coulomb matrix element in the coupled CSF
302 basis.
303 @details
304 Evaluates the angular-reduced, antisymmetrised Coulomb interaction between
305 two two-electron CSFs \f$ |vw; J\rangle \f$ and \f$ |xy; J\rangle \f$:
306
307 \f[
308 \langle vw; J \| g \| xy; J \rangle
309 = \eta_{vw}\eta_{xy}
310 \sum_k (-1)^{j_v+j_x+k+J}
311 \begin{Bmatrix} j_v & j_w & J \\ j_y & j_x & k \end{Bmatrix}
312 Q^k_{vwxy} + \text{exchange},
313 \f]
314
315 where \f$ \eta_{ab} = 1/\sqrt{2} \f$ if \f$ a = b \f$ (identical-particle
316 normalisation) and 1 otherwise, and \f$ Q^k \f$ are the Coulomb integrals stored in @p qk.
317
318 @param qk Table of Coulomb \f$ Q^k \f$ integrals.
319 @param v,w Indices of the bra single-particle states.
320 @param x,y Indices of the ket single-particle states.
321 @param twoJ Twice the total angular momentum 2J of the coupled pair.
322 @return Antisymmetrised, angular-reduced two-body Coulomb matrix element.
323*/
326 DiracSpinor::Index y, int twoJ);
327
328/*!
329 @brief Two-body Sigma_2 (MBPT) correction to CSF2_Coulomb().
330 @details
331 Evaluates the same angular reduction as CSF2_Coulomb(), but using the
332 two-body \f$ \Sigma_2 \f$ integrals \f$ S^k \f$ stored in @p Sk in place of
333 the Coulomb \f$ Q^k \f$ integrals. Adds the second-order MBPT correction to
334 the two-electron interaction.
335
336 @param Sk Table of two-body \f$ \Sigma_2 \f$ (\f$ L^k \f$) integrals.
337 @param v,w Indices of the bra single-particle states.
338 @param x,y Indices of the ket single-particle states.
339 @param twoJ Twice the total angular momentum 2J of the coupled pair.
340 @return Antisymmetrised two-body \f$ \Sigma_2 \f$ matrix element.
341*/
344 DiracSpinor::Index y, int twoJ,
345 const Coulomb::QkTable *qk = nullptr,
346 const std::vector<double> &hk = {},
347 const Coulomb::LkTable *dSk = nullptr, double dE0 = 0.0);
348
349/*!
350 @brief Antisymmetrised two-body Breit matrix element in the coupled CSF
351 basis.
352 @details
353 Evaluates the same angular reduction as CSF2_Coulomb(), but using the Breit
354 \f$ B^k \f$ integrals stored in @p Bk.
355
356 @param Bk Table of Breit \f$ W^k \f$ integrals.
357 @param v,w Indices of the bra single-particle states.
358 @param x,y Indices of the ket single-particle states.
359 @param twoJ Twice the total angular momentum 2J of the coupled pair.
360 @return Antisymmetrised two-body Breit matrix element.
361*/
364 DiracSpinor::Index y, int twoJ);
365
366/*!
367 @brief CI Hamiltonian matrix element between two two-electron CSFs.
368 @details
369 Computes \f$ H_{AB} = \langle A | \hat{H} | B \rangle \f$ using the
370 Slater-Condon rules, including one-body terms from @p h1 (which may already
371 incorporate \f$ \Sigma_1 \f$ corrections) and the two-body Coulomb
372 interaction via CSF2_Coulomb().
373
374 Does NOT include \f$ \Sigma_2 \f$ or Breit corrections; add those via
375 Sigma2_AB() and Breit_AB() respectively.
376
377 @param A,B The two CSFs.
378 @param twoJ Twice the total angular momentum 2J.
379 @param h1 Table of one-body matrix elements \f$ \langle a | h_1 | b \rangle \f$.
380 @param qk Table of Coulomb \f$ Q^k \f$ integrals.
381 @param s1c Optional derivative (dSigma/dE) correction to Sigma_1; applied
382 to each one-body matrix element (with the spectator orbital
383 energy) if given. See @ref Sigma1Correction.
384 @return CI Hamiltonian matrix element \f$ H_{AB} \f$.
385*/
386double Hab(const CI::CSF2 &A, const CI::CSF2 &B, int twoJ,
387 const Coulomb::meTable<double> &h1, const Coulomb::QkTable &qk,
388 const Sigma1Correction *s1c = nullptr);
389
390/*!
391 @brief Two-body Sigma_2 correction to Hab().
392 @details
393 Evaluates the MBPT \f$ \Sigma_2 \f$ contribution to the CI matrix element
394 using CSF2_Sigma2(). Add to Hab() to form the full CI+MBPT Hamiltonian
395 matrix element.
396
397 @param A,B The two CSFs.
398 @param twoJ Twice the total angular momentum 2J.
399 @param Sk Table of \f$ \Sigma_2 \f$ (\f$ L^k \f$) integrals.
400 @return \f$ \Sigma_2 \f$ correction to \f$ H_{AB} \f$.
401*/
402double Sigma2_AB(const CI::CSF2 &A, const CI::CSF2 &B, int twoJ,
403 const Coulomb::LkTable &Sk,
404 const Coulomb::QkTable *qk = nullptr,
405 const std::vector<double> &hk = {},
406 const Coulomb::LkTable *dSk = nullptr, double dE0 = 0.0);
407
408/*!
409 @brief Breit correction to Hab().
410 @details
411 Evaluates the two-body Breit contribution to the CI matrix element using
412 CSF2_Breit(). Add to Hab() to include the Breit interaction.
413
414 @param A,B The two CSFs.
415 @param twoJ Twice the total angular momentum 2J.
416 @param Bk Table of Breit \f$ W^k \f$ integrals.
417 @return Breit correction to \f$ H_{AB} \f$.
418*/
419double Breit_AB(const CI::CSF2 &A, const CI::CSF2 &B, int twoJ,
420 const Coulomb::WkTable &Bk);
421
422/*!
423 @brief Builds the one-body Hamiltonian matrix element table for the CI basis.
424 @details
425 Constructs a lookup table of single-particle matrix elements
426 \f$ \langle a | h_1 | b \rangle \f$ for all pairs \f$ a, b \f$ in
427 @p ci_basis. The diagonal elements are the HF single-particle energies.
428
429 If @p include_Sigma1 is true, the one-body MBPT \f$ \Sigma_1 \f$ correction
430 is computed from the Coulomb integrals in @p qk using @p s1_basis_core and
431 @p s1_basis_excited as the internal lines of the MBPT diagrams and added to
432 the diagonal.
433
434 @param ci_basis Basis states for which table entries are needed.
435 @param s1_basis_core Core states used as internal lines for \f$ \Sigma_1 \f$.
436 @param s1_basis_excited Excited states used as internal lines for \f$ \Sigma_1 \f$.
437 @param qk Table of Coulomb \f$ Q^k \f$ integrals.
438 @param include_Sigma1 If true, add one-body MBPT \f$ \Sigma_1 \f$ corrections.
439 @return Table of \f$ \langle a | h_1 | b \rangle \f$ matrix elements.
440
441 @warning Assumes @p ci_basis states are Hartree-Fock eigenstates, so
442 off-diagonal HF terms vanish.
443*/
444[[nodiscard]] Coulomb::meTable<double>
445calculate_h1_table(const std::vector<DiracSpinor> &ci_basis,
446 const std::vector<DiracSpinor> &s1_basis_core,
447 const std::vector<DiracSpinor> &s1_basis_excited,
448 const Coulomb::QkTable &qk, bool include_Sigma1);
449
450/*!
451 @brief Builds the one-body Hamiltonian table using a precomputed
452 CorrelationPotential.
453 @details
454 Overload of calculate_h1_table() that uses a CorrelationPotential object
455 (i.e., a precomputed \f$ \Sigma_1 \f$ operator) instead of computing MBPT
456 diagrams on the fly. Preferred when a CorrelationPotential is available, as
457 it is generally faster and more complete.
458
459 @param ci_basis Basis states for which table entries are needed.
460 @param Sigma Precomputed one-body correlation potential \f$ \Sigma_1 \f$.
461 @param include_Sigma1 If true, include \f$ \Sigma_1 \f$ corrections from @p Sigma.
462 @return Table of \f$ \langle a | h_1 | b \rangle \f$ matrix elements.
463*/
464[[nodiscard]] Coulomb::meTable<double>
465calculate_h1_table(const std::vector<DiracSpinor> &ci_basis,
466 const MBPT::CorrelationPotential &Sigma,
467 bool include_Sigma1);
468
469/*!
470 @brief Builds or loads the two-body Breit integral table.
471 @details
472 Computes Breit \f$ W^k \f$ integrals for all pairs in @p ci_basis using the
473 Breit operator @p pBr. Results are cached to/from @p bk_filename.
474
475 If @p pBr is nullptr or @p no_new_integralsQ is true, no new integrals are
476 computed; only cached values are loaded.
477
478 @param bk_filename Filename for caching the \f$ W^k \f$ table.
479 @param pBr Pointer to Breit operator; if nullptr, returns empty table.
480 @param ci_basis Basis for which Breit integrals are needed.
481 @param max_k Maximum multipolarity k to include.
482 @param no_new_integralsQ If true, skip computing any new integrals.
483 @return Table of Breit \f$ W^k \f$ integrals.
484*/
485[[nodiscard]] Coulomb::WkTable
486calculate_Bk(const std::string &bk_filename, const HF::Breit *const pBr,
487 const std::vector<DiracSpinor> &ci_basis, int max_k,
488 bool no_new_integralsQ = false);
489
490/*!
491 @brief Returns the subset of @p basis matching @p include_str, excluding
492 states in @p exclude_str.
493 @details
494 Filters @p basis to retain only states described by the ampsci basis-string
495 notation (e.g., "20spdf") that are not part of the frozen core.
496
497 @param basis Full single-particle basis to filter.
498 @param include_str Basis-string specifying which states to keep;
499 if empty, all states in @p basis are kept (subject
500 to the frozen-core exclusion).
501 @param exclude_str Basis-string specifying core states to exclude.
502 @return Filtered basis vector. Negative-energy states (if present) with
503 kappa in @p include_str are kept (the n limit is not applied to them).
504*/
505[[nodiscard]] std::vector<DiracSpinor>
506basis_subset(const std::vector<DiracSpinor> &basis,
507 const std::string &include_str,
508 const std::string &exclude_str = "");
509
510/*!
511 @brief Reduced matrix element between two CI states (low-level overload).
512 @details
513 Evaluates the reduced matrix element of a rank-@p K_rank tensor operator
514 between two CI states:
515
516 \f[
517 \redmatel{A}{T^K}{B}
518 = \sum_{ij} c_i^A \, c_j^B \, \redmatel{\text{CSF}_i}{T^K}{\text{CSF}_j},
519 \f]
520
521 where the single-particle reduced matrix elements are looked up from @p h.
522
523 @param cA,cB CI expansion coefficient vectors for states A and B.
524 @param CSFAs,CSFBs CSF bases for states A and B respectively.
525 @param twoJA,twoJB Twice the total angular momentum of states A and B.
526 @param h Lookup table of single-particle reduced matrix elements.
527 @param K_rank Rank of the tensor operator.
528 @param Parity Parity of the operator (+1 or -1).
529 @return Reduced matrix element \f$ \redmatel{A}{T^K}{B} \f$.
530*/
532 const std::vector<CI::CSF2> &CSFAs, int twoJA,
534 const std::vector<CI::CSF2> &CSFBs, int twoJB,
535 const Coulomb::meTable<double> &h, int K_rank, int Parity);
536
537/*!
538 @brief Reduced matrix element between two CI states (PsiJPi overload).
539 @details
540 Convenience wrapper around the low-level ReducedME() overload. Extracts
541 expansion coefficients and CSF lists from @p As and @p Bs for the requested
542 solution indices @p iA and @p iB.
543
544 @param As,Bs CI solution containers for the two states.
545 @param iA,iB Solution indices within @p As and @p Bs.
546 @param h Lookup table of single-particle reduced matrix elements.
547 @param K_rank Rank of the tensor operator.
548 @param Parity Parity of the operator (+1 or -1).
549 @return Reduced matrix element \f$ \redmatel{A}{T^K}{B} \f$.
550*/
551inline double ReducedME(const PsiJPi &As, std::size_t iA, const PsiJPi &Bs,
552 std::size_t iB, const Coulomb::meTable<double> &h,
553 int K_rank, int Parity) {
554 return ReducedME(As.coefs(iA), As.CSFs(), As.twoJ(), Bs.coefs(iB), Bs.CSFs(),
555 Bs.twoJ(), h, K_rank, Parity);
556}
557
558/*!
559 @brief Reduced matrix element between two two-electron CSFs.
560 @details
561 Evaluates \f$ \redmatel{X; J_X}{T^K}{V; J_V} \f$ for a rank-@p K_rank
562 one-body tensor operator using the standard 6j angular reduction, accounting
563 for identical-particle normalisation factors.
564
565 @warning This function may not handle all cases correctly; results should be
566 verified for non-trivial configurations.
567*/
568double RME_CSF2(const CI::CSF2 &X, int twoJX, const CI::CSF2 &V, int twoJV,
569 const Coulomb::meTable<double> &h, int K_rank);
570
571/*!
572 @brief Leading non-relativistic configuration of a CI state.
573 @details
574 Sums |c|^2 over the relativistic CSFs belonging to each non-relativistic
575 configuration, and returns the configuration with the largest total weight.
576
577 @param coefs CI expansion coefficients (one per CSF).
578 @param csfs The CSF basis (matching @p coefs).
579 @return Pair {configuration label (non-rel notation), total |c|^2 weight}.
580*/
581std::pair<std::string, double>
583 const std::vector<CSF2> &csfs);
584
585/*!
586 @brief Determines the best-fit (S, L) term for a two-electron state by
587 matching the g-factor.
588 @details
589 Iterates over all allowed (S, L) combinations for given orbital angular
590 momenta @p l1, @p l2 and total @p twoJ /2, and returns the pair whose
591 Lande g-factor is closest to @p gJ_target.
592
593 @param l1,l2 Orbital angular momenta of the two electrons.
594 @param twoJ Twice the total angular momentum 2J.
595 @param gJ_target Target g-factor to match.
596 @return Best-fit {2S, L} pair.
597*/
598std::pair<int, int> Term_S_L(int l1, int l2, int twoJ, double gJ_target);
599
600/*!
601 @brief Determines the (S, L) term for a two-electron state from the
602 expectation values of L^2 and S^2.
603 @details
604 Returns the (S, L) pair, subject to the triangle condition with J, that
605 minimises the combined distance |L(L+1) - @p L2| + |S(S+1) - @p S2|.
606 For a mixed state, this is the nearest (dominant) term; the purity is
607 indicated by @p L2, @p S2 themselves. See @ref expectation_L2S2.
608
609 @param L2 Expectation value of L^2.
610 @param S2 Expectation value of S^2.
611 @param twoJ Twice the total angular momentum 2J.
612 @return Best-fit {S, L} pair.
613*/
614std::pair<int, int> Term_S_L_from_expectation(double L2, double S2, int twoJ);
615
616//! Returns spectroscopic term symbol string, e.g. "3P_1"
617std::string Term_Symbol(int two_J, int L, int two_S, int parity);
618//! Returns term symbol without the J subscript, e.g. "3P"
619std::string Term_Symbol(int L, int two_S, int parity);
620
621/*!
622 @brief Constructs the full CI Hamiltonian matrix in the CSF basis.
623 @details
624 Builds the symmetric matrix \f$ H_{AB} \f$ for all CSF pairs in @p psi,
625 calling Hab() for each element and optionally adding Breit and
626 \f$ \Sigma_2 \f$ corrections.
627
628 @param psi CI solution container holding the CSF basis and J/parity.
629 @param h1 One-body matrix element table (may include \f$ \Sigma_1 \f$).
630 @param qk Coulomb \f$ Q^k \f$ integral table.
631 @param Bk Pointer to Breit \f$ W^k \f$ table; ignored if nullptr.
632 @param Sk Pointer to \f$ \Sigma_2 \f$ \f$ L^k \f$ table; ignored if nullptr.
633 @param s1c Pointer to derivative (dSigma/dE) correction for Sigma_1;
634 ignored if nullptr. See @ref Sigma1Correction.
635 @param hk Average S^k/Q^k ratios; if non-empty, diagrams with no stored
636 S^k use S^k = hk[k]*Q^k. See @ref MBPT::average_hk.
637 @param dSk Pointer to the dS^k/dE0 table; ignored if nullptr. If given,
638 each stored S^k is shifted to the target E0. See
639 @ref CI::corrected_Sk.
640 @param dE0 Shift of the target E0 from the one Sk was tabulated at.
641 @return Full CI Hamiltonian matrix in the CSF basis.
642*/
644construct_Hci(const PsiJPi &psi, const Coulomb::meTable<double> &h1,
645 const Coulomb::QkTable &qk, const Coulomb::WkTable *Bk = nullptr,
646 const Coulomb::LkTable *Sk = nullptr,
647 const Sigma1Correction *s1c = nullptr,
648 const std::vector<double> &hk = {},
649 const Coulomb::LkTable *dSk = nullptr, double dE0 = 0.0);
650
651/*!
652 @brief Constructs the CI Hamiltonian matrix from a set of integral tables.
653 @details
654 Overload of construct_Hci() taking the tables as @ref Integrals; the Breit
655 and \f$ \Sigma_2 \f$ corrections are included if those tables are non-empty.
656
657 If the iterative (dSigma/dE) correction is included, the reference energy
658 E0 (which also sets the Sigma_2 BW shift, if present) belongs to this
659 J/Pi: the lowest solved energy of @p psi is used if it has
660 solutions; otherwise the stored fallback is used, which is the
661 ground-state energy of the CI run. Blocks never solved directly - e.g.,
662 the target J/Pi of a mixed state - thus have their corrections evaluated
663 at the run's ground-state energy; the difference is higher order.
664
665 @param psi CI solution container holding the CSF basis and J/parity.
666 @param ints Integral tables, e.g., from Wavefunction::CI_integrals().
667 @return Full CI Hamiltonian matrix in the CSF basis.
668*/
669LinAlg::Matrix<double> construct_Hci(const PsiJPi &psi, const Integrals &ints);
670
671} // namespace CI
Two-electron configuration state function (CSF).
Definition CSF.hpp:31
Container for CI solutions in a single J/Pi.
Definition CSF.hpp:248
LinAlg::View< const double > coefs(std::size_t i) const
CI expansion coefficients for the ith solution (one per CSF)
Definition CSF.cpp:334
const std::vector< CSF2 > & CSFs() const
Full list of CSFs spanning this J/Pi.
Definition CSF.cpp:322
int twoJ() const
Twice the total angular momentum 2J for this J/Pi.
Definition CSF.cpp:349
Base class template to store Coulomb integrals, and similar. 3 specific cases (by template instantiat...
Definition QkTable.hpp:118
Look-up table for matrix elements. Note: does not assume any symmetry: (a,b) is stored independantly ...
Definition meTable.hpp:17
bool empty() const
Returns true in the meTable is empty.
Definition meTable.hpp:63
uint16_t Index
Integer type for the compressed (n,kappa) index.
Definition DiracSpinor.hpp:73
Breit potentials for one- (Hartree-Fock Breit) and two-body Breit integrals.
Definition Breit.hpp:88
Row-major dense matrix with arithmetic and linear algebra support.
Definition Matrix.hpp:208
Non-owning strided view onto a 1D segment of an array.
Definition Matrix.hpp:69
Correlation potential, Sigma, for valence states.
Definition CorrelationPotential.hpp:108
Functions and classes for Configuration Interaction calculations.
Definition CI_Integrals.cpp:22
double CSF2_Breit(const Coulomb::WkTable &Bk, DiracSpinor::Index v, DiracSpinor::Index w, DiracSpinor::Index x, DiracSpinor::Index y, int twoJ)
Antisymmetrised two-body Breit matrix element in the coupled CSF basis.
Definition CI_Integrals.cpp:167
std::vector< DiracSpinor > basis_subset(const std::vector< DiracSpinor > &basis, const std::string &subset_string, const std::string &frozen_core_string)
Returns the subset of basis matching include_str, excluding states in exclude_str.
Definition CI_Integrals.cpp:685
Coulomb::meTable< double > calculate_h1_table(const std::vector< DiracSpinor > &ci_basis, const std::vector< DiracSpinor > &s1_basis_core, const std::vector< DiracSpinor > &s1_basis_excited, const Coulomb::QkTable &qk, bool include_Sigma1)
Builds the one-body Hamiltonian matrix element table for the CI basis.
Definition CI_Integrals.cpp:559
double corrected_Sigma(double Sigma, double dSigma, double dE)
Resummed derivative (dSigma/dE) correction to a Sigma_1 matrix element (Kozlov formula).
Definition CI_Integrals.cpp:233
double Breit_AB(const CI::CSF2 &A, const CI::CSF2 &B, int twoJ, const Coulomb::WkTable &Bk)
Breit correction to Hab().
Definition CI_Integrals.cpp:225
double RME_CSF2(const CI::CSF2 &X, int twoJX, const CI::CSF2 &V, int twoJV, const Coulomb::meTable< double > &h, int K_rank)
Reduced matrix element between two two-electron CSFs.
Definition CI_Integrals.cpp:766
std::string Term_Symbol(int two_J, int L, int two_S, int parity)
Returns spectroscopic term symbol string, e.g. "3P_1".
Definition CI_Integrals.cpp:900
double Hab(const CI::CSF2 &X, const CI::CSF2 &V, int twoJ, const Coulomb::meTable< double > &h1, const Coulomb::QkTable &qk, const Sigma1Correction *s1c)
CI Hamiltonian matrix element between two two-electron CSFs.
Definition CI_Integrals.cpp:521
std::pair< std::string, double > leading_config(const LinAlg::View< const double > &coefs, const std::vector< CSF2 > &csfs)
Leading non-relativistic configuration of a CI state.
Definition CI_Integrals.cpp:815
std::pair< int, int > Term_S_L_from_expectation(double L2, double S2, int twoJ)
Determines the (S, L) term for a two-electron state from the expectation values of L^2 and S^2.
Definition CI_Integrals.cpp:875
std::pair< int, int > Term_S_L(int l1, int l2, int twoJ, double gJ_target)
Determines the best-fit (S, L) term for a two-electron state by matching the g-factor.
Definition CI_Integrals.cpp:834
double ReducedME(const LinAlg::View< const double > &cA, const std::vector< CI::CSF2 > &CSFAs, int twoJA, const LinAlg::View< const double > &cB, const std::vector< CI::CSF2 > &CSFBs, int twoJB, const Coulomb::meTable< double > &h, int K_rank, int Parity)
Reduced matrix element between two CI states (low-level overload).
Definition CI_Integrals.cpp:727
std::vector< PsiJPi > levels
One entry per {J, parity} requested.
Definition CI_Integrals.hpp:295
double corrected_Sk(double Sk, double dSk, double dE0)
Resummed shift of a Sigma_2 integral to a new reference energy E0 (Brillouin-Wigner denominators).
Definition CI_Integrals.cpp:249
double Sigma2_AB(const CI::CSF2 &A, const CI::CSF2 &B, int twoJ, const Coulomb::LkTable &Sk, const Coulomb::QkTable *qk, const std::vector< double > &hk, const Coulomb::LkTable *dSk, double dE0)
Two-body Sigma_2 correction to Hab().
Definition CI_Integrals.cpp:215
double CSF2_Sigma2(const Coulomb::LkTable &Sk, DiracSpinor::Index v, DiracSpinor::Index w, DiracSpinor::Index x, DiracSpinor::Index y, int twoJ, const Coulomb::QkTable *qk, const std::vector< double > &hk, const Coulomb::LkTable *dSk, double dE0)
Two-body Sigma_2 (MBPT) correction to CSF2_Coulomb().
Definition CI_Integrals.cpp:86
Coulomb::WkTable calculate_Bk(const std::string &bk_filename, const HF::Breit *const pBr, const std::vector< DiracSpinor > &ci_basis, int max_k, bool no_new_integrals)
Builds or loads the two-body Breit integral table.
Definition CI_Integrals.cpp:641
Sigma1Correction calculate_dSdE_correction(const std::vector< DiracSpinor > &ci_basis, const std::vector< DiracSpinor > &s1_basis_core, const std::vector< DiracSpinor > &s1_basis_excited, const Coulomb::QkTable &qk)
Builds the Sigma_1 derivative-correction tables; see Sigma1Correction.
Definition CI_Integrals.cpp:332
LinAlg::Matrix< double > construct_Hci(const PsiJPi &psi, const Coulomb::meTable< double > &h1, const Coulomb::QkTable &qk, const Coulomb::WkTable *Bk, const Coulomb::LkTable *Sk, const Sigma1Correction *s1c, const std::vector< double > &hk, const Coulomb::LkTable *dSk, double dE0)
Constructs the full CI Hamiltonian matrix in the CSF basis.
Definition CI_Integrals.cpp:915
Integrals integrals
Integral tables used to construct the CI Hamiltonians.
Definition CI_Integrals.hpp:297
double CSF2_Coulomb(const Coulomb::QkTable &qk, DiracSpinor::Index v, DiracSpinor::Index w, DiracSpinor::Index x, DiracSpinor::Index y, int twoJ)
Antisymmetrised two-body Coulomb matrix element in the coupled CSF basis.
Definition CI_Integrals.cpp:27
LinAlg::Matrix< double > iterate_E0(PsiJPi *psi, const Sigma1Correction &s1c, const Coulomb::meTable< double > &h1, const Coulomb::QkTable &qk, const Coulomb::WkTable *Bk, const Coulomb::LkTable *Sk, const std::vector< double > &hk, const Coulomb::LkTable *dSk, double E0_sigma2, std::ostream &outstream)
Finds the reference energy E0 for the dSigma/dE correction, for a single (J, parity); returns the CI ...
Definition CI_Integrals.cpp:434
The result of a CI calculation: the solutions, and the integrals used to construct the CI Hamiltonian...
Definition CI_Integrals.hpp:293
Functions and classes for Hartree-Fock.
Definition CI_Integrals.hpp:16
Many-body perturbation theory.
Definition MatrixElements.hpp:12
The integral tables required to construct the CI Hamiltonian matrix.
Definition CI_Integrals.hpp:250
Coulomb::LkTable Sk
Two-body Sigma_2 integrals, S^k; empty if not included.
Definition CI_Integrals.hpp:262
Sigma1Correction s1_corr
Derivative (dSigma/dE) correction for Sigma_1; empty if not included.
Definition CI_Integrals.hpp:274
std::vector< DiracSpinor > ci_basis
Single-particle basis used for the CI expansion.
Definition CI_Integrals.hpp:252
std::vector< double > hk
Average S^k/Q^k ratios, indexed by k; empty if Sigma_2 is not being extrapolated beyond the cis2 basi...
Definition CI_Integrals.hpp:266
bool availableQ() const
False if the tables were never calculated (e.g., CI was run 'read_only')
Definition CI_Integrals.hpp:277
Coulomb::QkTable qk
Two-body Coulomb integrals, Q^k.
Definition CI_Integrals.hpp:258
bool brueckner
True if ci_basis are Brueckner (spectrum) states, false if HF basis.
Definition CI_Integrals.hpp:254
Coulomb::LkTable dSk
Energy derivatives dS^k/dE0 of the Sigma_2 integrals; empty unless the Brillouin-Wigner (E0-dependent...
Definition CI_Integrals.hpp:270
double E0_sigma2
Reference E0 that Sk and dSk were tabulated at (Brillouin-Wigner)
Definition CI_Integrals.hpp:272
Coulomb::meTable< double > h1
One-body matrix elements, <a|h1|b>; may include Sigma_1.
Definition CI_Integrals.hpp:256
Coulomb::WkTable Bk
Two-body Breit integrals, B^k; empty if not included.
Definition CI_Integrals.hpp:260
Derivative (dSigma/dE) correction data for the one-body Sigma_1 matrix elements.
Definition CI_Integrals.hpp:101
Coulomb::meTable< double > S1
One-body Sigma_1 matrix elements (uncorrected), <a|Sigma_1|b>
Definition CI_Integrals.hpp:103
double delta_h1(DiracSpinor::Index a, DiracSpinor::Index b, DiracSpinor::Index spectator) const
Correction to the one-body matrix element <a|h1|b>, given the spectator orbital.
Definition CI_Integrals.cpp:266
double E0
Reference total two-electron valence energy. 0.0 means "not set": it belongs to a single (J,...
Definition CI_Integrals.hpp:112
Coulomb::meTable< double > dS1
Energy derivative matrix elements, <a|dSigma_1/dE|b>
Definition CI_Integrals.hpp:105
bool read_write(const std::string &fname, IO::FRW::RoW rw)
Reads or writes the correction tables to/from a binary file.
Definition CI_Integrals.cpp:283
std::map< int, double > e_sigma
Energy Sigma_1 was evaluated at, for each kappa.
Definition CI_Integrals.hpp:107
std::map< DiracSpinor::Index, double > en
Single-particle orbital energies, keyed by nk_index.
Definition CI_Integrals.hpp:109