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"
37 gr.
r(), Realness::real,
true, &gr,
'V',
'E',
false,
jl,
52 std::vector<double> m_jK{};
53 std::vector<double> m_jKp1{};
54 const std::vector<double> *p_jK{
nullptr};
55 const std::vector<double> *p_jKp1{
nullptr};
62 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK),
63 p_jKp1(other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1) {}
66 EM_multipole::operator=(other);
68 m_jKp1 = other.m_jKp1;
69 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
70 p_jKp1 = other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1;
98 gr.
r(), Realness::imaginary,
true, &gr,
'V',
'E',
false,
113 std::vector<double> m_jK_on_qr{};
114 std::vector<double> m_jKp1{};
115 const std::vector<double> *p_jK_on_qr{
nullptr};
116 const std::vector<double> *p_jKp1{
nullptr};
121 m_jK_on_qr(other.m_jK_on_qr),
122 m_jKp1(other.m_jKp1),
123 p_jK_on_qr(other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr :
125 p_jKp1(other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1) {}
126 VEk &operator=(
const VEk &other) {
127 if (
this != &other) {
128 EM_multipole::operator=(other);
129 m_jK_on_qr = other.m_jK_on_qr;
130 m_jKp1 = other.m_jKp1;
132 other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr : other.p_jK_on_qr;
133 p_jKp1 = other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1;
157 gr.
r(), Realness::imaginary,
true, &gr,
'V',
'L',
false,
172 std::vector<double> m_jK_on_qr{};
173 std::vector<double> m_jKp1{};
174 const std::vector<double> *p_jK_on_qr{
nullptr};
175 const std::vector<double> *p_jKp1{
nullptr};
180 m_jK_on_qr(other.m_jK_on_qr),
181 m_jKp1(other.m_jKp1),
182 p_jK_on_qr(other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr :
184 p_jKp1(other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1) {}
185 VLk &operator=(
const VLk &other) {
186 if (
this != &other) {
187 EM_multipole::operator=(other);
188 m_jK_on_qr = other.m_jK_on_qr;
189 m_jKp1 = other.m_jKp1;
191 other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr : other.p_jK_on_qr;
192 p_jKp1 = other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1;
218 gr.
r(), Realness::real,
true, &gr,
'V',
'M',
false,
jl) {
233 std::vector<double> m_jK{};
234 const std::vector<double> *p_jK{
nullptr};
240 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK) {}
241 VMk &operator=(
const VMk &other) {
242 if (
this != &other) {
243 EM_multipole::operator=(other);
245 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
268 gr.
r(), Realness::real,
true, &gr,
'V',
'T',
false,
jl) {
282 std::vector<double> m_jK{};
283 const std::vector<double> *p_jK{
nullptr};
289 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK) {}
290 Phik &operator=(
const Phik &other) {
291 if (
this != &other) {
292 EM_multipole::operator=(other);
294 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
318 gr.
r(), Realness::real,
true, &gr,
'S',
'T',
false,
jl) {
332 std::vector<double> m_jK{};
333 const std::vector<double> *p_jK{
nullptr};
339 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK) {}
340 Sk &operator=(
const Sk &other) {
341 if (
this != &other) {
342 EM_multipole::operator=(other);
344 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
371 gr.
r(), Realness::real,
true, &gr,
'A',
'E',
false,
jl) {
385 std::vector<double> m_jK_on_qr{};
386 std::vector<double> m_jKp1{};
387 const std::vector<double> *p_jK_on_qr{
nullptr};
388 const std::vector<double> *p_jKp1{
nullptr};
393 m_jK_on_qr(other.m_jK_on_qr),
394 m_jKp1(other.m_jKp1),
395 p_jK_on_qr(other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr :
397 p_jKp1(other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1) {}
398 AEk &operator=(
const AEk &other) {
399 if (
this != &other) {
400 EM_multipole::operator=(other);
401 m_jK_on_qr = other.m_jK_on_qr;
402 m_jKp1 = other.m_jKp1;
404 other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr : other.p_jK_on_qr;
405 p_jKp1 = other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1;
425 gr.
r(), Realness::real,
true, &gr,
'A',
'L',
false,
jl) {
439 std::vector<double> m_jK_on_qr{};
440 std::vector<double> m_jKp1{};
441 const std::vector<double> *p_jK_on_qr{
nullptr};
442 const std::vector<double> *p_jKp1{
nullptr};
447 m_jK_on_qr(other.m_jK_on_qr),
448 m_jKp1(other.m_jKp1),
449 p_jK_on_qr(other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr :
451 p_jKp1(other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1) {}
452 ALk &operator=(
const ALk &other) {
453 if (
this != &other) {
454 EM_multipole::operator=(other);
455 m_jK_on_qr = other.m_jK_on_qr;
456 m_jKp1 = other.m_jKp1;
458 other.p_jK_on_qr == &other.m_jK_on_qr ? &m_jK_on_qr : other.p_jK_on_qr;
459 p_jKp1 = other.p_jKp1 == &other.m_jKp1 ? &m_jKp1 : other.p_jKp1;
482 gr.
r(), Realness::imaginary,
true, &gr,
'A',
'M',
false,
498 std::vector<double> m_jK{};
499 const std::vector<double> *p_jK{
nullptr};
505 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK) {}
506 AMk &operator=(
const AMk &other) {
507 if (
this != &other) {
508 EM_multipole::operator=(other);
510 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
536 gr.
r(), Realness::imaginary,
true, &gr,
'A',
'T',
false,
551 std::vector<double> m_jK{};
552 const std::vector<double> *p_jK{
nullptr};
558 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK) {}
560 if (
this != &other) {
561 EM_multipole::operator=(other);
563 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
588 gr.
r(), Realness::real,
true, &gr,
'P',
'T',
false,
jl) {
602 std::vector<double> m_jK{};
603 const std::vector<double> *p_jK{
nullptr};
609 p_jK(other.p_jK == &other.m_jK ? &m_jK : other.p_jK) {}
610 S5k &operator=(
const S5k &other) {
611 if (
this != &other) {
612 EM_multipole::operator=(other);
614 p_jK = other.p_jK == &other.m_jK ? &m_jK : other.p_jK;
630 std::sqrt(K / (K + 1.0));
640 static std::unique_ptr<TensorOperator> generate(
const IO::InputBlock &input,
644 "Note: This function cannot use the Spherical Bessel looup table. If "
645 "require efficiency for large number of q values, construct directly"},
646 {
"k",
"Rank: k=1 for E1, =2 for E2 etc. [1]"},
647 {
"omega",
"Frequency: nb: q := alpha*omega [1.0e-4]"},
648 {
"type",
"V,A,S,P (Vector, Axial, Scalar, Pseudoscalar) [V]"},
649 {
"low_q",
"bool. Use low-q formulas (K=0 and 1 only, no L-form) [false]"},
650 {
"component",
"E,M,L,T (electric, magnetic, longitudanel, temporal). "
651 "Temporal is forced if type = S or P. [E]"},
652 {
"form",
"L,V (Length, Velocity); only for electric vector [L]"},
657 const auto k = input.
get(
"k", 1);
658 const auto omega = input.
get(
"omega", 1.0e-4);
660 const auto low_q = input.
get(
"low_q",
false);
662 using namespace std::string_literals;
663 const auto type = input.
get(
"type",
"V"s);
664 const auto component = input.
get(
"component",
"E"s);
665 const auto form = input.
get(
"form",
"V"s);
679 if (LengthForm && !(Electric && Vector)) {
680 std::cout <<
"Fail; Length form only valid for Electric Vector\n";
684 if (Electric && Vector)
685 return std::make_unique<VEk_lowq>(wf.
grid(), k, omega);
686 if (Electric && AxialVector)
687 return std::make_unique<AEk_lowq>(wf.
grid(), k, omega);
690 if (Longitudinal && Vector)
691 return std::make_unique<VLk_lowq>(wf.
grid(), k, omega);
692 if (Longitudinal && AxialVector)
693 return std::make_unique<ALk_lowq>(wf.
grid(), k, omega);
696 if (Magnetic && Vector)
697 return std::make_unique<VMk_lowq>(wf.
grid(), k, omega);
698 if (Magnetic && AxialVector)
699 return std::make_unique<AMk_lowq>(wf.
grid(), k, omega);
702 if (Temporal && Vector)
703 return std::make_unique<Phik_lowq>(wf.
grid(), k, omega);
704 if (Temporal && AxialVector)
705 return std::make_unique<Phi5k_lowq>(wf.
grid(), k, omega);
708 return std::make_unique<Sk_lowq>(wf.
grid(), k, omega);
710 return std::make_unique<S5k_lowq>(wf.
grid(), k, omega);
714 if (Electric && LengthForm && Vector)
715 return std::make_unique<VEk_Len>(wf.
grid(), k, omega);
716 if (Electric && Vector)
717 return std::make_unique<VEk>(wf.
grid(), k, omega);
718 if (Electric && AxialVector)
719 return std::make_unique<AEk>(wf.
grid(), k, omega);
722 if (Longitudinal && Vector)
723 return std::make_unique<VLk>(wf.
grid(), k, omega);
724 if (Longitudinal && AxialVector)
725 return std::make_unique<ALk>(wf.
grid(), k, omega);
728 if (Magnetic && Vector)
729 return std::make_unique<VMk>(wf.
grid(), k, omega);
730 if (Magnetic && AxialVector)
731 return std::make_unique<AMk>(wf.
grid(), k, omega);
734 if (Temporal && Vector)
735 return std::make_unique<Phik>(wf.
grid(), k, omega);
736 if (Temporal && AxialVector)
737 return std::make_unique<Phi5k>(wf.
grid(), k, omega);
740 return std::make_unique<Sk>(wf.
grid(), k, omega);
742 return std::make_unique<S5k>(wf.
grid(), k, omega);
744 std::cout <<
"Fail; Invalid Combination\n";
745 return std::make_unique<NullOperator>();
827std::unique_ptr<DiracOperator::TensorOperator>
Axial electric multipole operator: .
Definition EM_multipole.hpp:366
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:420
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:477
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:531
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:263
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:583
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:313
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
double omega() const
Returns the current frequency set by the last updateFrequency() call. Zero for frequency-independent ...
Definition TensorOperator.hpp:266
Vector electric multipole (transition) operator, Length-form: ( ).
Definition EM_multipole.hpp:32
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:93
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:152
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:213
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:63
Stores radial Dirac spinor: F_nk = (f, g)
Definition DiracSpinor.hpp:44
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:38
const Grid & grid() const
Returns a const reference to the radial grid.
Definition Wavefunction.hpp:84
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:627
Dirac operators: TensorOperator base class and derived implementations for single-particle (one-body)...
Definition SecondOrder.hpp:7
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:156
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:638