-
Notifications
You must be signed in to change notification settings - Fork 191
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5655 from nilsvu/index_manip
Move `raise_or_lower_index` and `trace` to Tensor lib
- Loading branch information
Showing
85 changed files
with
364 additions
and
262 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// Distributed under the MIT License. | ||
// See LICENSE.txt for details. | ||
|
||
#include "DataStructures/Tensor/EagerMath/Trace.hpp" | ||
|
||
#include <cstddef> | ||
|
||
#include "DataStructures/Tensor/Tensor.hpp" | ||
#include "Utilities/GenerateInstantiations.hpp" | ||
|
||
template <typename DataType, typename Index0, typename Index1> | ||
void trace_last_indices( | ||
const gsl::not_null<Tensor<DataType, Symmetry<1>, index_list<Index0>>*> | ||
trace_of_tensor, | ||
const Tensor<DataType, Symmetry<2, 1, 1>, | ||
index_list<Index0, Index1, Index1>>& tensor, | ||
const Tensor<DataType, Symmetry<1, 1>, | ||
index_list<change_index_up_lo<Index1>, | ||
change_index_up_lo<Index1>>>& metric) { | ||
constexpr auto dimension_of_trace = Index0::dim; | ||
constexpr auto dimension_of_metric = Index1::dim; | ||
for (size_t i = 0; i < dimension_of_trace; ++i) { | ||
trace_of_tensor->get(i) = tensor.get(i, 0, 0) * get<0, 0>(metric); | ||
for (size_t j = 0; j < dimension_of_metric; ++j) { | ||
if (j != 0) { | ||
trace_of_tensor->get(i) += tensor.get(i, j, j) * metric.get(j, j); | ||
} | ||
for (size_t k = j + 1; k < dimension_of_metric; ++k) { | ||
trace_of_tensor->get(i) += 2.0 * tensor.get(i, j, k) * metric.get(j, k); | ||
} | ||
} | ||
} | ||
} | ||
|
||
template <typename DataType, typename Index0> | ||
void trace( | ||
const gsl::not_null<Scalar<DataType>*> trace, | ||
const Tensor<DataType, Symmetry<1, 1>, index_list<Index0, Index0>>& tensor, | ||
const Tensor<DataType, Symmetry<1, 1>, | ||
index_list<change_index_up_lo<Index0>, | ||
change_index_up_lo<Index0>>>& metric) { | ||
constexpr auto dimension = Index0::dim; | ||
get(*trace) = get<0, 0>(tensor) * get<0, 0>(metric); | ||
for (size_t i = 0; i < dimension; ++i) { | ||
if (i != 0) { | ||
get(*trace) += tensor.get(i, i) * metric.get(i, i); | ||
} | ||
for (size_t j = i + 1; j < dimension; ++j) { // symmetry | ||
get(*trace) += 2.0 * tensor.get(i, j) * metric.get(i, j); | ||
} | ||
} | ||
} | ||
|
||
#define DIM(data) BOOST_PP_TUPLE_ELEM(0, data) | ||
#define DTYPE(data) BOOST_PP_TUPLE_ELEM(1, data) | ||
#define FRAME(data) BOOST_PP_TUPLE_ELEM(2, data) | ||
#define INDEXTYPE(data) BOOST_PP_TUPLE_ELEM(3, data) | ||
#define UPORLO0(data) BOOST_PP_TUPLE_ELEM(4, data) | ||
#define UPORLO1(data) BOOST_PP_TUPLE_ELEM(5, data) | ||
|
||
// Note: currently only instantiate these functions for the cases | ||
// where Index0 and Index1 have the same spatial dimension, Frame and | ||
// IndexType. The functions above are generic and can handle any of | ||
// them being different, if these cases are needed. | ||
#define INDEX0(data) INDEXTYPE(data)<DIM(data), UPORLO0(data), FRAME(data)> | ||
#define INDEX1(data) INDEXTYPE(data)<DIM(data), UPORLO1(data), FRAME(data)> | ||
|
||
#define INSTANTIATE(_, data) \ | ||
template void trace_last_indices( \ | ||
const gsl::not_null< \ | ||
Tensor<DTYPE(data), Symmetry<1>, index_list<INDEX0(data)>>*> \ | ||
result, \ | ||
const Tensor<DTYPE(data), Symmetry<2, 1, 1>, \ | ||
index_list<INDEX0(data), INDEX1(data), INDEX1(data)>>& \ | ||
tensor, \ | ||
const Tensor<DTYPE(data), Symmetry<1, 1>, \ | ||
index_list<change_index_up_lo<INDEX1(data)>, \ | ||
change_index_up_lo<INDEX1(data)>>>& metric); | ||
|
||
GENERATE_INSTANTIATIONS(INSTANTIATE, (1, 2, 3), (double, DataVector), | ||
(Frame::Grid, Frame::Distorted, Frame::Inertial, | ||
Frame::Spherical<Frame::Inertial>, | ||
Frame::Spherical<Frame::Distorted>, | ||
Frame::Spherical<Frame::Grid>), | ||
(SpatialIndex, SpacetimeIndex), (UpLo::Lo, UpLo::Up), | ||
(UpLo::Lo, UpLo::Up)) | ||
|
||
#undef FRAME1 | ||
#undef UPORLO1 | ||
#undef INDEXTYPE1 | ||
#undef INDEX1 | ||
#undef INSTANTIATE | ||
|
||
#define INSTANTIATE2(_, data) \ | ||
template void trace( \ | ||
const gsl::not_null<Scalar<DTYPE(data)>*> trace, \ | ||
const Tensor<DTYPE(data), Symmetry<1, 1>, \ | ||
index_list<INDEX0(data), INDEX0(data)>>& tensor, \ | ||
const Tensor<DTYPE(data), Symmetry<1, 1>, \ | ||
index_list<change_index_up_lo<INDEX0(data)>, \ | ||
change_index_up_lo<INDEX0(data)>>>& metric); | ||
|
||
GENERATE_INSTANTIATIONS(INSTANTIATE2, (1, 2, 3), (double, DataVector), | ||
(Frame::Grid, Frame::Distorted, Frame::Inertial), | ||
(SpatialIndex, SpacetimeIndex), (UpLo::Lo, UpLo::Up)) | ||
|
||
#undef DIM | ||
#undef DTYPE | ||
#undef FRAME0 | ||
#undef UPORLO0 | ||
#undef INDEXTYPE0 | ||
#undef INDEX0 | ||
#undef INSTANTIATE2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Distributed under the MIT License. | ||
// See LICENSE.txt for details. | ||
|
||
#pragma once | ||
|
||
#include "DataStructures/Tensor/Tensor.hpp" | ||
#include "Utilities/Gsl.hpp" | ||
#include "Utilities/MakeWithValue.hpp" | ||
|
||
/// @{ | ||
/*! | ||
* \ingroup GeneralRelativityGroup | ||
* \brief Computes trace of a rank 3 tensor, which is symmetric in its last two | ||
* indices, tracing the symmetric indices. | ||
* | ||
* \details For example, if \f$ T_{abc} \f$ is a tensor such that \f$T_{abc} = | ||
* T_{acb} \f$ then \f$ T_a = g^{bc}T_{abc} \f$ is computed, where \f$ g^{bc} | ||
* \f$ is the inverse metric. Note that indices \f$a,b,c,...\f$ can represent | ||
* either spatial or spacetime indices, and can have either valence. You may | ||
* have to add a new instantiation of this template if you need a new use case. | ||
*/ | ||
template <typename DataType, typename Index0, typename Index1> | ||
void trace_last_indices( | ||
gsl::not_null<Tensor<DataType, Symmetry<1>, index_list<Index0>>*> | ||
trace_of_tensor, | ||
const Tensor<DataType, Symmetry<2, 1, 1>, | ||
index_list<Index0, Index1, Index1>>& tensor, | ||
const Tensor<DataType, Symmetry<1, 1>, | ||
index_list<change_index_up_lo<Index1>, | ||
change_index_up_lo<Index1>>>& metric); | ||
|
||
template <typename DataType, typename Index0, typename Index1> | ||
Tensor<DataType, Symmetry<1>, index_list<Index0>> trace_last_indices( | ||
const Tensor<DataType, Symmetry<2, 1, 1>, | ||
index_list<Index0, Index1, Index1>>& tensor, | ||
const Tensor<DataType, Symmetry<1, 1>, | ||
index_list<change_index_up_lo<Index1>, | ||
change_index_up_lo<Index1>>>& metric) { | ||
auto trace_of_tensor = | ||
make_with_value<Tensor<DataType, Symmetry<1>, index_list<Index0>>>(metric, | ||
0.); | ||
trace_last_indices(make_not_null(&trace_of_tensor), tensor, metric); | ||
return trace_of_tensor; | ||
} | ||
/// @} | ||
|
||
/// @{ | ||
/*! | ||
* \ingroup GeneralRelativityGroup | ||
* \brief Computes trace of a rank-2 symmetric tensor. | ||
* \details Computes \f$g^{ab}T_{ab}\f$ or \f$g_{ab}T^{ab}\f$ where \f$(a,b)\f$ | ||
* can be spatial or spacetime indices. | ||
*/ | ||
template <typename DataType, typename Index0> | ||
void trace( | ||
gsl::not_null<Scalar<DataType>*> trace, | ||
const Tensor<DataType, Symmetry<1, 1>, index_list<Index0, Index0>>& tensor, | ||
const Tensor<DataType, Symmetry<1, 1>, | ||
index_list<change_index_up_lo<Index0>, | ||
change_index_up_lo<Index0>>>& metric); | ||
|
||
template <typename DataType, typename Index0> | ||
Scalar<DataType> trace( | ||
const Tensor<DataType, Symmetry<1, 1>, index_list<Index0, Index0>>& tensor, | ||
const Tensor<DataType, Symmetry<1, 1>, | ||
index_list<change_index_up_lo<Index0>, | ||
change_index_up_lo<Index0>>>& metric) { | ||
Scalar<DataType> trace{}; | ||
::trace(make_not_null(&trace), tensor, metric); | ||
return trace; | ||
} | ||
/// @} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.