ampsci
High-precision calculations for one- and two-valence atomic systems
DiracOperator Namespace Reference

Detailed Description

Dirac operators: TensorOperator base class and derived implementations for single-particle (one-body) spherical tensor operators.

This namespace contains the TensorOperator base class and all derived operator classes. Operators act on DiracSpinor objects and compute reduced matrix elements (RMEs) of the form:

\[ \langle a \| \hat{h} \| b \rangle = A_{ab} \cdot R_{ab} \]

where \( A_{ab} \) is a purely angular factor and \( R_{ab} \) is a radial integral. New operators are implemented by deriving from TensorOperator (or ScalarOperator for rank-0 operators) and overriding the relevant virtual functions; see TensorOperator for details.

Operators are typically constructed via generate(), which takes a name string and an InputBlock; see GenerateOperator.hpp for the full list of available operators.

See TensorOperator class documentation for main descriptions. All usable tensor operators dervive from that virtual class.

From the command line, use

ampsci -o

to get a list of available operators. For a specific operator 'OperatorName', use:

ampsci -o OperatorName

to see available run-time options for that operator. These options are passed to generate().

Note
New operator classes must be registered in the operator_list in GenerateOperator.hpp to be accessible at runtime.

Namespaces

namespace  Hyperfine
 Auxillary Functions for hyperfine operatrs; F(r) [nuclear distribution] and similar.
 
namespace  multipole
 Helper functions for the multipole operators.
 

Classes

class  AEk
 Axial electric multipole operator: \( A^E_K = T^{(+1)}_K(q)\gamma^5 \). More...
 
class  AEk_lowq
 Low qr form of Axial electric multipole operator: \( A^E_K = T^{(+1)}_K(q)\gamma^5\). More...
 
class  ALk
 Axial longitudinal multipole operator: \( A^L_K = T^{(-1)}_K(q)\gamma^5 \). More...
 
class  ALk_lowq
 Low qr form of Axial longitudinal multipole operator: \( A^L_K = T^{(-1)}_K(q)\gamma^5\). More...
 
class  AMk
 Axial magnetic multipole operator: \( A^M_K = T^{(0)}_K(q)\gamma^5 \). More...
 
class  AMk_lowq
 Low qr form of Axial magnetic multipole operator: \( A^M_K = T^{(0)}_K(q)\gamma^5\). More...
 
class  E1
 Electric dipole operator: -|e|r = -er. More...
 
class  E1v
 Electric dipole operator, v-form: \( \frac{ie}{\omega \alpha} \vec{\alpha}\). More...
 
class  Ek
 E^k (electric multipole) operator, length form, with (qr<<1) approximation. More...
 
class  EM_multipole
 Intermediate abstract base class for all EM relativistic multipole operators. More...
 
class  fieldshift
 Field shift operator: dV = V(r, nuc2) - V(r, nuc1) More...
 
class  g0jL
 Matrix element of tensor operator: gamma^0 J_L(qr) C^L. More...
 
class  hfs
 Generalised hyperfine-structure operator, including relevant nuclear moment. More...
 
class  ig0g5jL
 Matrix element of tensor operator: i gamma^0gamma^5 J_L(qr) C^L. nb: i makes ME real. More...
 
class  ig5jL
 Matrix element of tensor operator: i gamma^5 J_L(qr) C^L. nb: i makes ME real. More...
 
class  j
 j (total angular momentum) operator More...
 
class  jL
 Matrix element of tensor operator: J_L(qr)*C^L. More...
 
class  l
 l (orbital angular momentum) operator More...
 
class  M1
 Magnetic dipole operator: <a||M1||b> More...
 
class  M1nr
 Magnetic dipole operator, in non-relativistic form: M1 = L + 2S. More...
 
class  MLVP
 Magnetic loop vacuum polarisation (Uehling vertex) More...
 
class  NullOperator
 Speacial operator: 0. More...
 
class  p
 Momentum operator p = -i grad. More...
 
class  Phi5k
 Temporal component of the axial vector multipole operator. More...
 
