Skip to content

Commit

Permalink
Add function to create a spacetime tensor from time and spatial ones.
Browse files Browse the repository at this point in the history
  • Loading branch information
ncorsobh committed Jan 10, 2024
1 parent 8592478 commit dd6e2e9
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/DataStructures/Tensor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ spectre_target_headers(
INCLUDE_DIRECTORY ${CMAKE_SOURCE_DIR}/src
HEADERS
ContractFirstNIndices.hpp
CreateView.hpp
Identity.hpp
IndexType.hpp
Metafunctions.hpp
Expand Down
70 changes: 70 additions & 0 deletions src/DataStructures/Tensor/CreateView.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// 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. 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$
/// to produce \f$ A^a \f$, or it may combine \f$ A^a{}_b{}_c \f$ with
/// \f$ B_i{}^a{}_b{}_c \f$ to produce \f$ C_a{}^b{}_c{}_d \f$, but it may not
/// combine \f$ A^i{}_a \f$ with \f$ B^i{}_j{}_a \f$ to produce \f$ C^i{}_a{}_b
/// \f$.
template <size_t SpatialDim, UpLo Ul, typename Frame, typename DataType,
typename SymmList, typename IndexList>
void create_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(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(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);
}
}
}
}
1 change: 1 addition & 0 deletions tests/Unit/DataStructures/Tensor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set(LIBRARY "Test_Tensor")

set(LIBRARY_SOURCES
Test_ContractFirstNIndices.cpp
Test_CreateView.cpp
Test_Identity.cpp
Test_Metafunctions.cpp
Test_Slice.cpp
Expand Down
66 changes: 66 additions & 0 deletions tests/Unit/DataStructures/Tensor/Test_CreateView.cpp
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/CreateView.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.CreateView",
"[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);

create_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<double, SpatialDim, Frame::Inertial> test_spacetime_tensor;
const auto tensor_time_component =
make_with_random_values<tnsr::aa<double, SpatialDim, Frame::Inertial>>(
nn_gen, nn_dist, used_for_size);
const auto tensor_spatial_components =
make_with_random_values<tnsr::Iaa<double, SpatialDim, Frame::Inertial>>(
nn_gen, nn_dist, used_for_size);

create_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

0 comments on commit dd6e2e9

Please sign in to comment.