16 #include "Eigen/Dense"
19 #include "smash/logging.h"
23 static constexpr
int LTmn = LogArea::Tmn::id;
26 using Eigen::Matrix4d;
27 using Eigen::Vector4d;
51 logg[
LTmn].debug(
"Looking for Landau frame for T_{mu}^{nu} ", A);
52 Eigen::EigenSolver<Matrix4d> es(A);
54 Vector4d eig_im = es.eigenvalues().imag();
55 Vector4d eig_re = es.eigenvalues().real();
56 size_t i_maxeigenvalue = 0;
57 for (
size_t i = 0; i < 4; i++) {
58 if (eig_re(i_maxeigenvalue) < eig_re(i)) {
68 if (i_maxeigenvalue != 0) {
70 "The Tmn diagonalization code previously relied on assumption that"
71 " 0th eigenvalue is the largest one. It seems to be always fulfilled "
72 "in practice, but not guaranteed by Eigen. Here is Tmn * gmn, ",
73 A,
" for which it is not fulfilled. Please let Dima(oliiny) know.");
75 for (
size_t i = 0; i < 4; i++) {
77 logg[
LTmn].error(
"Tmn*gmn\n ", A,
"\n has a complex eigenvalue ",
78 eig_re(i),
" + i * ", eig_im(i));
82 "\nenergy density eigenvalue is not positive ",
83 eig_re(i),
" + i * ", eig_im(i));
84 logg[
LTmn].error(
"i_max = ", i_maxeigenvalue);
87 logg[
LTmn].error(
"Tmn*gmn\n", A,
"\npressure eigenvalue is not negative ",
88 eig_re(i),
" + i * ", eig_im(i));
92 Vector4d tmp = es.eigenvectors().col(i_maxeigenvalue).real();
100 const double u_sqr = u.
sqr();
102 u /= std::sqrt(u_sqr);
105 "Landau frame is not defined.",
" Eigen vector", u,
" of ", A,
106 " is not time-like and",
107 " cannot be 4-velocity. This may happen if energy-momentum",
108 " tensor was constructed for a massless particle.");
115 using Eigen::Matrix4d;
127 L << u[0], u[1], u[2], u[3],
128 u[1], u[1] * tmp.
x1() + 1.0, u[2] * tmp.
x1(), u[3] * tmp.
x1(),
129 u[2], u[1] * tmp.
x2(), u[2] * tmp.
x2() + 1.0, u[3] * tmp.
x2(),
130 u[3], u[1] * tmp.
x3(), u[2] * tmp.
x3(), u[3] * tmp.
x3() + 1.0;
136 R(1, 1),
R(1, 2),
R(1, 3),
148 Tmn_[4] += mom[1] * tmp.
x1();
149 Tmn_[5] += mom[1] * tmp.
x2();
150 Tmn_[6] += mom[1] * tmp.
x3();
151 Tmn_[7] += mom[2] * tmp.
x2();
152 Tmn_[8] += mom[2] * tmp.
x3();
153 Tmn_[9] += mom[3] * tmp.
x3();
164 for (
size_t mu = 0; mu < 4; mu++) {
165 for (
size_t nu = 0; nu < 4; nu++) {
166 out << std::setprecision(3) << std::setw(12) << std::fixed
The EnergyMomentumTensor class represents a symmetric positive semi-definite energy-momentum tensor .
EnergyMomentumTensor boosted(const FourVector &u) const
Boost to a given 4-velocity.
FourVector landau_frame_4velocity() const
Find the Landau frame 4-velocity from energy-momentum tensor.
tmn_type Tmn_
The internal storage of the components.
EnergyMomentumTensor()
Default constructor (nulls all components)
static std::int8_t tmn_index(std::int8_t mu, std::int8_t nu)
Access the index of component .
void add_particle(const FourVector &mom)
Given momentum of the particle adds to the energy momentum tensor.
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
double sqr() const
calculate the square of the vector (which is a scalar)
ThreeVector threevec() const
ParticleData contains the dynamic information of a certain particle.
The ThreeVector class represents a physical three-vector with the components .
@ Tmn
Energy-momentum tensor in lab frame.
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > & logg
An array that stores all pre-configured Logger objects.
#define GCC_IGNORE_END()
Non-GCC compilers: fallback empty macro.
#define GCC_IGNORE_BEGIN(warning)
Non-GCC compilers: fallback empty macro.
static constexpr int LTmn
constexpr double really_small
Numerical error tolerance.
Generic numerical functions.