Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/DataStructures/Tensor/TypeAliases.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,13 @@ using iJkk = Tensor<DataType, tmpl::integral_list<std::int32_t, 3, 2, 1, 1>,
SpatialIndex<SpatialDim, UpLo::Lo, Fr>,
SpatialIndex<SpatialDim, UpLo::Lo, Fr>>>;

template <typename DataType, size_t SpatialDim, typename Fr = Frame::Inertial>
using iijj = Tensor<DataType, tmpl::integral_list<std::int32_t, 2, 2, 1, 1>,
index_list<SpatialIndex<SpatialDim, UpLo::Lo, Fr>,
SpatialIndex<SpatialDim, UpLo::Lo, Fr>,
SpatialIndex<SpatialDim, UpLo::Lo, Fr>,
SpatialIndex<SpatialDim, UpLo::Lo, Fr>>>;

template <typename DataType, size_t SpatialDim, typename Fr = Frame::Inertial>
using iiJJ = Tensor<DataType, tmpl::integral_list<std::int32_t, 2, 2, 1, 1>,
index_list<SpatialIndex<SpatialDim, UpLo::Lo, Fr>,
Expand Down
130 changes: 78 additions & 52 deletions src/Evolution/Systems/Ccz4/DerivChristoffel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,69 @@
#include "Evolution/Systems/Ccz4/DerivChristoffel.hpp"

#include <cstddef>
#include <type_traits>

#include "DataStructures/DataVector.hpp"
#include "DataStructures/Tensor/Tensor.hpp"
#include "Utilities/GenerateInstantiations.hpp"
#include "Utilities/Gsl.hpp"