class  Phi5k_lowq
 Low qr form of Temporal component of the axial vector multipole operator: \( \Theta_K = \Phi^5_K = t^K(q)\gamma^5\) . NOTE: If K=0, omega should be (ea-eb); for K=1 should be q = alpha*omega! More...
 
class  Phik
 Temporal component of the vector multipole operator: \( \Phi_K = t^K(q) \). More...
 
class  Phik_lowq
 Low qr form of Temporal component of the vector multipole operator: \( \Phi_K = t^K(q)\). More...
 
class  PNCnsi
 Nuclear-spin independent PNC operator (Qw) More...
 
class  PNCnsi_const
 PNC nuclear-spin-independent operator with uniform (constant) nuclear density. More...
 
class  RadialF
 General function of r, even scalar operator. More...
 
class  s
 s (spin) operator More...
 
class  S5k
 Pseudoscalar multipole operator: t^k (i g^0 g^5) More...
 
class  S5k_lowq
 Low qr form of Pseudoscalar multipole operator: \( P_K = S^5_K = t^K(q)(i\gamma^0\gamma^5)\) NOTE: If K=0, omega should be (ea-eb); for K=1 should be q = alpha*omega! More...
 
class  ScalarOperator
 Rank-0 (scalar) tensor operator; derives from TensorOperator with k=0. More...
 
class  sigma_r
 Odd-parity rank-0 operator with radial function r (sigma_r) More...
 
class  Sk
 Scalar multipole operator: \( S_K = t^K(q)\gamma^0 \). More...
 
class  Sk_lowq
 Low qr form of Scalar multipole operator: \( S_K = t^K(q)\gamma^0\). More...
 
class  TensorOperator
 General tensor operator (virtual base class); all single-particle (one-body) tenosor operators derive from this. More...
 
class  VEk
 Vector electric multipole (V-form) operator: \( V^E_K = T^{(+1)}_K(q) \). More...
 
class  VEk_Len
 Vector electric multipole (transition) operator, Length-form: ( \( T^{(+1),{\rm Len}}_K \) ). More...
 
class  VEk_lowq
 Low qr form of Vector electric. Only for K=1 (zero otherwise) More...
 
class  VertexQED
 Effective VertexQED operator. More...
 
class  VLk
 Vector longitudinal multipole operator (V-form): \( V^L_K = T^{(-1)}_K(q) \). More...
 
class  VLk_lowq
 Low qr form of Vector longitudinal. More...
 
class  VMk
 Vector magnetic multipole operator: \( V^M_K = T^{(0)}_K(q) \). More...
 
class  VMk_lowq
 Low qr form of Vector magnetic. Only for K=1 (zero otherwise) More...
 
class  Vrad
 Flambaum-Ginges radiative potential operator. More...
 

Enumerations

enum class  Parity { even , odd , Error }
 Parity of operator. More...
 
enum class  Realness { real , imaginary , Error }
 Specifies whether an operator's matrix elements are real or imaginary. More...
 
enum class  MatrixElementType { Reduced , Stretched , HFConstant , Error }
 Type of matrix element returned. More...
 

Functions

std::unique_ptr< DiracOperator::TensorOperatorgenerate (std::string_view operator_name, const IO::InputBlock &input, const Wavefunction &wf)
 Returns a unique_ptr (polymorphic) to the requested operator, with given properties.
 
void list_operators ()
 List available operators.
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_sigma_r (const IO::InputBlock &input, const Wavefunction &wf)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_E1 (const IO::InputBlock &input, const Wavefunction &wf)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_E1v (const IO::InputBlock &input, const Wavefunction &wf)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_E2 (const IO::InputBlock &input, const Wavefunction &wf)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_ialpha (const IO::InputBlock &input, const Wavefunction &)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_Ek (const IO::InputBlock &input, const Wavefunction &wf)
 
