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 \f$ \Sigma_2 \f$ 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 //! One-body matrix elements, <a|h1|b>; may include Sigma_1
255 //! Two-body Coulomb integrals, Q^k
257 //! Two-body Breit integrals, B^k; empty if not included
259 //! Two-body Sigma_2 integrals, S^k; empty if not included
261 //! Average S^k/Q^k ratios, indexed by k; empty if Sigma_2 is not being
262 //! extrapolated beyond the cis2 basis. Diagrams with no stored S^k then
263 //! use S^k = hk[k] * Q^k. See MBPT::average_hk
264 std::vector<double> hk{};
265 //! Energy derivatives dS^k/dE0 of the Sigma_2 integrals; empty unless the
266 //! Brillouin-Wigner (E0-dependent) Sigma_2 correction is included.
267 //! See CI::corrected_Sk
269 //! Reference E0 that Sk and dSk were tabulated at (Brillouin-Wigner)
270 double E0_sigma2{0.0};
271 //! Derivative (dSigma/dE) correction for Sigma_1; empty if not included
273
274 //! False if the tables were never calculated (e.g., CI was run 'read_only')
275 [[nodiscard]] bool availableQ() const {
276 return !ci_basis.empty() && !h1.empty();
277 }
278};
279
280//==============================================================================
281/*!
282 @brief The result of a CI calculation: the solutions, and the integrals used
283 to construct the CI Hamiltonian.
284 @details
285 Returned by @ref configuration_interaction, and stored in the Wavefunction
286 (see Wavefunction::CIwfs and Wavefunction::CI_integrals). The integrals are
287 kept so that CI Hamiltonians for other (J, parity) may be constructed later
288 without recalculating them - e.g., for the mixed-states equation,
289 @ref solve_mixed_state. See @ref Integrals.
290*/
291struct Solutions {
292 //! One entry per {J, parity} requested
293 std::vector<PsiJPi> levels{};
294 //! Integral tables used to construct the CI Hamiltonians
296};
297
298/*!
299 @brief Antisymmetrised two-body Coulomb matrix element in the coupled CSF
300 basis.
301 @details
302 Evaluates the angular-reduced, antisymmetrised Coulomb interaction between
303 two two-electron CSFs \f$ |vw; J\rangle \f$ and \f$ |xy; J\rangle \f$:
304
305 \f[
306 \langle vw; J \| g \| xy; J \rangle
307 = \eta_{vw}\eta_{xy}
308 \sum_k (-1)^{j_v+j_x+k+J}
309 \begin{Bmatrix} j_v & j_w & J \\ j_y & j_x & k \end{Bmatrix}
310 Q^k_{vwxy} + \text{exchange},
311 \f]
312
313 where \f$ \eta_{ab} = 1/\sqrt{2} \f$ if \f$ a = b \f$ (identical-particle
314 normalisation) and 1 otherwise, and \f$ Q^k \f$ are the Coulomb integrals stored in @p qk.
315
316 @param qk Table of Coulomb \f$ Q^k \f$ integrals.
317 @param v,w Indices of the bra single-particle states.
318 @param x,y Indices of the ket single-particle states.
319 @param twoJ Twice the total angular momentum 2J of the coupled pair.
320 @return Antisymmetrised, angular-reduced two-body Coulomb matrix element.
321*/
324 DiracSpinor::Index y, int twoJ);
325
326/*!
327 @brief Two-body \f$ \Sigma_2 \f$ (MBPT) correction to CSF2_Coulomb().
328 @details
329 Evaluates the same angular reduction as CSF2_Coulomb(), but using the
330 two-body \f$ \Sigma_2 \f$ integrals \f$ S^k \f$ stored in @p Sk in place of
331 the Coulomb \f$ Q^k \f$ integrals. Adds the second-order MBPT correction to
332 the two-electron interaction.
333
334 @param Sk Table of two-body \f$ \Sigma_2 \f$ (\f$ L^k \f$) integrals.
335 @param v,w Indices of the bra single-particle states.
336 @param x,y Indices of the ket single-particle states.
337 @param twoJ Twice the total angular momentum 2J of the coupled pair.
338 @return Antisymmetrised two-body \f$ \Sigma_2 \f$ matrix element.
339*/
342 DiracSpinor::Index y, int twoJ,
343 const Coulomb::QkTable *qk = nullptr,
344 const std::vector<double> &hk = {},
345 const Coulomb::LkTable *dSk = nullptr, double dE0 = 0.0);
346
347/*!
348 @brief Antisymmetrised two-body Breit matrix element in the coupled CSF
349 basis.
350 @details
351 Evaluates the same angular reduction as CSF2_Coulomb(), but using the Breit
352 \f$ B^k \f$ integrals stored in @p Bk.
353
354 @param Bk Table of Breit \f$ W^k \f$ integrals.
355 @param v,w Indices of the bra single-particle states.
356 @param x,y Indices of the ket single-particle states.
357 @param twoJ Twice the total angular momentum 2J of the coupled pair.
358 @return Antisymmetrised two-body Breit matrix element.
359*/
362 DiracSpinor::Index y, int twoJ);
363
364/*!
365 @brief CI Hamiltonian matrix element between two two-electron CSFs.
366 @details
367 Computes \f$ H_{AB} = \langle A | \hat{H} | B \rangle \f$ using the
368 Slater-Condon rules, including one-body terms from @p h1 (which may already
369 incorporate \f$ \Sigma_1 \f$ corrections) and the two-body Coulomb
370 interaction via CSF2_Coulomb().
371
372 Does NOT include \f$ \Sigma_2 \f$ or Breit corrections; add those via
373 Sigma2_AB() and Breit_AB() respectively.
374
375 @param A,B The two CSFs.
376 @param twoJ Twice the total angular momentum 2J.
377 @param h1 Table of one-body matrix elements \f$ \langle a | h_1 | b \rangle \f$.
378 @param qk Table of Coulomb \f$ Q^k \f$ integrals.
379 @param s1c Optional derivative (dSigma/dE) correction to Sigma_1; applied
380 to each one-body matrix element (with the spectator orbital
381 energy) if given. See @ref Sigma1Correction.
382 @return CI Hamiltonian matrix element \f$ H_{AB} \f$.
383*/
384double Hab(const CI::CSF2 &A, const CI::CSF2 &B, int twoJ,
385 const Coulomb::meTable<double> &h1, const Coulomb::QkTable &qk,
386 const Sigma1Correction *s1c = nullptr);
387
388/*!
389 @brief Two-body \f$ \Sigma_2 \f$ correction to Hab().
390 @details
391 Evaluates the MBPT \f$ \Sigma_2 \f$ contribution to the CI matrix element
392 using CSF2_Sigma2(). Add to Hab() to form the full CI+MBPT Hamiltonian
393 matrix element.
394
395 @param A,B The two CSFs.
396 @param twoJ Twice the total angular momentum 2J.
397 @param Sk Table of \f$ \Sigma_2 \f$ (\f$ L^k \f$) integrals.
398 @return \f$ \Sigma_2 \f$ correction to \f$ H_{AB} \f$.
399*/
400double Sigma2_AB(const CI::CSF2 &A, const CI::CSF2 &B, int twoJ,
401 const Coulomb::LkTable &Sk,
402 const Coulomb::QkTable *qk = nullptr,
403 const std::vector<double> &hk = {},
404 const Coulomb::LkTable *dSk = nullptr, double dE0 = 0.0);
405
406/*!
407 @brief Breit correction to Hab().
408 @details
409 Evaluates the two-body Breit contribution to the CI matrix element using
410 CSF2_Breit(). Add to Hab() to include the Breit interaction.
411
412 @param A,B The two CSFs.
413 @param twoJ Twice the total angular momentum 2J.
414 @param Bk Table of Breit \f$ W^k \f$ integrals.
415 @return Breit correction to \f$ H_{AB} \f$.
416*/
417double Breit_AB(const CI::CSF2 &A, const CI::CSF2 &B, int twoJ,
418 const Coulomb::WkTable &Bk);
419
420/*!
421 @brief Builds the one-body Hamiltonian matrix element table for the CI basis.
422 @details
423 Constructs a lookup table of single-particle matrix elements
424 \f$ \langle a | h_1 | b \rangle \f$ for all pairs \f$ a, b \f$ in
425 @p ci_basis. The diagonal elements are the HF single-particle energies.
426
427 If @p include_Sigma1 is true, the one-body MBPT \f$ \Sigma_1 \f$ correction
428 is computed from the Coulomb integrals in @p qk using @p s1_basis_core and
429 @p s1_basis_excited as the internal lines of the MBPT diagrams and added to
430 the diagonal.
431
432 @param ci_basis Basis states for which table entries are needed.
433 @param s1_basis_core Core states used as internal lines for \f$ \Sigma_1 \f$.
434 @param s1_basis_excited Excited states used as internal lines for \f$ \Sigma_1 \f$.
435 @param qk Table of Coulomb \f$ Q^k \f$ integrals.
436 @param include_Sigma1 If true, add one-body MBPT \f$ \Sigma_1 \f$ corrections.
437 @return Table of \f$ \langle a | h_1 | b \rangle \f$ matrix elements.
438
439 @warning Assumes @p ci_basis states are Hartree-Fock eigenstates, so
440 off-diagonal HF terms vanish.
441*/
442[[nodiscard]] Coulomb::meTable<double>
443calculate_h1_table(const std::vector<DiracSpinor> &ci_basis,
444 const std::vector<DiracSpinor> &s1_basis_core,
445 const std::vector<DiracSpinor> &s1_basis_excited,
446 const Coulomb::QkTable &qk, bool include_Sigma1);
447
448/*!
449 @brief Builds the one-body Hamiltonian table using a precomputed
450 CorrelationPotential.
451 @details
452 Overload of calculate_h1_table() that uses a CorrelationPotential object
453 (i.e., a precomputed \f$ \Sigma_1 \f$ operator) instead of computing MBPT
454 diagrams on the fly. Preferred when a CorrelationPotential is available, as
455 it is generally faster and more complete.
456
457 @param ci_basis Basis states for which table entries are needed.
458 @param Sigma Precomputed one-body correlation potential \f$ \Sigma_1 \f$.
459 @param include_Sigma1 If true, include \f$ \Sigma_1 \f$ corrections from @p Sigma.
460 @return Table of \f$ \langle a | h_1 | b \rangle \f$ matrix elements.
461*/
462[[nodiscard]] Coulomb::meTable<double>
463calculate_h1_table(const std::vector<DiracSpinor> &ci_basis,
464 const MBPT::CorrelationPotential &Sigma,
465 bool include_Sigma1);
466
467/*!
468 @brief Builds or loads the two-body Breit integral table.
469 @details
470 Computes Breit \f$ W^k \f$ integrals for all pairs in @p ci_basis using the
471 Breit operator @p pBr. Results are cached to/from @p bk_filename.
472
473 If @p pBr is nullptr or @p no_new_integralsQ is true, no new integrals are
474 computed; only cached values are loaded.
475
476 @param bk_filename Filename for caching the \f$ W^k \f$ table.
477 @param pBr Pointer to Breit operator; if nullptr, returns empty table.
478 @param ci_basis Basis for which Breit integrals are needed.
479 @param max_k Maximum multipolarity k to include.
480 @param no_new_integralsQ If true, skip computing any new integrals.
481 @return Table of Breit \f$ W^k \f$ integrals.
482*/
483[[nodiscard]] Coulomb::WkTable
484calculate_Bk(const std::string &bk_filename, const HF::Breit *const pBr,
485 const std::vector<DiracSpinor> &ci_basis, int max_k,
486 bool no_new_integralsQ = false);
487
488/*!
489 @brief Returns the subset of @p basis matching @p include_str, excluding
490 states in @p exclude_str.
491 @details
492 Filters @p basis to retain only states described by the ampsci basis-string
493 notation (e.g., "20spdf") that are not part of the frozen core.
494
495 @param basis Full single-particle basis to filter.
496 @param include_str Basis-string specifying which states to keep;
497 if empty, all states in @p basis are kept (subject
498 to the frozen-core exclusion).
499 @param exclude_str Basis-string specifying core states to exclude.
500 @return Filtered basis vector.
501*/
502[[nodiscard]] std::vector<DiracSpinor>
503basis_subset(const std::vector<DiracSpinor> &basis,
504 const std::string &include_str,
505 const std::string &exclude_str = "");
506
507/*!
508 @brief Reduced matrix element between two CI states (low-level overload).
509 @details
510 Evaluates the reduced matrix element of a rank-@p K_rank tensor operator
511 between two CI states:
512
513 \f[
514 \redmatel{A}{T^K}{B}
515 = \sum_{ij} c_i^A \, c_j^B \, \redmatel{\text{CSF}_i}{T^K}{\text{CSF}_j},
516 \f]
517
518 where the single-particle reduced matrix elements are looked up from @p h.
519
520 @param cA,cB CI expansion coefficient vectors for states A and B.
521 @param CSFAs,CSFBs CSF bases for states A and B respectively.
522 @param twoJA,twoJB Twice the total angular momentum of states A and B.
523 @param h Lookup table of single-particle reduced matrix elements.
524 @param K_rank Rank of the tensor operator.
525 @param Parity Parity of the operator (+1 or -1).
526 @return Reduced matrix element \f$ \redmatel{A}{T^K}{B} \f$.
527*/
529 const std::vector<CI::CSF2> &CSFAs, int twoJA,
531 const std::vector<CI::CSF2> &CSFBs, int twoJB,
532 const Coulomb::meTable<double> &h, int K_rank, int Parity);
533
534/*!
535 @brief Reduced matrix element between two CI states (PsiJPi overload).
536 @details
537 Convenience wrapper around the low-level ReducedME() overload. Extracts
538 expansion coefficients and CSF lists from @p As and @p Bs for the requested
539 solution indices @p iA and @p iB.
540
541 @param As,Bs CI solution containers for the two states.
542 @param iA,iB Solution indices within @p As and @p Bs.
543 @param h Lookup table of single-particle reduced matrix elements.
544 @param K_rank Rank of the tensor operator.
545 @param Parity Parity of the operator (+1 or -1).
546 @return Reduced matrix element \f$ \redmatel{A}{T^K}{B} \f$.
547*/
548inline double ReducedME(const PsiJPi &As, std::size_t iA, const PsiJPi &Bs,
549 std::size_t iB, const Coulomb::meTable<double> &h,
550 int K_rank, int Parity) {
551 return ReducedME(As.coefs(iA), As.CSFs(), As.twoJ(), Bs.coefs(iB), Bs.CSFs(),
552 Bs.twoJ(), h, K_rank, Parity);
553}
554
555/*!
556 @brief Reduced matrix element between two two-electron CSFs.
557 @details
558 Evaluates \f$ \redmatel{X; J_X}{T^K}{V; J_V} \f$ for a rank-@p K_rank
559 one-body tensor operator using the standard 6j angular reduction, accounting
560 for identical-particle normalisation factors.
561
562 @warning This function may not handle all cases correctly; results should be
563 verified for non-trivial configurations.
564*/
565double RME_CSF2(const CI::CSF2 &X, int twoJX, const CI::CSF2 &V, int twoJV,
566 const Coulomb::meTable<double> &h, int K_rank);
567
568/*!
569 @brief Leading non-relativistic configuration of a CI state.
570 @details
571 Sums |c|^2 over the relativistic CSFs belonging to each non-relativistic
572 configuration, and returns the configuration with the largest total weight.
573
574 @param coefs CI expansion coefficients (one per CSF).
575 @param csfs The CSF basis (matching @p coefs).
576 @return Pair {configuration label (non-rel notation), total |c|^2 weight}.
577*/
578std::pair<std::string, double>
580 const std::vector<CSF2> &csfs);
581
582/*!
583 @brief Determines the best-fit (S, L) term for a two-electron state by
584 matching the g-factor.
585 @details
586 Iterates over all allowed (S, L) combinations for given orbital angular
587 momenta @p l1, @p l2 and total @p twoJ /2, and returns the pair whose
588 Lande g-factor is closest to @p gJ_target.
589
590 @param l1,l2 Orbital angular momenta of the two electrons.
591 @param twoJ Twice the total angular momentum 2J.
592 @param gJ_target Target g-factor to match.
593 @return Best-fit {2S, L} pair.
594*/
595std::pair<int, int> Term_S_L(int l1, int l2, int twoJ, double gJ_target);
596
597/*!
598 @brief Determines the (S, L) term for a two-electron state from the
599 expectation values of L^2 and S^2.
600 @details
601 Returns the (S, L) pair, subject to the triangle condition with J, that
602 minimises the combined distance |L(L+1) - @p L2| + |S(S+1) - @p S2|.
603 For a mixed state, this is the nearest (dominant) term; the purity is
604 indicated by @p L2, @p S2 themselves. See @ref expectation_L2S2.
605
606 @param L2 Expectation value of L^2.
607 @param S2 Expectation value of S^2.
608 @param twoJ Twice the total angular momentum 2J.
609 @return Best-fit {S, L} pair.
610*/
611std::pair<int, int> Term_S_L_from_expectation(double L2, double S2, int twoJ);
612
613//! Returns spectroscopic term symbol string, e.g. "3P_1"
614std::string Term_Symbol(int two_J, int L, int two_S, int parity);
615//! Returns term symbol without the J subscript, e.g. "3P"
616std::string Term_Symbol(int L, int two_S, int parity);
617
618/*!
619 @brief Constructs the full CI Hamiltonian matrix in the CSF basis.
620 @details
621 Builds the symmetric matrix \f$ H_{AB} \f$ for all CSF pairs in @p psi,
622 calling Hab() for each element and optionally adding Breit and
623 \f$ \Sigma_2 \f$ corrections.
624
625 @param psi CI solution container holding the CSF basis and J/parity.
626 @param h1 One-body matrix element table (may include \f$ \Sigma_1 \f$).
627 @param qk Coulomb \f$ Q^k \f$ integral table.
628 @param Bk Pointer to Breit \f$ W^k \f$ table; ignored if nullptr.
629 @param Sk Pointer to \f$ \Sigma_2 \f$ \f$ L^k \f$ table; ignored if nullptr.
630 @param s1c Pointer to derivative (dSigma/dE) correction for Sigma_1;
631 ignored if nullptr. See @ref Sigma1Correction.
632 @param hk Average S^k/Q^k ratios; if non-empty, diagrams with no stored
633 S^k use S^k = hk[k]*Q^k. See @ref MBPT::average_hk.
634 @param dSk Pointer to the dS^k/dE0 table; ignored if nullptr. If given,
635 each stored S^k is shifted to the target E0. See
636 @ref CI::corrected_Sk.
637 @param dE0 Shift of the target E0 from the one Sk was tabulated at.
638 @return Full CI Hamiltonian matrix in the CSF basis.
639*/
641construct_Hci(const PsiJPi &psi, const Coulomb::meTable<double> &h1,
642 const Coulomb::QkTable &qk, const Coulomb::WkTable *Bk = nullptr,
643 const Coulomb::LkTable *Sk = nullptr,
644 const Sigma1Correction *s1c = nullptr,
645 const std::vector<double> &hk = {},
646 const Coulomb::LkTable *dSk = nullptr, double dE0 = 0.0);
647
648/*!
649 @brief Constructs the CI Hamiltonian matrix from a set of integral tables.
650 @details
651 Overload of construct_Hci() taking the tables as @ref Integrals; the Breit
652 and \f$ \Sigma_2 \f$ corrections are included if those tables are non-empty.
653
654 If the iterative (dSigma/dE) correction is included, the reference energy
655 E0 (which also sets the Sigma_2 BW shift, if present) belongs to this
656 (J, parity) block: the lowest solved energy of @p psi is used if it has
657 solutions; otherwise the stored fallback is used, which is the
658 ground-state energy of the CI run. Blocks never solved directly - e.g.,
659 the target block of a mixed state - thus have their corrections evaluated
660 at the run's ground-state energy; the difference is higher order.
661
662 @param psi CI solution container holding the CSF basis and J/parity.
663 @param ints Integral tables, e.g., from Wavefunction::CI_integrals().
664 @return Full CI Hamiltonian matrix in the CSF basis.
665*/
666LinAlg::Matrix<double> construct_Hci(const PsiJPi &psi, const Integrals &ints);
667
668} // namespace CI
Two-electron configuration state function (CSF).
Definition CSF.hpp:31
Container for CI solutions in a single (J, parity) block.
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, parity) block.
Definition CSF.cpp:322
int twoJ() const
Twice the total angular momentum 2J for this block.
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:51
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
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:764
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:898
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:813
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:873
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:832
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:725
std::vector< PsiJPi > levels
One entry per {J, parity} requested.
Definition CI_Integrals.hpp:293
double corrected_Sk(double Sk, double dSk, double dE0)
Resummed shift of a 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 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 (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:913
Integrals integrals
Integral tables used to construct the CI Hamiltonians.
Definition CI_Integrals.hpp:295
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:291
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:260
Sigma1Correction s1_corr
Derivative (dSigma/dE) correction for Sigma_1; empty if not included.
Definition CI_Integrals.hpp:272
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:264
bool availableQ() const
False if the tables were never calculated (e.g., CI was run 'read_only')
Definition CI_Integrals.hpp:275
Coulomb::QkTable qk
Two-body Coulomb integrals, Q^k.
Definition CI_Integrals.hpp:256
Coulomb::LkTable dSk
Energy derivatives dS^k/dE0 of the Sigma_2 integrals; empty unless the Brillouin-Wigner (E0-dependent...
Definition CI_Integrals.hpp:268
double E0_sigma2
Reference E0 that Sk and dSk were tabulated at (Brillouin-Wigner)
Definition CI_Integrals.hpp:270
Coulomb::meTable< double > h1
One-body matrix elements, <a|h1|b>; may include Sigma_1.
Definition CI_Integrals.hpp:254
Coulomb::WkTable Bk
Two-body Breit integrals, B^k; empty if not included.
Definition CI_Integrals.hpp:258
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