-
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.
Add function to create a spacetime tensor from time and spatial ones.
- Loading branch information
Showing
4 changed files
with
149 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// Distributed under the MIT License. | ||
// See LICENSE.txt for details. | ||
|
||
#pragma once | ||
|
||
#include <cstddef> | ||
#include <type_traits> | ||
|
||
#include "DataStructures/Tensor/IndexType.hpp" | ||
#include "DataStructures/Tensor/Metafunctions.hpp" | ||
#include "DataStructures/Tensor/Tensor.hpp" | ||
#include "DataStructures/VectorImpl.hpp" | ||
#include "Utilities/Array.hpp" | ||
#include "Utilities/Gsl.hpp" | ||
#include "Utilities/StdArrayHelpers.hpp" | ||
#include "Utilities/TMPL.hpp" | ||
|
||
/// \ingroup TensorGroup | ||
/// \brief Combines a time component of a tensor with spatial components to | ||
/// produce a spacetime tensor. | ||
/// | ||
/// \details Combines a time component of a tensor with spatial components to | ||
/// produce a spacetime tensor. Specifically, the components of the result | ||
/// are views to the inputs. Can do so for a tensor of any rank, but | ||
/// requires that the new index is the first index of the resulting tensor, | ||
/// replacing the position of the spatial index in the input spatial tensor. | ||
/// For instance, it may combine \f$ \phi \f$ with \f$ A^i \f$ into | ||
/// \f$ A^a = \left(\phi, A^i\right) \f$, or it may combine \f$ A^a{}_b{}_c \f$ | ||
/// with \f$ B_i{}^a{}_b{}_c \f$ into | ||
/// \f$ C_a{}^b{}_c{}_d = \left(A^b{}_c{}_d, B_i{}^b{}_c{}_d\right)\f$, | ||
/// but it may not combine \f$ A^i{}_a \f$ with \f$ B^i{}_j{}_a \f$ to produce | ||
/// a tensor of the form \f$ C^i{}_a{}_b \f$. | ||
/// | ||
/// \tparam SpatialDim the number of spatial dimensions in the input and output | ||
/// tensors | ||
/// \tparam Ul whether the new index is covariant or contravariant (must match | ||
/// that of the spatial index of the input spatial tensor) | ||
/// \tparam Frame the frame of the new spacetime index (must match that of the | ||
/// spatial index of the input spatial tensor) | ||
template <size_t SpatialDim, UpLo Ul, typename Frame, typename DataType, | ||
typename SymmList, typename IndexList> | ||
void combine_spacetime_view( | ||
gsl::not_null<TensorMetafunctions::prepend_spacetime_index< | ||
Tensor<DataType, SymmList, IndexList>, SpatialDim, Ul, Frame>*> | ||
spacetime_tensor, | ||
const Tensor<DataType, SymmList, IndexList>& time_tensor, | ||
const TensorMetafunctions::prepend_spatial_index< | ||
Tensor<DataType, SymmList, IndexList>, SpatialDim, Ul, Frame>& | ||
spatial_tensor) { | ||
for (size_t storage_index = 0; | ||
storage_index < Tensor<DataVector, SymmList, IndexList>::size(); | ||
++storage_index) { | ||
const auto u_multi_index = | ||
Tensor<DataVector, SymmList, | ||
IndexList>::structure::get_canonical_tensor_index(storage_index); | ||
if constexpr (std::is_same_v<DataType, DataVector>) { | ||
const auto dtu_multi_index = prepend(u_multi_index, 0_st); | ||
make_const_view( | ||
make_not_null(&std::as_const(spacetime_tensor->get(dtu_multi_index))), | ||
time_tensor.get(u_multi_index), 0, | ||
time_tensor.get(u_multi_index).size()); | ||
for (size_t i = 0; i < SpatialDim; i++) { | ||
const auto du_multi_index = prepend(u_multi_index, i + 1); | ||
const auto diu_multi_index = prepend(u_multi_index, i); | ||
make_const_view(make_not_null(&std::as_const( | ||
spacetime_tensor->get(du_multi_index))), | ||
spatial_tensor.get(diu_multi_index), 0, | ||
spatial_tensor.get(diu_multi_index).size()); | ||
} | ||
} else { | ||
const auto dtu_multi_index = prepend(u_multi_index, 0_st); | ||
spacetime_tensor->get(dtu_multi_index) = time_tensor.get(u_multi_index); | ||
for (size_t i = 0; i < SpatialDim; ++i) { | ||
const auto du_multi_index = prepend(u_multi_index, i + 1); | ||
const auto diu_multi_index = prepend(u_multi_index, i); | ||
spacetime_tensor->get(du_multi_index) = | ||
spatial_tensor.get(diu_multi_index); | ||
} | ||
} | ||
} | ||
} |
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
66 changes: 66 additions & 0 deletions
66
tests/Unit/DataStructures/Tensor/Test_CombineSpacetimeView.cpp
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,66 @@ | ||
// Distributed under the MIT License. | ||
// See LICENSE.txt for details. | ||
|
||
#include "Framework/TestingFramework.hpp" | ||
|
||
#include <cstddef> | ||
|
||
#include "DataStructures/DataVector.hpp" | ||
#include "DataStructures/Tensor/CombineSpacetimeView.hpp" | ||
#include "DataStructures/Tensor/IndexType.hpp" | ||
#include "DataStructures/Tensor/Metafunctions.hpp" | ||
#include "DataStructures/Tensor/Tensor.hpp" | ||
#include "Framework/TestHelpers.hpp" | ||
#include "Helpers/DataStructures/MakeWithRandomValues.hpp" | ||
|
||
namespace { | ||
|
||
SPECTRE_TEST_CASE("Unit.DataStructures.Tensor.CombineSpacetimeView", | ||
"[DataStructures][Unit]") { | ||
const size_t SpatialDim = 3; | ||
const DataVector used_for_size(5); | ||
MAKE_GENERATOR(generator); | ||
const auto nn_gen = make_not_null(&generator); | ||
std::uniform_real_distribution<> distribution(-1.0, 1.0); | ||
const auto nn_dist = make_not_null(&distribution); | ||
|
||
tnsr::a<double, SpatialDim, Frame::Inertial> test_spacetime_vector; | ||
const auto scalar_time_component = | ||
make_with_random_values<Scalar<double>>(nn_gen, nn_dist, used_for_size); | ||
const auto vector_spatial_components = | ||
make_with_random_values<tnsr::i<double, SpatialDim, Frame::Inertial>>( | ||
nn_gen, nn_dist, used_for_size); | ||
|
||
combine_spacetime_view<SpatialDim, UpLo::Lo, Frame::Inertial>( | ||
make_not_null(&test_spacetime_vector), scalar_time_component, | ||
vector_spatial_components); | ||
|
||
CHECK(test_spacetime_vector.get(0) == get(scalar_time_component)); | ||
for (size_t i = 0; i < SpatialDim; ++i) { | ||
CHECK(test_spacetime_vector.get(i + 1) == vector_spatial_components.get(i)); | ||
} | ||
|
||
tnsr::Abb<DataVector, SpatialDim, Frame::Inertial> test_spacetime_tensor; | ||
const auto tensor_time_component = make_with_random_values< | ||
tnsr::aa<DataVector, SpatialDim, Frame::Inertial>>(nn_gen, nn_dist, | ||
used_for_size); | ||
const auto tensor_spatial_components = make_with_random_values< | ||
tnsr::Iaa<DataVector, SpatialDim, Frame::Inertial>>(nn_gen, nn_dist, | ||
used_for_size); | ||
|
||
combine_spacetime_view<SpatialDim, UpLo::Up, Frame::Inertial>( | ||
make_not_null(&test_spacetime_tensor), tensor_time_component, | ||
tensor_spatial_components); | ||
|
||
for (size_t i = 0; i <= SpatialDim; ++i) { | ||
for (size_t j = 0; j <= SpatialDim; ++j) { | ||
CHECK(test_spacetime_tensor.get(0, i, j) == | ||
tensor_time_component.get(i, j)); | ||
for (size_t k = 0; k < SpatialDim; ++k) { | ||
CHECK(test_spacetime_tensor.get(k + 1, i, j) == | ||
tensor_spatial_components.get(k, i, j)); | ||
} | ||
} | ||
} | ||
} | ||
} // namespace |