std::unique_ptr< DiracOperator::TensorOperatorMultipoleOperator (const Grid &grid, int k, double omega, char type, char comp, bool low_q, const SphericalBessel::JL_table *jl=nullptr)
 Factory for relativistic multipole operators.
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_Multipole (const IO::InputBlock &input, const Wavefunction &wf)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_fieldshift (const IO::InputBlock &input, const Wavefunction &wf)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_hfs (const IO::InputBlock &input, const Wavefunction &wf)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_l (const IO::InputBlock &input, const Wavefunction &)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_s (const IO::InputBlock &input, const Wavefunction &)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_M1 (const IO::InputBlock &input, const Wavefunction &wf)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_M1nr (const IO::InputBlock &input, const Wavefunction &)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_p (const IO::InputBlock &input, const Wavefunction &)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_pnc (const IO::InputBlock &input, const Wavefunction &wf)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_Vrad (const IO::InputBlock &input, const Wavefunction &wf)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_MLVP (const IO::InputBlock &input, const Wavefunction &wf)
 
std::unique_ptr< DiracOperator::TensorOperatorgenerate_r (const IO::InputBlock &input, const Wavefunction &wf)
 
double Pab (double pm, const std::vector< double > &t, const DiracSpinor &Fa, const DiracSpinor &Fb)
 Pab function: Int[ (fa*gb + pm*ga*fb) * t(r) , dr]. pm = +/-1 (usually)
 
double Rab (double pm, const std::vector< double > &t, const DiracSpinor &Fa, const DiracSpinor &Fb)
 Rab function: Int[ (fa*fb + pm*ga*gb) * t(r) , dr]. pm = +/-1 (usually)
 
void Pab_rhs (double pm, const std::vector< double > &t, DiracSpinor *dF, const DiracSpinor &Fb, double A=1.0)
 Pab_rhs function: dF_ab += A * t(r) * (g, pm*f) , pm=+/-1 (usually). NOTE: uses +=, so can combine. Ensure empty to begin.
 
void Rab_rhs (double pm, const std::vector< double > &t, DiracSpinor *dF, const DiracSpinor &Fb, double A=1.0)
 Rab_rhs function: dF_ab += A * t(r) * (f, pm*g) , pm=+/-1 (usually). NOTE: uses +=, so can combine. Ensure empty to begin.
 
double Vab (const std::vector< double > &t, const DiracSpinor &Fa, const DiracSpinor &Fb)
 Vab function: Int[ (fa*gb ) * t(r) , dr].
 
double Wab (const std::vector< double > &t, const DiracSpinor &Fa, const DiracSpinor &Fb)
 Wab function: Int[ (ga*fb ) * t(r) , dr].
 
double Gab (const std::vector< double > &t, const DiracSpinor &Fa, const DiracSpinor &Fb)
 Gab function: Int[ (ga*gb ) * t(r) , dr].
 
void Gab_rhs (const std::vector< double > &t, DiracSpinor *dF, const DiracSpinor &Fb, double a)
 Gab_rhs function: dF += a * t(r) * (0, g_b). NOTE: uses +=, so can combine.
 
double Gab (const DiracSpinor &Fa, const DiracSpinor &Fb)
 Gab = Int[ ga*gb , dr] - (just relativistic correction part of integral)
 
void Gab_rhs (DiracSpinor *dF, const DiracSpinor &Fb, double a)
 Gab_rhs(r) += a*g_b(r). Note: uses += so may be sumulative.
 
double Pab (double pm, const DiracSpinor &Fa, const DiracSpinor &Fb)
 Pab[1] function: Int[ (fa*gb + pm*ga*fb) , dr]. pm = +/-1 (usually)
 
double Rab (double pm, const DiracSpinor &Fa, const DiracSpinor &Fb)
 Rab[1] function: Int[ (fa*fb + pm*ga*gb) , dr] = Int[ (pm-1)*ga*gb) , dr]. NOTE: assumes NOT diagonal, using orthogonality condition.
 
void Pab_rhs (double pm, DiracSpinor *dF, const DiracSpinor &Fb, double A=1.0)
 Pab_rhs[1] function: dF_ab += A * (g, pm*f) , pm=+/-1 (usually).
 
void Rab_rhs (double pm, DiracSpinor *dF, const DiracSpinor &Fb, double A=1.0)
 Rab_rhs[1] function: dF_ab += A * (f, pm*g) = dF_ab += A * (0, (pm-1)*g). NOTE: assumes NOT diagonal, using orthogonality condition.
 
