2#include "DiracOperator/Operators/EM_multipole_base.hpp"
3#include "DiracOperator/TensorOperator.hpp"
4#include "IO/InputBlock.hpp"
5#include "Maths/SphericalBessel.hpp"
6#include "Wavefunction/Wavefunction.hpp"
7#include "qip/Maths.hpp"
11#include "EM_multipole_lowqr.hpp"
35 gr.
r(), Realness::imaginary,
true, &gr,
'V',
'E',
false,
jl,
50 std::vector<double> m_jK{};
51 std::vector<double> m_jKp1{};
52 const std::vector<double> *p_jK{
nullptr};
53 const std::vector<double> *p_jKp1{
nullptr};
60 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK),
61 p_jKp1(other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1) {}
64 EM_multipole::operator=(other);
66 m_jKp1 = other.m_jKp1;
67 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
68 p_jKp1 = other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1;
90 VEk(
const Grid &gr,
int K,
double omega,
93 gr.
r(), Realness::imaginary,
true, &gr,
'V',
'E',
false,
108 std::vector<double> m_jK_on_qr{};
109 std::vector<double> m_jKp1{};
110 const std::vector<double> *p_jK_on_qr{
nullptr};
111 const std::vector<double> *p_jKp1{
nullptr};
116 m_jK_on_qr(other.m_jK_on_qr),
117 m_jKp1(other.m_jKp1),
118 p_jK_on_qr(other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr :
120 p_jKp1(other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1) {}
121 VEk &operator=(
const VEk &other) {
122 if (
this != &other) {
123 EM_multipole::operator=(other);
124 m_jK_on_qr = other.m_jK_on_qr;
125 m_jKp1 = other.m_jKp1;
127 other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr : other.p_jK_on_qr;
128 p_jKp1 = other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1;
149 VLk(
const Grid &gr,
int K,
double omega,
152 gr.
r(), Realness::imaginary,
true, &gr,
'V',
'L',
false,
167 std::vector<double> m_jK_on_qr{};
168 std::vector<double> m_jKp1{};
169 const std::vector<double> *p_jK_on_qr{
nullptr};
170 const std::vector<double> *p_jKp1{
nullptr};
175 m_jK_on_qr(other.m_jK_on_qr),
176 m_jKp1(other.m_jKp1),
177 p_jK_on_qr(other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr :
179 p_jKp1(other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1) {}
180 VLk &operator=(
const VLk &other) {
181 if (
this != &other) {
182 EM_multipole::operator=(other);
183 m_jK_on_qr = other.m_jK_on_qr;
184 m_jKp1 = other.m_jKp1;
186 other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr : other.p_jK_on_qr;
187 p_jKp1 = other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1;
207 VMk(
const Grid &gr,
int K,
double omega,
210 gr.
r(), Realness::imaginary,
true, &gr,
'V',
'M',
false,
226 std::vector<double> m_jK{};
227 const std::vector<double> *p_jK{
nullptr};
233 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK) {}
234 VMk &operator=(
const VMk &other) {
235 if (
this != &other) {
236 EM_multipole::operator=(other);
238 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
258 Phik(
const Grid &gr,
int K,
double omega,
261 gr.
r(), Realness::real,
true, &gr,
'V',
'T',
false,
jl) {
275 std::vector<double> m_jK{};
276 const std::vector<double> *p_jK{
nullptr};
282 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK) {}
283 Phik &operator=(
const Phik &other) {
284 if (
this != &other) {
285 EM_multipole::operator=(other);
287 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
308 Sk(
const Grid &gr,
int K,
double omega,
311 gr.
r(), Realness::real,
true, &gr,
'S',
'T',
false,
jl) {
325 std::vector<double> m_jK{};
326 const std::vector<double> *p_jK{
nullptr};
332 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK) {}
333 Sk &operator=(
const Sk &other) {
334 if (
this != &other) {
335 EM_multipole::operator=(other);
337 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
361 AEk(
const Grid &gr,
int K,
double omega,
364 gr.
r(), Realness::real,
false, &gr,
'A',
'E',
false,
jl) {
378 std::vector<double> m_jK_on_qr{};
379 std::vector<double> m_jKp1{};
380 const std::vector<double> *p_jK_on_qr{
nullptr};
381 const std::vector<double> *p_jKp1{
nullptr};
386 m_jK_on_qr(other.m_jK_on_qr),
387 m_jKp1(other.m_jKp1),
388 p_jK_on_qr(other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr :
390 p_jKp1(other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1) {}
391 AEk &operator=(
const AEk &other) {
392 if (
this != &other) {
393 EM_multipole::operator=(other);
394 m_jK_on_qr = other.m_jK_on_qr;
395 m_jKp1 = other.m_jKp1;
397 other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr : other.p_jK_on_qr;
398 p_jKp1 = other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1;
415 ALk(
const Grid &gr,
int K,
double omega,
418 gr.
r(), Realness::real,
true, &gr,
'A',
'L',
false,
jl) {
432 std::vector<double> m_jK_on_qr{};
433 std::vector<double> m_jKp1{};
434 const std::vector<double> *p_jK_on_qr{
nullptr};
435 const std::vector<double> *p_jKp1{
nullptr};
440 m_jK_on_qr(other.m_jK_on_qr),
441 m_jKp1(other.m_jKp1),
442 p_jK_on_qr(other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr :
444 p_jKp1(other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1) {}
445 ALk &operator=(
const ALk &other) {
446 if (
this != &other) {
447 EM_multipole::operator=(other);
448 m_jK_on_qr = other.m_jK_on_qr;
449 m_jKp1 = other.m_jKp1;
451 other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr : other.p_jK_on_qr;
452 p_jKp1 = other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1;
469 AMk(
const Grid &gr,
int K,
double omega,
472 gr.
r(), Realness::real,
true, &gr,
'A',
'M',
false,
jl) {
487 std::vector<double> m_jK{};
488 const std::vector<double> *p_jK{
nullptr};
494 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK) {}
495 AMk &operator=(
const AMk &other) {
496 if (
this != &other) {
497 EM_multipole::operator=(other);
499 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
519 Phi5k(
const Grid &gr,
int K,
double omega,
522 gr.
r(), Realness::real,
true, &gr,
'A',
'T',
false,
jl) {
536 std::vector<double> m_jK{};
537 const std::vector<double> *p_jK{
nullptr};
543 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK) {}
545 if (
this != &other) {
546 EM_multipole::operator=(other);
548 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
568 S5k(
const Grid &gr,
int K,
double omega,
571 gr.
r(), Realness::real,
true, &gr,
'P',
'T',
false,
jl) {
585 std::vector<double> m_jK{};
586 const std::vector<double> *p_jK{
nullptr};
592 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK) {}
593 S5k &operator=(
const S5k &other) {
594 if (
this != &other) {
595 EM_multipole::operator=(other);
597 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
613 std::sqrt(K / (K + 1.0));
621inline std::unique_ptr<DiracOperator::TensorOperator>
625 {
"",
"Note: This function cannot use the Spherical Bessel looup table. If "
626 "require efficiency for large number of q values, construct directly"},
627 {
"k",
"Rank: k=1 for E1, =2 for E2 etc. [1]"},
628 {
"omega",
"Frequency: nb: q := alpha*omega [1.0e-4]"},
629 {
"type",
"V,A,S,P (Vector, Axial, Scalar, Pseudoscalar) [V]"},
630 {
"low_q",
"bool. Use low-q formulas (K=0 and 1 only, no L-form) [false]"},
631 {
"component",
"E,M,L,T (electric, magnetic, longitudanel, temporal). "
632 "Temporal is forced if type = S or P. [E]"},
633 {
"form",
"L,V (Length, Velocity); only for electric vector [L]"},
638 const auto k = input.
get(
"k", 1);
639 const auto omega = input.
get(
"omega", 1.0e-4);
641 const auto low_q = input.
get(
"low_q",
false);
643 using namespace std::string_literals;
644 const auto type = input.
get(
"type",
"V"s);
645 const auto component = input.
get(
"component",
"E"s);
646 const auto form = input.
get(
"form",
"V"s);
660 if (LengthForm && !(Electric && Vector)) {
661 std::cout <<
"Fail; Length form only valid for Electric Vector\n";
665 if (Electric && Vector)
666 return std::make_unique<VEk_lowq>(wf.
grid(), k, omega);
667 if (Electric && AxialVector)
668 return std::make_unique<AEk_lowq>(wf.
grid(), k, omega);
671 if (Longitudinal && Vector)
672 return std::make_unique<VLk_lowq>(wf.
grid(), k, omega);
673 if (Longitudinal && AxialVector)
674 return std::make_unique<ALk_lowq>(wf.
grid(), k, omega);
677 if (Magnetic && Vector)
678 return std::make_unique<VMk_lowq>(wf.
grid(), k, omega);
679 if (Magnetic && AxialVector)
680 return std::make_unique<AMk_lowq>(wf.
grid(), k, omega);
683 if (Temporal && Vector)
684 return std::make_unique<Phik_lowq>(wf.
grid(), k, omega);
685 if (Temporal && AxialVector)
686 return std::make_unique<Phi5k_lowq>(wf.
grid(), k, omega);
689 return std::make_unique<Sk_lowq>(wf.
grid(), k, omega);
691 return std::make_unique<S5k_lowq>(wf.
grid(), k, omega);
695 if (Electric && LengthForm && Vector)
696 return std::make_unique<VEk_Len>(wf.
grid(), k, omega);
697 if (Electric && Vector)
698 return std::make_unique<VEk>(wf.
grid(), k, omega);
699 if (Electric && AxialVector)
700 return std::make_unique<AEk>(wf.
grid(), k, omega);
703 if (Longitudinal && Vector)
704 return std::make_unique<VLk>(wf.
grid(), k, omega);
705 if (Longitudinal && AxialVector)
706 return std::make_unique<ALk>(wf.
grid(), k, omega);
709 if (Magnetic && Vector)
710 return std::make_unique<VMk>(wf.
grid(), k, omega);
711 if (Magnetic && AxialVector)
712 return std::make_unique<AMk>(wf.
grid(), k, omega);
715 if (Temporal && Vector)
716 return std::make_unique<Phik>(wf.
grid(), k, omega);
717 if (Temporal && AxialVector)
718 return std::make_unique<Phi5k>(wf.
grid(), k, omega);
721 return std::make_unique<Sk>(wf.
grid(), k, omega);
723 return std::make_unique<S5k>(wf.
grid(), k, omega);
725 std::cout <<
"Fail; Invalid Combination\n";
726 return std::make_unique<NullOperator>();
790std::unique_ptr<DiracOperator::TensorOperator>
Axial electric multipole operator: .
Definition EM_multipole.hpp:359
DiracSpinor radial_rhs(const int kappa_a, const DiracSpinor &Fb) const override final
radial_int = Fa * radial_rhs(a, Fb) (a needed for angular factor)
Definition EM_multipole.cpp:335
void updateFrequency(const double omega) override final
nb: q = alpha*omega!
Definition EM_multipole.cpp:398
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial part of integral R_ab = (Fa|t|Fb).
Definition EM_multipole.cpp:368
Axial longitudinal multipole operator: .
Definition EM_multipole.hpp:413
DiracSpinor radial_rhs(const int kappa_a, const DiracSpinor &Fb) const override final
radial_int = Fa * radial_rhs(a, Fb) (a needed for angular factor)
Definition EM_multipole.cpp:417
void updateFrequency(const double omega) override final
nb: q = alpha*omega!
Definition EM_multipole.cpp:453
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial part of integral R_ab = (Fa|t|Fb).
Definition EM_multipole.cpp:439
Axial magnetic multipole operator: .
Definition EM_multipole.hpp:467
DiracSpinor radial_rhs(const int kappa_a, const DiracSpinor &Fb) const override final
radial_int = Fa * radial_rhs(a, Fb) (a needed for angular factor)
Definition EM_multipole.cpp:475
void updateFrequency(const double omega) override final
nb: q = alpha*omega!
Definition EM_multipole.cpp:514
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial part of integral R_ab = (Fa|t|Fb).
Definition EM_multipole.cpp:497
Intermediate abstract base class for all EM relativistic multipole operators.
Definition EM_multipole_base.hpp:50
const SphericalBessel::JL_table * jl() const
Returns the precomputed Bessel table pointer (may be nullptr).
Definition EM_multipole_base.hpp:83
Temporal component of the axial vector multipole operator.
Definition EM_multipole.hpp:517
DiracSpinor radial_rhs(const int kappa_a, const DiracSpinor &Fb) const override final
radial_int = Fa * radial_rhs(a, Fb) (a needed for angular factor)
Definition EM_multipole.cpp:531
void updateFrequency(const double omega) override final
nb: q = alpha*omega!
Definition EM_multipole.cpp:559
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial part of integral R_ab = (Fa|t|Fb).
Definition EM_multipole.cpp:548
Temporal component of the vector multipole operator: .
Definition EM_multipole.hpp:256
DiracSpinor radial_rhs(const int kappa_a, const DiracSpinor &Fb) const override final
radial_int = Fa * radial_rhs(a, Fb) (a needed for angular factor)
Definition EM_multipole.cpp:248
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial part of integral R_ab = (Fa|t|Fb).
Definition EM_multipole.cpp:265
void updateFrequency(const double omega) override final
nb: q = alpha*omega!
Definition EM_multipole.cpp:276
Pseudoscalar multipole operator: t^k (i g^0 g^5)
Definition EM_multipole.hpp:566
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial part of integral R_ab = (Fa|t|Fb).
Definition EM_multipole.cpp:592
DiracSpinor radial_rhs(const int kappa_a, const DiracSpinor &Fb) const override final
radial_int = Fa * radial_rhs(a, Fb) (a needed for angular factor)
Definition EM_multipole.cpp:575
void updateFrequency(const double omega) override final
nb: q = alpha*omega!
Definition EM_multipole.cpp:602
Scalar multipole operator: .
Definition EM_multipole.hpp:306
DiracSpinor radial_rhs(const int kappa_a, const DiracSpinor &Fb) const override final
radial_int = Fa * radial_rhs(a, Fb) (a needed for angular factor)
Definition EM_multipole.cpp:292
void updateFrequency(const double omega) override final
nb: q = alpha*omega!
Definition EM_multipole.cpp:319
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial part of integral R_ab = (Fa|t|Fb).
Definition EM_multipole.cpp:309
Vector electric multipole (transition) operator, Length-form: ( ).
Definition EM_multipole.hpp:30
DiracSpinor radial_rhs(const int kappa_a, const DiracSpinor &Fb) const override final
radial_int = Fa * radial_rhs(a, Fb) (a needed for angular factor)
Definition EM_multipole.cpp:9
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial part of integral R_ab = (Fa|t|Fb).
Definition EM_multipole.cpp:31
void updateFrequency(const double omega) override final
nb: q = alpha*omega!
Definition EM_multipole.cpp:47
Vector electric multipole (V-form) operator: .
Definition EM_multipole.hpp:88
void updateFrequency(const double omega) override final
nb: q = alpha*omega!
Definition EM_multipole.cpp:112
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial part of integral R_ab = (Fa|t|Fb).
Definition EM_multipole.cpp:93
DiracSpinor radial_rhs(const int kappa_a, const DiracSpinor &Fb) const override final
radial_int = Fa * radial_rhs(a, Fb) (a needed for angular factor)
Definition EM_multipole.cpp:67
Vector longitudinal multipole operator (V-form): .
Definition EM_multipole.hpp:147
DiracSpinor radial_rhs(const int kappa_a, const DiracSpinor &Fb) const override final
radial_int = Fa * radial_rhs(a, Fb) (a needed for angular factor)
Definition EM_multipole.cpp:134
void updateFrequency(const double omega) override final
nb: q = alpha*omega!
Definition EM_multipole.cpp:172
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial part of integral R_ab = (Fa|t|Fb).
Definition EM_multipole.cpp:158
Vector magnetic multipole operator: .
Definition EM_multipole.hpp:205
void updateFrequency(const double omega) override final
nb: q = alpha*omega!
Definition EM_multipole.cpp:232
DiracSpinor radial_rhs(const int kappa_a, const DiracSpinor &Fb) const override final
radial_int = Fa * radial_rhs(a, Fb) (a needed for angular factor)
Definition EM_multipole.cpp:194
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial part of integral R_ab = (Fa|t|Fb).
Definition EM_multipole.cpp:216
s (spin) operator
Definition jls.hpp:50
Stores radial Dirac spinor: F_nk = (f, g)
Definition DiracSpinor.hpp:42
Holds grid, including type + Jacobian (dr/du)
Definition Grid.hpp:31
const std::vector< double > & r() const
Grid points, r.
Definition Grid.hpp:75
Spherical Bessel Lookup table; in the form j_L(qr) = J[L][q][r].
Definition SphericalBessel.hpp:120
Stores Wavefunction (set of valence orbitals, grid, HF etc.)
Definition Wavefunction.hpp:37
const Grid & grid() const
Returns a const reference to the radial grid.
Definition Wavefunction.hpp:82
constexpr bool evenQ(int a)
Returns true if a is even - for integer values.
Definition Wigner369j.hpp:220
double moment_factor(int K, double omega)
Convert from "transition form" to "moment form".
Definition EM_multipole.hpp:610
Dirac Operators: General + derived.
Definition GenerateOperator.cpp:3
std::unique_ptr< DiracOperator::TensorOperator > MultipoleOperator(const Grid &grid, int k, double omega, char type, char comp, bool low_q, const SphericalBessel::JL_table *jl)
Factory for relativistic multipole operators.
Definition EM_multipole.cpp:629
constexpr double alpha
Fine-structure constant: alpha = 1/137.035 999 177(21) [CODATA 2022].
Definition PhysConst_constants.hpp:24
constexpr T double_factorial(T x)
Double factorial x!! - nb: does not check for overflow. Max x is 20 for uint64_t.
Definition Maths.hpp:131
bool ci_wc_compare(std::string_view s1, std::string_view s2)
Compares two strings, s1 and s2. s2 may contain ONE wildcard ('*') which will match anything....
Definition String.hpp:140
constexpr auto pow(T x)
x^n for integer n (n compile-time template parameter), x any arithmetic type (T). Returns double for ...
Definition Maths.hpp:88