ampsci
High-precision calculations for one- and two-valence atomic systems
calcMatrixElements.hpp
1#pragma once
2#include "CorePolarisation.hpp"
3#include "Coulomb/meTable.hpp"
4#include "MBPT/StructureRad.hpp"
5#include "qip/String.hpp"
6#include <iostream>
7#include <string>
8#include <vector>
9class DiracSpinor;
10namespace DiracOperator {
11class TensorOperator;
12}
13namespace HF {
14class HartreeFock;
15}
16
17namespace ExternalField {
18
19/*!
20 @brief Small struct to store a single calculated reduced matrix element with RPA correction.
21 @details
22 Holds the result of a single matrix element calculation \f$ \redmatel{a}{h}{b} \f$,
23 including the lowest-order value, the RPA correction, and the transition
24 frequency.
25
26 The printed output includes columns: state labels, frequency, lowest-order
27 matrix element, and (if non-zero) the RPA-corrected value \f$ t_{ab} + \delta V_{ab} \f$.
28*/
29struct MEdata {
30
31 std::string a, b;
32 double w_ab;
33 double hab, dv;
34
35 static std::string title(bool rpaQ = true) {
36 if (rpaQ)
37 return " a b w_ab t_ab RPA_ab";
38 else
39 return " a b w_ab t_ab";
40 }
41 static std::string title_noRPA() { return " a b w_ab t_ab"; }
42
43 friend std::ostream &operator<<(std::ostream &os, const MEdata &m) {
44 os << qip::fstring(" %4s %4s %8.5f %13.6e", m.a.c_str(), m.b.c_str(),
45 m.w_ab, m.hab);
46 if (m.dv != 0.0) {
47 os << qip::fstring(" %13.6e", m.hab + m.dv);
48 }
49 return os;
50 }
51};
52
53/*!
54 @brief Calculates reduced matrix elements <a||h||b> for lists of orbitals.
55 @details
56 Computes reduced matrix elements \f$ \redmatel{a}{h}{b} \f$ for all
57 non-zero combinations of states from @p a_orbs and @p b_orbs. Optionally
58 includes RPA corrections via @p dV.
59
60 The transition frequency is set to \f$ \omega_{ab} = \varepsilon_a - \varepsilon_b \f$
61 for off-diagonal elements, and 0 for diagonal elements.
62
63 If @p each_freq is true, the operator and dV are updated at each transition
64 frequency individually. Otherwise, they are updated once using @p omega.
65
66 Selection rules are applied via the operator's `isZero()` method. For
67 odd-parity operators, only elements with the even-parity state on the right
68 are included (unless @p calculate_both is true). For even-parity operators,
69 each off-diagonal pair is included once (upper triangle, unless
70 @p calculate_both is true). When @p b_orbs != @p a_orbs,
71 @p calculate_both is set to true automatically.
72
73 @param b_orbs Bra states (final states, index b).
74 @param a_orbs Ket states (initial states, index a).
75 @param h Pointer to the tensor operator.
76 @param dV Optional RPA/core-polarisation correction. If nullptr,
77 no correction is applied.
78 @param omega Frequency used to update frequency-dependent operators
79 and dV when @p each_freq is false.
80 @param each_freq If true, update the operator and dV at the natural
81 transition frequency for each element.
82 @param diagonal If true, include diagonal elements \f$ \redmatel{a}{h}{a} \f$.
83 @param off_diagonal If true, include off-diagonal elements.
84 @param calculate_both If true, include both \f$ \redmatel{a}{h}{b} \f$ and
85 \f$ \redmatel{b}{h}{a} \f$ for off-diagonal pairs.
86 Forced true when @p b_orbs != @p a_orbs.
87
88 @return Vector of MEdata structs, one per non-zero matrix element.
89*/
90std::vector<MEdata>
91calcMatrixElements(const std::vector<DiracSpinor> &b_orbs,
92 const std::vector<DiracSpinor> &a_orbs,
94 CorePolarisation *const dV = nullptr, double omega = 0.0,
95 bool each_freq = false, bool diagonal = true,
96 bool off_diagonal = true, bool calculate_both = false);
97
98/*!
99 @brief Calculates reduced matrix elements for a single list of orbitals.
100 @details
101 Convenience overload; calls calcMatrixElements(orbs, orbs, ...) with both
102 bra and ket taken from the same set @p orbs.
103*/
104inline std::vector<MEdata>
105calcMatrixElements(const std::vector<DiracSpinor> &orbs,
107 CorePolarisation *const dV = nullptr, double omega = 0.0,
108 bool each_freq = false, bool diagonal = true,
109 bool off_diagonal = true, bool calculate_both = false) {
110 return calcMatrixElements(orbs, orbs, h, dV, omega, each_freq, diagonal,
111 off_diagonal, calculate_both);
112}
113
114/*!
115 @brief Builds a lookup table of reduced matrix elements <a||h||b>.
116 @details
117 Fills and returns a `Coulomb::meTable<double>` with reduced matrix elements
118 \f[ t_{ab} = \redmatel{a}{h}{b} + \delta V_{ab} + \delta_{\rm SR}^{ab} \f]
119 for all non-zero pairs from @p a_orbs and @p b_orbs.
120
121 Optionally includes RPA correction @p dV and structure radiation @p srn.
122 The symmetry-conjugate \f$ \redmatel{b}{h}{a} \f$ is also stored via
123 `symm_sign()`. Table is filled with OpenMP parallelisation.
124
125 @param a_orbs Bra states.
126 @param b_orbs Ket states.
127 @param h Pointer to the (const) tensor operator.
128 @param dV Optional RPA correction. If nullptr, not applied.
129 @param srn Optional structure radiation/normalisation correction.
130 If nullptr, not applied.
131 @param omega Only used for Structure Radiation. If set, use this fixed
132 frequency for all elements; otherwise uses |eb - ea|.
133
134 @return meTable containing t_ab for all non-zero pairs (and conjugates).
135
136 @note For frequency-dependent operators, @p omega should be set before
137 calling this function.
138*/
139Coulomb::meTable<double> me_table(const std::vector<DiracSpinor> &a_orbs,
140 const std::vector<DiracSpinor> &b_orbs,
142 const CorePolarisation *dV = nullptr,
143 const MBPT::StructureRad *srn = nullptr,
144 std::optional<double> omega = {});
145
146/*!
147 @brief Builds a matrix element table for a single set of orbitals.
148 @details
149 Convenience overload; calls me_table(a_orbs, a_orbs, ...) with both
150 bra and ket taken from @p a_orbs.
151*/
153 const std::vector<DiracSpinor> &a_orbs,
154 const DiracOperator::TensorOperator *h, const CorePolarisation *dV = nullptr,
155 const MBPT::StructureRad *srn = nullptr, std::optional<double> omega = {}) {
156 return me_table(a_orbs, a_orbs, h, dV, srn, omega);
157}
158
159/*!
160 @brief Factory function to construct a core-polarisation (RPA) object.
161 @details
162 Parses @p method and returns a `std::unique_ptr<CorePolarisation>` of the
163 appropriate type. Returns nullptr if @p method is "none" or "false".
164
165 Supported methods (case-insensitive):
166 - `"TDHF"`: time-dependent Hartree-Fock (TDHF).
167 - `"basis"`: TDHF solved in a basis set.
168 - `"diagram"`: diagram RPA.
169 - `"none"`, `"false"`, `""`: no RPA; returns nullptr.
170
171 If the method string is not recognised, prints an error and defaults to none.
172
173 @param method String specifying the RPA method (see above).
174 @param h Pointer to the operator for which RPA is to be solved.
175 @param vhf Pointer to the Hartree-Fock object (provides core potential).
176 @param print If true, print a brief description of the chosen method.
177 @param basis Basis set for basis/diagram methods (ignored for TDHF).
178 @param identity Identifier string passed to DiagramRPA (e.g. for caching).
179
180 @return Unique pointer to the constructed CorePolarisation object, or
181 nullptr if RPA is disabled.
182
183 @warning An unrecognised @p method string triggers an error message and
184 falls through to no RPA rather than throwing.
185*/
186std::unique_ptr<CorePolarisation>
187make_rpa(const std::string &method, const DiracOperator::TensorOperator *h,
188 const HF::HartreeFock *vhf, bool print = false,
189 const std::vector<DiracSpinor> &basis = {},
190 const std::string &identity = "");
191
192} // namespace ExternalField
Look-up table for matrix elements. Note: does not assume any symmetry: (a,b) is stored independantly ...
Definition meTable.hpp:17
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
Solves relativistic Hartree-Fock equations for core and valence. Optionally includes Breit and QED ef...
Definition HartreeFock.hpp:72
Calculates Structure Radiation + Normalisation of states, using diagram method.
Definition StructureRad.hpp:65
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
std::vector< MEdata > calcMatrixElements(const std::vector< DiracSpinor > &b_orbs, const std::vector< DiracSpinor > &a_orbs, DiracOperator::TensorOperator *const h, CorePolarisation *const dV, double omega, bool each_freq, bool diagonal, bool off_diagonal, bool calculate_both)
Calculates reduced matrix elements <a||h||b> for lists of orbitals.
Definition calcMatrixElements.cpp:16
std::unique_ptr< CorePolarisation > make_rpa(const std::string &method, const DiracOperator::TensorOperator *h, const HF::HartreeFock *vhf, bool print, const std::vector< DiracSpinor > &basis, const std::string &identity)
Factory function to construct a core-polarisation (RPA) object.
Definition calcMatrixElements.cpp:165
Coulomb::meTable< double > me_table(const std::vector< DiracSpinor > &a_orbs, const std::vector< DiracSpinor > &b_orbs, const DiracOperator::TensorOperator *h, const CorePolarisation *dV, const MBPT::StructureRad *srn, std::optional< double > omega)
Builds a lookup table of reduced matrix elements <a||h||b>.
Definition calcMatrixElements.cpp:111
Functions and classes for Hartree-Fock.
Definition CI_Integrals.hpp:13
std::string fstring(const std::string format,...)
Returns a formatted string using printf-style format specifiers.
Definition String.hpp:23
Small struct to store a single calculated reduced matrix element with RPA correction.
Definition calcMatrixElements.hpp:29