Parity parse_Parity (const std::string &s)
 Convert string to Parity.
 
std::string parse_Parity (Parity p)
 Convert Parity to string.
 
Realness parse_Realness (const std::string &s)
 Convert string to Realness.
 
std::string parse_Realness (Realness r)
 Convert Realness to string.
 
MatrixElementType parse_MatrixElementType (const std::string &s)
 Convert string to MatrixElementType.
 
std::string parse_MatrixElementType (MatrixElementType t)
 Convert MatrixElementType to string.
 

Variables

brief i vec
 

Enumeration Type Documentation

◆ Parity

enum class DiracOperator::Parity
strong

Parity of operator.

◆ Realness

enum class DiracOperator::Realness
strong

Specifies whether an operator's matrix elements are real or imaginary.

Operators must have purely real or purely imaginary reduced matrix elements. For imaginary operators, the imaginary part is computed and stored; the real part is identically zero. This distinction affects the Hermitian symmetry relation \( \langle b \| \hat{h} \| a \rangle = \pm \langle a \| \hat{h} \| b \rangle^* \) and the sign of \( \langle b \| \hat{h} \| a \rangle \) relative to \( \langle a \| \hat{h} \| b \rangle \) .

◆ MatrixElementType

Type of matrix element returned.

Specifies which form of matrix element is used or returned.

@value Reduced : Reduced matrix element @value Stretched : Matrix element for stretched states (m = j) @value HFConstant : Hyperfine (A,B,C...) constant

For off-diagonal, j:=min(ja,jb)

Function Documentation

◆ generate()

std::unique_ptr< DiracOperator::TensorOperator > DiracOperator::generate ( std::string_view  operator_name,
const IO::InputBlock input,
const Wavefunction wf 
)

Returns a unique_ptr (polymorphic) to the requested operator, with given properties.

From the command line, use

ampsci -o

to get a list of available operators. For a specific operator 'OperatorName', use:

ampsci -o OperatorName

to see available run-time options for that operator.

◆ list_operators()

void DiracOperator::list_operators ( )

List available operators.

◆ MultipoleOperator()

std::unique_ptr< DiracOperator::TensorOperator > DiracOperator::MultipoleOperator ( const Grid grid,
int  k,
double  omega,
char  type,
char  comp,
bool  low_q,
const SphericalBessel::JL_table jl = nullptr 
)

Factory for relativistic multipole operators.

Constructs and returns a specific multipole operator derived from DiracOperator::TensorOperator, based on the requested Lorentz structure, multipole component, and momentum-transfer regime.

These are the \( t^K_Q \tilde\gamma \), \( T^{(\sigma)}_{KQ} \tilde\gamma \) operators from the vector expansion:

\[ \begin{align} e^{i\vec{q}\cdot\vec{r}} &= \sqrt{4\pi}\sum_{KQ}\sqrt{[K]} \, i^K \, {Y^*_{KQ}}{(\hat q)} \, t^K_Q(q,r),\\ \vec{\alpha} \, e^{i\vec{q}\cdot\vec{r}} & = \sqrt{4\pi} \sum_{KQ\sigma} \sqrt{[K]} \, i^{K-\sigma} \, \vec{Y}_{KQ}^{(\sigma)*}(\hat{{q}}) \, T^{(\sigma)}_{KQ}. \end{align} \]

The operator corresponds to a spherical multipole of rank k with frequency/energy transfer omega. The type and component determine the Lorentz structure and spatial character of the interaction.

These are "frequency"-dependent operators, via momentum transfer, q. For electromagnetic interactions, \( \omega = q c\). The "updateFrequency()" function expects these units, so even when momentum transfer is not equal to energy exchange, we should pass \( qc \) to this function.

Parameters
gridRadial grid on which the operator acts.
kMultipole rank (total angular momentum of the operator).
omegaEnergy (frequency) transfer.
typeInteraction type:
  • 'V' : Vector
  • 'A' : Axial-vector
  • 'S' : Scalar
  • 'P' : Pseudoscalar