namespace Ccz4 {
template <typename DataType, size_t Dim, typename Frame>
template <typename DataType, size_t Dim, typename Frame, typename TensorType>
void deriv_conformal_christoffel_second_kind(
const gsl::not_null<tnsr::iJkk<DataType, Dim, Frame>*> result,
const tnsr::II<DataType, Dim, Frame>& inverse_conformal_spatial_metric,
const tnsr::ijj<DataType, Dim, Frame>& field_d,
const tnsr::ijkk<DataType, Dim, Frame>& d_field_d,
const tnsr::ijj<DataType, Dim, Frame>& field_d, const TensorType& d_field_d,
const tnsr::iJJ<DataType, Dim, Frame>& field_d_up) {
for (size_t i = 0; i < Dim; ++i) {
for (size_t j = i; j < Dim; ++j) {
for (size_t k = 0; k < Dim; ++k) {
for (size_t m = 0; m < Dim; ++m) {
(*result).get(k, m, i, j) =
-2.0 * field_d_up.get(k, m, 0) *
(field_d.get(i, j, 0) + field_d.get(j, i, 0) -
field_d.get(0, i, j)) +
0.5 * inverse_conformal_spatial_metric.get(m, 0) *
(d_field_d.get(k, i, j, 0) + d_field_d.get(i, k, j, 0) +
d_field_d.get(k, j, i, 0) + d_field_d.get(j, k, i, 0) -
d_field_d.get(k, 0, i, j) - d_field_d.get(0, k, i, j));
for (size_t l = 1; l < Dim; ++l) {
(*result).get(k, m, i, j) +=
-2.0 * field_d_up.get(k, m, l) *
(field_d.get(i, j, l) + field_d.get(j, i, l) -
field_d.get(l, i, j)) +
0.5 * inverse_conformal_spatial_metric.get(m, l) *
(d_field_d.get(k, i, j, l) + d_field_d.get(i, k, j, l) +
d_field_d.get(k, j, i, l) + d_field_d.get(j, k, i, l) -
d_field_d.get(k, l, i, j) - d_field_d.get(l, k, i, j));
// We keep this for loop specialization for faster speed when no symmetry
// of d_field_d is present.
if constexpr (std::is_same_v<TensorType, tnsr::ijkk<DataType, Dim, Frame>>) {
for (size_t i = 0; i < Dim; ++i) {
for (size_t j = i; j < Dim; ++j) {
for (size_t k = 0; k < Dim; ++k) {
for (size_t m = 0; m < Dim; ++m) {
(*result).get(k, m, i, j) =
-2.0 * field_d_up.get(k, m, 0) *
(field_d.get(i, j, 0) + field_d.get(j, i, 0) -
field_d.get(0, i, j)) +
0.5 * inverse_conformal_spatial_metric.get(m, 0) *
(d_field_d.get(k, i, j, 0) + d_field_d.get(i, k, j, 0) +
d_field_d.get(k, j, i, 0) + d_field_d.get(j, k, i, 0) -
d_field_d.get(k, 0, i, j) - d_field_d.get(0, k, i, j));
for (size_t l = 1; l < Dim; ++l) {
(*result).get(k, m, i, j) +=
-2.0 * field_d_up.get(k, m, l) *
(field_d.get(i, j, l) + field_d.get(j, i, l) -
field_d.get(l, i, j)) +
0.5 * inverse_conformal_spatial_metric.get(m, l) *
(d_field_d.get(k, i, j, l) + d_field_d.get(i, k, j, l) +
d_field_d.get(k, j, i, l) + d_field_d.get(j, k, i, l) -
d_field_d.get(k, l, i, j) - d_field_d.get(l, k, i, j));
}
}
}
}
}
} else {
::tenex::evaluate<ti::k, ti::M, ti::i, ti::j>(
result,
-2.0 * field_d_up(ti::k, ti::M, ti::L) *
(field_d(ti::i, ti::j, ti::l) + field_d(ti::j, ti::i, ti::l) -
field_d(ti::l, ti::i, ti::j)) +
inverse_conformal_spatial_metric(ti::M, ti::L) * 0.5 *
(d_field_d(ti::k, ti::i, ti::j, ti::l) +
d_field_d(ti::i, ti::k, ti::j, ti::l) +
d_field_d(ti::k, ti::j, ti::i, ti::l) +
d_field_d(ti::j, ti::k, ti::i, ti::l) -
d_field_d(ti::k, ti::l, ti::i, ti::j) -
d_field_d(ti::l, ti::k, ti::i, ti::j)));
}
}

template <typename DataType, size_t Dim, typename Frame>
template <typename DataType, size_t Dim, typename Frame, typename TensorType>
tnsr::iJkk<DataType, Dim, Frame> deriv_conformal_christoffel_second_kind(
const tnsr::II<DataType, Dim, Frame>& inverse_conformal_spatial_metric,
const tnsr::ijj<DataType, Dim, Frame>& field_d,
const tnsr::ijkk<DataType, Dim, Frame>& d_field_d,
const tnsr::ijj<DataType, Dim, Frame>& field_d, const TensorType& d_field_d,
const tnsr::iJJ<DataType, Dim, Frame>& field_d_up) {
tnsr::iJkk<DataType, Dim, Frame> result{};
deriv_conformal_christoffel_second_kind(make_not_null(&result),
Expand Down Expand Up @@ -94,47 +110,57 @@ deriv_contracted_conformal_christoffel_second_kind(
#define DIM(data) BOOST_PP_TUPLE_ELEM(0, data)
#define FRAME(data) BOOST_PP_TUPLE_ELEM(1, data)
#define DTYPE(data) BOOST_PP_TUPLE_ELEM(2, data)
#define TTYPE(data) BOOST_PP_TUPLE_ELEM(3, data)

#define INSTANTIATE(_, data) \
#define INSTANTIATE_CONFORMAL_CHRISTOFFEL(_, data) \
template void Ccz4::deriv_conformal_christoffel_second_kind( \
const gsl::not_null<tnsr::iJkk<DTYPE(data), DIM(data), FRAME(data)>*> \
result, \
const tnsr::II<DTYPE(data), DIM(data), FRAME(data)>& \
inverse_conformal_spatial_metric, \
const tnsr::ijj<DTYPE(data), DIM(data), FRAME(data)>& field_d, \
const tnsr::ijkk<DTYPE(data), DIM(data), FRAME(data)>& d_field_d, \
const TTYPE(data) < DTYPE(data), DIM(data), FRAME(data) > &d_field_d, \
const tnsr::iJJ<DTYPE(data), DIM(data), FRAME(data)>& field_d_up); \
template tnsr::iJkk<DTYPE(data), DIM(data), FRAME(data)> \
Ccz4::deriv_conformal_christoffel_second_kind( \
const tnsr::II<DTYPE(data), DIM(data), FRAME(data)>& \
inverse_conformal_spatial_metric, \
const tnsr::ijj<DTYPE(data), DIM(data), FRAME(data)>& field_d, \
const tnsr::ijkk<DTYPE(data), DIM(data), FRAME(data)>& d_field_d, \
const tnsr::iJJ<DTYPE(data), DIM(data), FRAME(data)>& field_d_up); \
template void Ccz4::deriv_contracted_conformal_christoffel_second_kind( \
const gsl::not_null<tnsr::iJ<DTYPE(data), DIM(data), FRAME(data)>*> \
result, \
const tnsr::II<DTYPE(data), DIM(data), FRAME(data)>& \
inverse_conformal_spatial_metric, \
const tnsr::iJJ<DTYPE(data), DIM(data), FRAME(data)>& field_d_up, \
const tnsr::Ijj<DTYPE(data), DIM(data), FRAME(data)>& \
conformal_christoffel_second_kind, \
const tnsr::iJkk<DTYPE(data), DIM(data), FRAME(data)>& \
d_conformal_christoffel_second_kind); \
template tnsr::iJ<DTYPE(data), DIM(data), FRAME(data)> \
Ccz4::deriv_contracted_conformal_christoffel_second_kind( \
const tnsr::II<DTYPE(data), DIM(data), FRAME(data)>& \
inverse_conformal_spatial_metric, \
const tnsr::iJJ<DTYPE(data), DIM(data), FRAME(data)>& field_d_up, \
const tnsr::Ijj<DTYPE(data), DIM(data), FRAME(data)>& \
conformal_christoffel_second_kind, \
const tnsr::iJkk<DTYPE(data), DIM(data), FRAME(data)>& \
const TTYPE(data) < DTYPE(data), DIM(data), FRAME(data) > &d_field_d, \
const tnsr::iJJ<DTYPE(data), DIM(data), FRAME(data)>& field_d_up);

GENERATE_INSTANTIATIONS(INSTANTIATE_CONFORMAL_CHRISTOFFEL, (1, 2, 3),
(Frame::Grid, Frame::Inertial), (double, DataVector),
(tnsr::iijj, tnsr::ijkk))

#undef INSTANTIATE_CONFORMAL_CHRISTOFFEL
#undef TTYPE

#define INSTANTIATE_CONTRACTED_CHRISTOFFEL(_, data) \
template void Ccz4::deriv_contracted_conformal_christoffel_second_kind( \
const gsl::not_null<tnsr::iJ<DTYPE(data), DIM(data), FRAME(data)>*> \
result, \
const tnsr::II<DTYPE(data), DIM(data), FRAME(data)>& \
inverse_conformal_spatial_metric, \
const tnsr::iJJ<DTYPE(data), DIM(data), FRAME(data)>& field_d_up, \
const tnsr::Ijj<DTYPE(data), DIM(data), FRAME(data)>& \
conformal_christoffel_second_kind, \
const tnsr::iJkk<DTYPE(data), DIM(data), FRAME(data)>& \
d_conformal_christoffel_second_kind); \
template tnsr::iJ<DTYPE(data), DIM(data), FRAME(data)> \
Ccz4::deriv_contracted_conformal_christoffel_second_kind( \
const tnsr::II<DTYPE(data), DIM(data), FRAME(data)>& \
inverse_conformal_spatial_metric, \
const tnsr::iJJ<DTYPE(data), DIM(data), FRAME(data)>& field_d_up, \
const tnsr::Ijj<DTYPE(data), DIM(data), FRAME(data)>& \
conformal_christoffel_second_kind, \
const tnsr::iJkk<DTYPE(data), DIM(data), FRAME(data)>& \
d_conformal_christoffel_second_kind);

GENERATE_INSTANTIATIONS(INSTANTIATE, (1, 2, 3), (Frame::Grid, Frame::Inertial),
(double, DataVector))
GENERATE_INSTANTIATIONS(INSTANTIATE_CONTRACTED_CHRISTOFFEL, (1, 2, 3),
(Frame::Grid, Frame::Inertial), (double, DataVector))

#undef INSTANTIATE
#undef INSTANTIATE_CONTRACTED_CHRISTOFFEL
#undef DTYPE
#undef FRAME
#undef DIM
16 changes: 10 additions & 6 deletions src/Evolution/Systems/Ccz4/DerivChristoffel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,25 @@ namespace Ccz4 {
* `Ccz4::Tags::InverseConformalMetric`, the CCZ4 auxiliary variable defined by
* `Ccz4::Tags::FieldD`, its spatial derivative, and the CCZ4 identity defined
* by `Ccz4::Tags::FieldDUp`.
* \note In second-order Ccz4, we impose symmetry of index k and l
* in \f$ \partial_l D_{kij}=\frac{1}{2}\partial_l \partial_k
* \tilde{\gamma}_{ij} \f$, because partial derivatives commute and to use
* `second_partial_derivatives()`. \f$ D_{kij} \f$ is evolved in
* the first-order system so no such symmetry is imposed.
*/
template <typename DataType, size_t Dim, typename Frame>
template <typename DataType, size_t Dim, typename Frame, typename TensorType>
void deriv_conformal_christoffel_second_kind(
const gsl::not_null<tnsr::iJkk<DataType, Dim, Frame>*> result,
const tnsr::II<DataType, Dim, Frame>& inverse_conformal_spatial_metric,
const tnsr::ijj<DataType, Dim, Frame>& field_d,
const tnsr::ijkk<DataType, Dim, Frame>& d_field_d,
const tnsr::ijj<DataType, Dim, Frame>& field_d, const TensorType& d_field_d,
const tnsr::iJJ<DataType, Dim, Frame>& field_d_up);

template <typename DataType, size_t Dim, typename Frame>
template <typename DataType, size_t Dim, typename Frame, typename TensorType>
tnsr::iJkk<DataType, Dim, Frame> deriv_conformal_christoffel_second_kind(
const tnsr::II<DataType, Dim, Frame>& inverse_conformal_spatial_metric,
const tnsr::ijj<DataType, Dim, Frame>& field_d,
const tnsr::ijkk<DataType, Dim, Frame>& d_field_d,
const tnsr::ijj<DataType, Dim, Frame>& field_d, const TensorType& d_field_d,
const tnsr::iJJ<DataType, Dim, Frame>& field_d_up);

/// @}

/// @{
Expand Down
10 changes: 10 additions & 0 deletions tests/Unit/Evolution/Systems/Ccz4/Test_DerivChristoffel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ void test_compute_deriv_conformal_christoffel_second_kind(
Frame::Inertial>),
"DerivChristoffel", "deriv_conformal_christoffel_second_kind",
{{{-1., 1.}}}, used_for_size);
pypp::check_with_random_values<1>(
static_cast<tnsr::iJkk<DataType, Dim, Frame::Inertial> (*)(
const tnsr::II<DataType, Dim, Frame::Inertial>&,
const tnsr::ijj<DataType, Dim, Frame::Inertial>&,
const tnsr::iijj<DataType, Dim, Frame::Inertial>&,
const tnsr::iJJ<DataType, Dim, Frame::Inertial>&)>(
&Ccz4::deriv_conformal_christoffel_second_kind<DataType, Dim,
Frame::Inertial>),
"DerivChristoffel", "deriv_conformal_christoffel_second_kind",
{{{-1., 1.}}}, used_for_size);
}

template <size_t Dim, typename DataType>
Expand Down
Loading