Tensorium
Loading...
Searching...
No Matches
ChristoffelSymbol.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "../Core/Matrix.hpp"
4#include "../Core/Tensor.hpp"
5#include "../Core/Vector.hpp"
9#include "../SIMD/SIMD.hpp"
10#include "Metric.hpp"
11#include <array>
12#include <cassert>
13#include <cmath>
14#include <functional>
15#include <iomanip>
16#include <iostream>
17#include <stdexcept>
18#include <vector>
19
20namespace tensorium_RG {
40template <typename T> class ChristoffelSym {
41 public:
43 static constexpr size_t rank = 4;
44 size_t dim;
49 ChristoffelSym(size_t dim) : dim(dim), data(dim * dim * dim * dim, T(0)) {}
50
54 T &operator()(size_t i, size_t j, size_t k, size_t l) {
55 assert(i < dim && j < dim && k < dim && l < dim);
56 return data[i * dim * dim * dim + j * dim * dim + k * dim + l];
57 }
58
62 const T &operator()(size_t i, size_t j, size_t k, size_t l) const {
63 return data[i * dim * dim * dim + j * dim * dim + k * dim + l];
64 }
69 void fill(T value) { std::fill(data.begin(), data.end(), value); }
70
75 void print() const {
76 for (size_t l = 0; l < dim; ++l) {
77 if (l != 0)
78 continue;
79 std::cout << "Γ^" << l << "_{μν} :\n";
80 for (size_t i = 0; i < dim; ++i) {
81 for (size_t j = 0; j < dim; ++j) {
82 std::cout << std::setw(12) << std::setprecision(6) << std::fixed
83 << (*this)(l, i, j, 0) << " ";
84 }
85 std::cout << "\n";
86 }
87 std::cout << "\n";
88 }
89 }
102 __attribute__((always_inline, hot, flatten)) static inline ChristoffelSym<T>
103 compute_christoffel(const tensorium::Vector<T> &X, T h, const tensorium::Tensor<T, 2> &g,
104 const tensorium::Tensor<T, 2> &g_inv,
105 const std::function<void(const tensorium::Vector<T> &,
106 tensorium::Tensor<T, 2> &)> &metric_generator) {
107 const size_t dim = X.size();
109 ChristoffelSym<T> d_metric(dim);
110 gamma.fill(T(0));
111 d_metric.fill(T(0));
112
113 tensorium::Vector<T> Xh = X, Xl = X;
114 tensorium::Tensor<T, 2> gh({dim, dim}), gl({dim, dim});
115
116 for (size_t mu = 0; mu < dim; ++mu) {
117 Xh = X;
118 Xl = X;
119 Xh(mu) += h;
120 Xl(mu) -= h;
121
122 metric_generator(Xh, gh);
123 metric_generator(Xl, gl);
124
125 for (size_t nu = 0; nu < dim; ++nu)
126 for (size_t lam = 0; lam < dim; ++lam)
127 d_metric(lam, nu, mu, 0) = (gh(lam, nu) - gl(lam, nu)) / (T(2) * h);
128 }
129
131 tmp.fill(T(0));
132 for (size_t lam = 0; lam < dim; ++lam)
133 for (size_t nu = 0; nu < dim; ++nu)
134 for (size_t mu = 0; mu < dim; ++mu)
135 tmp(lam, nu, mu, 0) =
136 T(0.5) * (d_metric(nu, lam, mu, 0) + d_metric(mu, lam, nu, 0) -
137 d_metric(mu, nu, lam, 0));
138
139 for (size_t lam = 0; lam < dim; ++lam)
140 for (size_t nu = 0; nu < dim; ++nu)
141 for (size_t mu = 0; mu < dim; ++mu) {
142 T sum = T(0);
143 for (size_t kap = 0; kap < dim; ++kap)
144 sum += g_inv(lam, kap) * tmp(kap, nu, mu, 0);
145 gamma(lam, nu, mu, 0) = sum;
146 }
147
148 return gamma;
149 }
150};
160template <typename T>
161__attribute__((always_inline, hot, flatten)) inline tensorium::Tensor<T, 2>
162inv_mat_tensor_local(const tensorium::Tensor<T, 2> &g) {
163 const size_t d0 = g.dimensions[0];
164 const size_t d1 = g.dimensions[1];
165 tensorium::Matrix<T> mat({d0, d1});
166
167 for (size_t i = 0; i < d0; ++i)
168 for (size_t j = 0; j < d1; ++j)
169 mat(i, j) = g(i, j);
170
171 tensorium::Matrix<T> inv = mat.inverse();
172
173 tensorium::Tensor<T, 2> out({d0, d1});
174 for (size_t i = 0; i < d0; ++i)
175 for (size_t j = 0; j < d1; ++j)
176 out(i, j) = inv(i, j);
177
178 return out;
179}
195template <typename T>
196__attribute__((always_inline, hot, flatten)) inline void
197calculate_christoffel_at_offset(const tensorium::Vector<T> &X, int direction, T offset, T h,
200 const tensorium_RG::Metric<T> &metric) {
201 tensorium::Vector<T> X_offset = X;
202 X_offset(direction) += offset;
203
204 metric(X_offset, g);
205 g_inv = tensorium_RG::inv_mat_tensor_local(g);
206
207 Gamma_out = tensorium_RG::ChristoffelSym<T>::compute_christoffel(X_offset, h, g, g_inv, metric);
208}
209} // namespace tensorium_RG
std::vector< K, AlignedAllocator< K, ALIGN > > aligned_vector
Type alias for a std::vector with aligned memory allocation.
Definition Allocator.hpp:111
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
std::array< size_t, Rank > dimensions
Dimensions of the tensor (e.g., {4,4,4,4})
Definition Tensor.hpp:29
Stores and computes Christoffel symbols .
Definition ChristoffelSymbol.hpp:40
size_t dim
Definition ChristoffelSymbol.hpp:44
__attribute__((always_inline, hot, flatten)) static inline ChristoffelSym< T > compute_christoffel(const tensorium
Compute Christoffel symbols numerically from a metric.
Definition ChristoffelSymbol.hpp:102
T & operator()(size_t i, size_t j, size_t k, size_t l)
Mutable access to component .
Definition ChristoffelSymbol.hpp:54
aligned_vector< T > data
Definition ChristoffelSymbol.hpp:42
ChristoffelSym(size_t dim)
Construct a Christoffel symbol tensor.
Definition ChristoffelSymbol.hpp:49
const T & operator()(size_t i, size_t j, size_t k, size_t l) const
Const access to component .
Definition ChristoffelSymbol.hpp:62
void fill(T value)
Fill all components with a constant value.
Definition ChristoffelSymbol.hpp:69
void print() const
Print all non-zero Christoffel components to stdout.
Definition ChristoffelSymbol.hpp:75
static constexpr size_t rank
Definition ChristoffelSymbol.hpp:43
A callable 4D metric class for general relativity (Minkowski, Schwarzschild, Kerr,...
Definition Metric.hpp:27
Definition BSSNAtildeTensor.hpp:10
__attribute__((always_inline, hot, flatten)) inline tensorium
Compute the inverse of a 2D metric tensor using local matrix inversion.
Definition ChristoffelSymbol.hpp:161