compMultipole component (for V/A types):
  • 'E' : Electric
  • 'M' : Magnetic
  • 'L' : Longitudinal
  • 'T' : Temporal [caution - NOT transverse!] (Ignored for scalar and pseudoscalar operators.)
low_qIf true, construct the low-momentum (long-wavelength) approximation of the operator.
jlOptional pointer to a precomputed spherical Bessel table. If provided, radial Bessel functions are taken from this table to avoid recomputation. If nullptr, they are generated internally as needed.
Returns
A std::unique_ptr to the requested TensorOperator.
Note
Length-form electric operators (if implemented separately) are only valid for vector-electric ('V','E') combinations.
Warning
Invalid combinations of type and comp may result in a nullptr being returned.

◆ Pab() [1/2]

double DiracOperator::Pab ( double  pm,
const std::vector< double > &  t,
const DiracSpinor Fa,
const DiracSpinor Fb 
)

Pab function: Int[ (fa*gb + pm*ga*fb) * t(r) , dr]. pm = +/-1 (usually)

Note: does not know selection rules, so only evaluate if non-zero

◆ Rab() [1/2]

double DiracOperator::Rab ( double  pm,
const std::vector< double > &  t,
const DiracSpinor Fa,
const DiracSpinor Fb 
)

Rab function: Int[ (fa*fb + pm*ga*gb) * t(r) , dr]. pm = +/-1 (usually)

Note: does not know selection rules, so only evaluate if non-zero

◆ Pab_rhs() [1/2]

void DiracOperator::Pab_rhs ( double  pm,
const std::vector< double > &  t,
DiracSpinor dF,
const DiracSpinor Fb,
double  A = 1.0 
)

Pab_rhs function: dF_ab += A * t(r) * (g, pm*f) , pm=+/-1 (usually). NOTE: uses +=, so can combine. Ensure empty to begin.

Note: does not know selection rules, so only evaluate if non-zero. Should have Fa*Pab_rhs = A * Pab.

◆ Rab_rhs() [1/2]

void DiracOperator::Rab_rhs ( double  pm,
const std::vector< double > &  t,
DiracSpinor dF,
const DiracSpinor Fb,
double  A = 1.0 
)

Rab_rhs function: dF_ab += A * t(r) * (f, pm*g) , pm=+/-1 (usually). NOTE: uses +=, so can combine. Ensure empty to begin.

Note: does not know selection rules, so only evaluate if non-zero. Should have Fa*Rab_rhs = A * Rab.

◆ Vab()

double DiracOperator::Vab ( const std::vector< double > &  t,
const DiracSpinor Fa,
const DiracSpinor Fb 
)

Vab function: Int[ (fa*gb ) * t(r) , dr].

◆ Wab()

double DiracOperator::Wab ( const std::vector< double > &  t,
const DiracSpinor Fa,
const DiracSpinor Fb 
)

Wab function: Int[ (ga*fb ) * t(r) , dr].

◆ Gab() [1/2]

double DiracOperator::Gab ( const std::vector< double > &  t,
const DiracSpinor Fa,
const DiracSpinor Fb 
)

Gab function: Int[ (ga*gb ) * t(r) , dr].

◆ Gab_rhs() [1/2]

void DiracOperator::Gab_rhs ( const std::vector< double > &  t,
DiracSpinor dF,
const DiracSpinor Fb,
double  a 
)

Gab_rhs function: dF += a * t(r) * (0, g_b). NOTE: uses +=, so can combine.

◆ Gab() [2/2]

double DiracOperator::Gab ( const DiracSpinor Fa,
const DiracSpinor Fb 
)

Gab = Int[ ga*gb , dr] - (just relativistic correction part of integral)

◆ Gab_rhs() [2/2]

void DiracOperator::Gab_rhs ( DiracSpinor dF,
const DiracSpinor Fb,
double  a 
)

Gab_rhs(r) += a*g_b(r). Note: uses += so may be sumulative.

◆ Pab() [2/2]

double DiracOperator::Pab ( double  pm,
const DiracSpinor Fa,
const DiracSpinor Fb 
)

