Tensorium
Loading...
Searching...
No Matches
BSSNConstraintsSolver.hpp
Go to the documentation of this file.
1#pragma once
2
5#include "../Metric.hpp"
6#include <cassert>
7#include <cstddef>
8
9namespace tensorium_RG {
10template <typename T> class ConstraintSolver {
11 public:
25 const tensorium::Tensor<T, 5> &g_tilde_inv,
26 T dx, T dy, T dz, int max_iter = 1000,
27 T tol = T(1e-8)) {
28 std::array<size_t, 5> shp = Atilde.shape();
29 const size_t NX = shp[0];
30 const size_t NY = shp[1];
31 const size_t NZ = shp[2];
32
33 tensorium::Tensor<T, 3> psi({NX, NY, NZ});
34 for (size_t i = 0; i < NX; ++i) {
35 for (size_t j = 0; j < NY; ++j) {
36 for (size_t k = 0; k < NZ; ++k) {
37 psi({i, j, k}) = T(1);
38 }
39 }
40 }
41
42 const T inv_dx2 = T(1) / (dx * dx);
43 const T inv_dy2 = T(1) / (dy * dy);
44 const T inv_dz2 = T(1) / (dz * dz);
45 const T factor = T(1) / (T(2) * (inv_dx2 + inv_dy2 + inv_dz2));
46
47 for (int it = 0; it < max_iter; ++it) {
48 T max_diff = T(0);
49
50 for (size_t i = 1; i < NX - 1; ++i) {
51 for (size_t j = 1; j < NY - 1; ++j) {
52 for (size_t k = 1; k < NZ - 1; ++k) {
53 T lap =
54 inv_dx2 *
55 (psi({i + 1, j, k}) + psi({i - 1, j, k}) - T(2) * psi({i, j, k})) +
56 inv_dy2 *
57 (psi({i, j + 1, k}) + psi({i, j - 1, k}) - T(2) * psi({i, j, k})) +
58 inv_dz2 *
59 (psi({i, j, k + 1}) + psi({i, j, k - 1}) - T(2) * psi({i, j, k}));
60
61 T A2 = T(0);
62 for (int a = 0; a < 3; ++a) {
63 for (int b = 0; b < 3; ++b) {
64 for (int c = 0; c < 3; ++c) {
65 for (int d = 0; d < 3; ++d) {
66 T g1 = g_tilde_inv({i, j, k, (size_t)a, (size_t)c});
67 T g2 = g_tilde_inv({i, j, k, (size_t)b, (size_t)d});
68 T A3 = Atilde({i, j, k, (size_t)c, (size_t)d});
69 T A4 = Atilde({i, j, k, (size_t)a, (size_t)b});
70 A2 += g1 * g2 * A3 * A4;
71 }
72 }
73 }
74 }
75
76 T psi_ijk = std::fmax(psi({i, j, k}), T(1e-8));
77 T rhs = (T(1) / T(8)) * A2 / std::pow(psi_ijk, T(7));
78
79 T new_psi = psi({i, j, k}) + T(0.5) * (lap - rhs) * factor;
80 new_psi = std::fmax(new_psi, T(0.1));
81
82 max_diff = std::fmax(max_diff, std::abs(new_psi - psi({i, j, k})));
83 psi({i, j, k}) = new_psi;
84 }
85 }
86 }
87
88 if (max_diff < tol) {
89 break;
90 }
91 }
92
93 return psi;
94 }
95};
96
97} // namespace tensorium_RG
Multi-dimensional tensor class with fixed rank and SIMD support.
Definition Tensor.hpp:25
std::array< size_t, Rank > shape() const
Definition Tensor.hpp:62
Definition BSSNConstraintsSolver.hpp:10
static tensorium::Tensor< T, 3 > solveLichnerowicz(const tensorium::Tensor< T, 5 > &Atilde, const tensorium::Tensor< T, 5 > &g_tilde_inv, T dx, T dy, T dz, int max_iter=1000, T tol=T(1e-8))
Solve the Lichnerowicz equation to enforce the Hamiltonian constraint in BSSN.
Definition BSSNConstraintsSolver.hpp:24
Definition BSSNAtildeTensor.hpp:10