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));
623 static std::unique_ptr<TensorOperator> generate(
const IO::InputBlock &input,
627 "Note: This function cannot use the Spherical Bessel looup table. If "
628 "require efficiency for large number of q values, construct directly"},
629 {
"k",
"Rank: k=1 for E1, =2 for E2 etc. [1]"},
630 {
"omega",
"Frequency: nb: q := alpha*omega [1.0e-4]"},
631 {
"type",
"V,A,S,P (Vector, Axial, Scalar, Pseudoscalar) [V]"},
632 {
"low_q",
"bool. Use low-q formulas (K=0 and 1 only, no L-form) [false]"},
633 {
"component",
"E,M,L,T (electric, magnetic, longitudanel, temporal). "
634 "Temporal is forced if type = S or P. [E]"},
635 {
"form",
"L,V (Length, Velocity); only for electric vector [L]"},
640 const auto k = input.
get(
"k", 1);
641 const auto omega = input.
get(
"omega", 1.0e-4);
643 const auto low_q = input.
get(
"low_q",
false);
645 using namespace std::string_literals;
646 const auto type = input.
get(
"type",
"V"s);
647 const auto component = input.
get(
"component",
"E"s);
648 const auto form = input.
get(
"form",
"V"s);
662 if (LengthForm && !(Electric && Vector)) {
663 std::cout <<
"Fail; Length form only valid for Electric Vector\n";
667 if (Electric && Vector)
668 return std::make_unique<VEk_lowq>(wf.
grid(), k, omega);
669 if (Electric && AxialVector)
670 return std::make_unique<AEk_lowq>(wf.
grid(), k, omega);
673 if (Longitudinal && Vector)
674 return std::make_unique<VLk_lowq>(wf.
grid(), k, omega);
675 if (Longitudinal && AxialVector)
676 return std::make_unique<ALk_lowq>(wf.
grid(), k, omega);
679 if (Magnetic && Vector)
680 return std::make_unique<VMk_lowq>(wf.
grid(), k, omega);
681 if (Magnetic && AxialVector)
682 return std::make_unique<AMk_lowq>(wf.
grid(), k, omega);
685 if (Temporal && Vector)
686 return std::make_unique<Phik_lowq>(wf.
grid(), k, omega);
687 if (Temporal && AxialVector)
688 return std::make_unique<Phi5k_lowq>(wf.
grid(), k, omega);
691 return std::make_unique<Sk_lowq>(wf.
grid(), k, omega);
693 return std::make_unique<S5k_lowq>(wf.
grid(), k, omega);
697 if (Electric && LengthForm && Vector)
698 return std::make_unique<VEk_Len>(wf.
grid(), k, omega);
699 if (Electric && Vector)
700 return std::make_unique<VEk>(wf.
grid(), k, omega);
701 if (Electric && AxialVector)
702 return std::make_unique<AEk>(wf.
grid(), k, omega);
705 if (Longitudinal && Vector)
706 return std::make_unique<VLk>(wf.
grid(), k, omega);
707 if (Longitudinal && AxialVector)
708 return std::make_unique<ALk>(wf.
grid(), k, omega);
711 if (Magnetic && Vector)
712 return std::make_unique<VMk>(wf.
grid(), k, omega);
713 if (Magnetic && AxialVector)
714 return std::make_unique<AMk>(wf.
grid(), k, omega);
717 if (Temporal && Vector)
718 return std::make_unique<Phik>(wf.
grid(), k, omega);
719 if (Temporal && AxialVector)
720 return std::make_unique<Phi5k>(wf.
grid(), k, omega);
723 return std::make_unique<Sk>(wf.
grid(), k, omega);
725 return std::make_unique<S5k>(wf.
grid(), k, omega);
727 std::cout <<
"Fail; Invalid Combination\n";
728 return std::make_unique<NullOperator>();
793std::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
Computes the right-hand spinor dF_b for the radial integral.
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 integral R_ab, defined by RME = angularF(a,b) * radialIntegral(a,b).
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
Computes the right-hand spinor dF_b for the radial integral.
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 integral R_ab, defined by RME = angularF(a,b) * radialIntegral(a,b).
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
Computes the right-hand spinor dF_b for the radial integral.
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 integral R_ab, defined by RME = angularF(a,b) * radialIntegral(a,b).
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
Computes the right-hand spinor dF_b for the radial integral.
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 integral R_ab, defined by RME = angularF(a,b) * radialIntegral(a,b).
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
Computes the right-hand spinor dF_b for the radial integral.
Definition EM_multipole.cpp:248
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial integral R_ab, defined by RME = angularF(a,b) * radialIntegral(a,b).
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 integral R_ab, defined by RME = angularF(a,b) * radialIntegral(a,b).
Definition EM_multipole.cpp:592
DiracSpinor radial_rhs(const int kappa_a, const DiracSpinor &Fb) const override final
Computes the right-hand spinor dF_b for the radial integral.
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
Computes the right-hand spinor dF_b for the radial integral.
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 integral R_ab, defined by RME = angularF(a,b) * radialIntegral(a,b).
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
Computes the right-hand spinor dF_b for the radial integral.
Definition EM_multipole.cpp:9
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial integral R_ab, defined by RME = angularF(a,b) * radialIntegral(a,b).
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 integral R_ab, defined by RME = angularF(a,b) * radialIntegral(a,b).
Definition EM_multipole.cpp:93
DiracSpinor radial_rhs(const int kappa_a, const DiracSpinor &Fb) const override final
Computes the right-hand spinor dF_b for the radial integral.
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
Computes the right-hand spinor dF_b for the radial integral.
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 integral R_ab, defined by RME = angularF(a,b) * radialIntegral(a,b).
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
Computes the right-hand spinor dF_b for the radial integral.
Definition EM_multipole.cpp:194
double radialIntegral(const DiracSpinor &Fa, const DiracSpinor &Fb) const override final
Radial integral R_ab, defined by RME = angularF(a,b) * radialIntegral(a,b).
Definition EM_multipole.cpp:216
s (spin) operator
Definition jls.hpp:57
Stores radial Dirac spinor: F_nk = (f, g)
Definition DiracSpinor.hpp:42
Non-uniform radial grid with Jacobian, suitable for atomic structure calculations.
Definition Grid.hpp:85
const std::vector< double > & r() const
Full grid vector r.
Definition Grid.hpp:131
Lookup table of spherical Bessel functions: j_L(q*r) = J[L][q][r].
Definition SphericalBessel.hpp:124
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:233
double moment_factor(int K, double omega)
Convert from "transition form" to "moment form".
Definition EM_multipole.hpp:610
Dirac operators: TensorOperator base class and derived implementations for single-particle (one-body)...
Definition GenerateOperator.cpp:6
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 double double_factorial(T x)
Double factorial x!! - takes integer, returns double.
Definition Maths.hpp:141
bool ci_wc_compare(std::string_view s1, std::string_view s2)
Case-insensitive version of wildcard_compare.
Definition String.hpp:155
constexpr auto pow(T x)
x^n for compile-time integer n, x any arithmetic type.
Definition Maths.hpp:98
Factory class for Multipole operators (never instantiated directly).
Definition EM_multipole.hpp:621