Pab[1] function: Int[ (fa*gb + pm*ga*fb) , dr]. pm = +/-1 (usually)

◆ Rab() [2/2]

double DiracOperator::Rab ( double  pm,
const DiracSpinor Fa,
const DiracSpinor Fb 
)

Rab[1] function: Int[ (fa*fb + pm*ga*gb) , dr] = Int[ (pm-1)*ga*gb) , dr]. NOTE: assumes NOT diagonal, using orthogonality condition.

◆ Pab_rhs() [2/2]

void DiracOperator::Pab_rhs ( double  pm,
DiracSpinor dF,
const DiracSpinor Fb,
double  a 
)

Pab_rhs[1] function: dF_ab += A * (g, pm*f) , pm=+/-1 (usually).

◆ Rab_rhs() [2/2]

void DiracOperator::Rab_rhs ( double  pm,
DiracSpinor dF,
const DiracSpinor Fb,
double  a 
)

Rab_rhs[1] function: dF_ab += A * (f, pm*g) = dF_ab += A * (0, (pm-1)*g). NOTE: assumes NOT diagonal, using orthogonality condition.

◆ parse_Parity() [1/2]

Parity DiracOperator::parse_Parity ( const std::string &  s)

Convert string to Parity.

◆ parse_Parity() [2/2]

std::string DiracOperator::parse_Parity ( Parity  p)

Convert Parity to string.

◆ parse_Realness() [1/2]

Realness DiracOperator::parse_Realness ( const std::string &  s)

Convert string to Realness.

◆ parse_Realness() [2/2]

std::string DiracOperator::parse_Realness ( Realness  r)

Convert Realness to string.

◆ parse_MatrixElementType() [1/2]

MatrixElementType DiracOperator::parse_MatrixElementType ( const std::string &  s)

Convert string to MatrixElementType.

◆ parse_MatrixElementType() [2/2]

std::string DiracOperator::parse_MatrixElementType ( MatrixElementType  t)

Convert MatrixElementType to string.

Variable Documentation

◆ vec

brief i DiracOperator::vec
Initial value:
{\alpha} matrix element: propto Electric dipole operator.
i factored so that ME is real
class ialpha final : public TensorOperator {
public:
ialpha() : TensorOperator(1, Parity::odd, 1.0, {}, Realness::real, true) {}
std::string name() const override final { return "i*alpha"; }
std::string units() const override final { return "au"; }
double angularF(const int ka, const int kb) const override final {
return Angular::Ck_kk(1, ka, kb);
}
double angularCff(int, int) const override final { return 0; }
double angularCgg(int, int) const override final { return 0; }
double angularCfg(int ka, int kb) const override final { return ka - kb - 1; }
double angularCgf(int ka, int kb) const override final { return ka - kb + 1; }
}
General tensor operator (virtual base class); all single-particle (one-body) tenosor operators derive...
Definition TensorOperator.hpp:197
virtual double angularCgf(int, int) const
Angular coefficient C_gf for the g_a*f_b term of the radial integral.
Definition TensorOperator.hpp:380
virtual std::string units() const
Returns units of operator as a string (usually au, may be MHz, etc.)
Definition TensorOperator.hpp:341
virtual double angularF(const int, const int) const =0
Angular factor A_ab linking the radial integral to the RME.
virtual double angularCfg(int, int) const
Angular coefficient C_fg for the f_a*g_b term of the radial integral.
Definition TensorOperator.hpp:378
virtual std::string name() const
Returns "name" of operator (e.g., 'E1')
Definition TensorOperator.hpp:339
virtual double angularCgg(int, int) const
Angular coefficient C_gg for the g_a*g_b term of the radial integral.
Definition TensorOperator.hpp:376
virtual double angularCff(int kappa_a, int kappa_b) const
Angular coefficient C_ff for the f_a*f_b term of the radial integral.
Definition TensorOperator.hpp:371
double Ck_kk(int k, int ka, int kb)
Reduced relativistic angular ME: <ka||C^k||kb>. Takes kappa values.
Definition Wigner369j.hpp:486
Parity
Parity of operator.
Definition TensorOperator.hpp:57