Tensorium
Loading...
Searching...
No Matches
Metric.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "../Core/Tensor.hpp"
4#include "../Core/Vector.hpp"
5#include <cassert>
6#include <cmath>
7#include <functional>
8#include <iostream>
9#include <stdexcept>
10#include <string>
11namespace tensorium_RG {
27template <typename T> class Metric {
28 public:
29 std::string type;
30 T M = T(1.0);
31 T a = T(0.935);
32
39 Metric(const std::string &metric_type = "minkowski", T mass = T(1.0), T spin = T(0.0))
40 : type(metric_type),
41 M(mass),
42 a(spin) {}
53 if (type == "minkowski") {
55 } else if (type == "schwarzschild") {
57 } else if (type == "kerr") {
58 compute_kerr(X, g);
59 } else if (type == "flrw") {
60 compute_flrw(X, g);
61 } else if (type == "kerr_schild") {
63 } else if (type == "custom" && custom_metric_fn) {
65 } else {
66 throw std::invalid_argument("Unknown metric type: " + type);
67 }
68 }
69
85 assert(X.size() == 4);
87 (*this)(X, g);
88
89 alpha = std::sqrt(-g({0, 0}));
90
91 beta.resize(3);
92 for (size_t i = 0; i < 3; ++i)
93 beta(i) = g(0, i + 1);
94
95 gamma.resize(3, 3);
96 for (size_t i = 0; i < 3; ++i)
97 for (size_t j = 0; j < 3; ++j)
98 gamma(i, j) = g(i + 1, j + 1);
99 }
100
102 assert(gamma.dimensions[0] == 3 && gamma.dimensions[1] == 3);
103 T det = gamma(0, 0) * (gamma(1, 1) * gamma(2, 2) - gamma(1, 2) * gamma(2, 1)) -
104 gamma(0, 1) * (gamma(1, 0) * gamma(2, 2) - gamma(1, 2) * gamma(2, 0)) +
105 gamma(0, 2) * (gamma(1, 0) * gamma(2, 1) - gamma(1, 1) * gamma(2, 0));
106 return std::pow(det, -1.0 / 3.0);
107 }
108
110 tensorium::Tensor<T, 2> &gamma_tilde) const {
111 gamma_tilde.resize(3, 3);
112 for (size_t i = 0; i < 3; ++i)
113 for (size_t j = 0; j < 3; ++j)
114 gamma_tilde(i, j) = chi * gamma(i, j);
115 }
116
117 private:
122 nullptr;
123
127 void
128 set_custom(std::function<void(const tensorium::Vector<T> &, tensorium::Tensor<T, 2> &)> fn) {
129 custom_metric_fn = std::move(fn);
130 type = "custom";
131 }
132
135 const size_t dim = 4;
136 g.resize(dim, dim);
137 g.fill(T(0));
138 g(0, 0) = T(-1);
139 g(1, 1) = T(1);
140 g(2, 2) = T(1);
141 g(3, 3) = T(1);
142 }
143
146 assert(X.size() == 4);
147 const T r = X(1);
148 const T theta = X(2);
149 const T sin_theta = std::sin(theta);
150 const T f = T(1) - T(2) * M / r;
151
152 g.resize(4, 4);
153 g.fill(T(0));
154 g(0, 0) = -f;
155 g(1, 1) = T(1) / f;
156 g(2, 2) = r * r;
157 g(3, 3) = r * r * sin_theta * sin_theta;
158 }
159
162 assert(X.size() == 4);
163 const T r = X(1);
164 const T theta = X(2);
165 const T sin_theta = std::sin(theta);
166 const T cos_theta = std::cos(theta);
167 const T sin2 = sin_theta * sin_theta;
168
169 const T Sigma = r * r + a * a * cos_theta * cos_theta;
170 const T Delta = r * r - T(2) * M * r + a * a;
171
172 g.resize({4, 4});
173 g.fill(T(0));
174
175 g(0, 0) = -(T(1) - (T(2) * M * r) / Sigma);
176 g(0, 3) = g(3, 0) = -T(2) * M * r * a * sin2 / Sigma;
177 g(1, 1) = Sigma / Delta;
178 g(2, 2) = Sigma;
179 g(3, 3) = (r * r + a * a + T(2) * M * r * a * a * sin2 / Sigma) * sin2;
180 }
181
184 assert(X.size() == 4);
185 const T t = X(0);
186 const T r = X(1);
187 const T theta = X(2);
188 const T sin_theta = std::sin(theta);
189
190 const T a_t = std::pow(t, T(2.0) / T(3.0));
191
192 g.resize(4, 4);
193 g.fill(T(0));
194
195 g(0, 0) = T(-1);
196 g(1, 1) = a_t * a_t;
197 g(2, 2) = a_t * a_t * r * r;
198 g(3, 3) = a_t * a_t * r * r * sin_theta * sin_theta;
199 }
200
202 T kerr_schild_radius(T x, T y, T z) const {
203 const T r2 = x * x + y * y + z * z;
204 const T a2 = a * a;
205 const T term = std::sqrt((r2 - a2) * (r2 - a2) + 4 * a2 * z * z);
206 const T r = std::sqrt(0.5 * (r2 - a2 + term));
207 return r;
208 }
209
212 assert(X.size() == 4);
213 const T x = X(1), y = X(2), z = X(3);
214
215 const T r = kerr_schild_radius(x, y, z);
216 const T cos_theta = (r > 1e-14) ? z / r : 0.0;
217 const T denom = r * r + a * a * cos_theta * cos_theta;
218 const T H = (denom > 1e-14) ? (M * r) / denom : 0.0;
219
220 const T denom_vec = r * r + a * a;
221 T lx = (denom_vec > 1e-14) ? (r * x + a * y) / denom_vec : 0.0;
222 T ly = (denom_vec > 1e-14) ? (r * y - a * x) / denom_vec : 0.0;
223 T lz = (r > 1e-14) ? z / r : 0.0;
224
225 T norm_l = std::sqrt(lx * lx + ly * ly + lz * lz);
226 if (norm_l > 1e-14) {
227 lx /= norm_l;
228 ly /= norm_l;
229 lz /= norm_l;
230 }
231
232 g.resize({4, 4});
233 g.fill(0);
234
235 g(0, 0) = -1.0;
236 g(1, 1) = 1.0;
237 g(2, 2) = 1.0;
238 g(3, 3) = 1.0;
239
240 const std::array<T, 4> l = {1.0, lx, ly, lz};
241
242 for (size_t mu = 0; mu < 4; ++mu)
243 for (size_t nu = 0; nu < 4; ++nu)
244 g(mu, nu) += 2.0 * H * l[mu] * l[nu];
245 }
246};
247} // namespace tensorium_RG
static FrontendPluginRegistry::Add< TensoriumPluginAction > X("tensorium-dispatch", "Handle #pragma tensorium directives")
Register the plugin under the name "tensorium-dispatch".
Multi-dimensional tensor class with fixed rank and SIMD support.
Definition Tensor.hpp:25
void resize(const std::array< size_t, Rank > &dims)
Resize 2D tensor.
Definition Tensor.hpp:70
void fill(K value)
Fill tensor with a constant value.
Definition Tensor.hpp:125
A callable 4D metric class for general relativity (Minkowski, Schwarzschild, Kerr,...
Definition Metric.hpp:27
void compute_schwarzschild(const tensorium::Vector< T > &X, tensorium::Tensor< T, 2 > &g) const
Schwarzschild metric in spherical coordinates.
Definition Metric.hpp:145
void set_custom(std::function< void(const tensorium::Vector< T > &, tensorium::Tensor< T, 2 > &)> fn)
Set a custom metric callable function.
Definition Metric.hpp:128
void compute_flrw(const tensorium::Vector< T > &X, tensorium::Tensor< T, 2 > &g) const
Flat FLRW metric in comoving spherical coordinates.
Definition Metric.hpp:183
void compute_conformal_metric(const tensorium::Tensor< T, 2 > &gamma, T chi, tensorium::Tensor< T, 2 > &gamma_tilde) const
Definition Metric.hpp:109
T a
Definition Metric.hpp:31
void operator()(const tensorium::Vector< T > &X, tensorium::Tensor< T, 2 > &g) const
Evaluate the metric tensor .
Definition Metric.hpp:52
T compute_conformal_factor(const tensorium::Tensor< T, 2 > &gamma) const
Definition Metric.hpp:101
std::function< void(const tensorium::Vector< T > &, tensorium::Tensor< T, 2 > &) custom_metric_fn)
Optional user-defined metric function (must accept X and fill g)
Definition Metric.hpp:121
std::string type
Definition Metric.hpp:29
void BSSN(const tensorium::Vector< T > &X, T &alpha, tensorium::Vector< T > &beta, tensorium::Tensor< T, 2 > &gamma) const
Extract BSSN 3+1 variables (lapse, shift, and spatial metric)
Definition Metric.hpp:83
Metric(const std::string &metric_type="minkowski", T mass=T(1.0), T spin=T(0.0))
Constructor.
Definition Metric.hpp:39
void compute_kerr_schild(const tensorium::Vector< T > &X, tensorium::Tensor< T, 2 > &g) const
Kerr–Schild metric in Cartesian coordinates.
Definition Metric.hpp:211
T M
Definition Metric.hpp:30
void compute_minkowski(tensorium::Tensor< T, 2 > &g) const
Minkowski metric in Cartesian coordinates.
Definition Metric.hpp:134
void compute_kerr(const tensorium::Vector< T > &X, tensorium::Tensor< T, 2 > &g) const
Kerr metric in Boyer–Lindquist coordinates.
Definition Metric.hpp:161
T kerr_schild_radius(T x, T y, T z) const
Kerr–Schild radius extraction helper.
Definition Metric.hpp:202
Definition BSSNAtildeTensor.hpp:10