Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <cstddef> 7 : 8 : #include "DataStructures/DataVector.hpp" 9 : #include "DataStructures/Tensor/Tensor.hpp" 10 : #include "DataStructures/Variables.hpp" 11 : #include "Utilities/ErrorHandling/Assert.hpp" 12 : #include "Utilities/Gsl.hpp" 13 : #include "Utilities/TMPL.hpp" 14 : 15 : /// \ingroup DataStructuresGroup 16 : /// Copy a given index of each component of a `Tensor<DataVector>` or 17 : /// `Variables<DataVector>` into a `Tensor<double>`, single point 18 : /// `Tensor<DataVector>`, or single-point `Variables<DataVector>`. 19 : /// Also works with `ComplexDataVector`. 20 : /// 21 : /// \note There is no by-value overload extracting to a 22 : /// `Tensor<DataVector>`. This is both for the practical reason that 23 : /// it would be ambiguous with the `Tensor<double>` overload and 24 : /// because allocating multiple `DataVector`s for the return type 25 : /// would usually be very inefficient. 26 : /// 27 : /// \see overwrite_point 28 : /// @{ 29 : template <typename VectorType, typename... Structure> 30 1 : void extract_point( 31 : const gsl::not_null<Tensor<typename VectorType::value_type, Structure...>*> 32 : destination, 33 : const Tensor<VectorType, Structure...>& source, const size_t index) { 34 : for (size_t i = 0; i < destination->size(); ++i) { 35 : (*destination)[i] = source[i][index]; 36 : } 37 : } 38 : 39 : template <typename VectorType, typename... Structure> 40 1 : Tensor<typename VectorType::value_type, Structure...> extract_point( 41 : const Tensor<VectorType, Structure...>& tensor, const size_t index) { 42 : Tensor<typename VectorType::value_type, Structure...> result; 43 : extract_point(make_not_null(&result), tensor, index); 44 : return result; 45 : } 46 : 47 : template <typename VectorType, typename... Structure> 48 1 : void extract_point( 49 : const gsl::not_null<Tensor<VectorType, Structure...>*> destination, 50 : const Tensor<VectorType, Structure...>& source, const size_t index) { 51 : ASSERT(destination->begin()->size() == 1, 52 : "Output tensor components have wrong size: " 53 : << destination->begin()->size()); 54 : for (size_t i = 0; i < destination->size(); ++i) { 55 : (*destination)[i][0] = source[i][index]; 56 : } 57 : } 58 : 59 : template <typename... Tags> 60 1 : void extract_point( 61 : const gsl::not_null<Variables<tmpl::list<Tags...>>*> result, 62 : const Variables<tmpl::list<Tags...>>& variables, const size_t index) { 63 : result->initialize(1); 64 : expand_pack((extract_point( 65 : make_not_null(&get<Tags>(*result)), get<Tags>(variables), index), 0)...); 66 : } 67 : 68 : template <typename... Tags> 69 1 : Variables<tmpl::list<Tags...>> extract_point( 70 : const Variables<tmpl::list<Tags...>>& variables, const size_t index) { 71 : Variables<tmpl::list<Tags...>> result(1); 72 : extract_point(make_not_null(&result), variables, index); 73 : return result; 74 : } 75 : /// @} 76 : 77 : /// \ingroup DataStructuresGroup 78 : /// Copy a `Tensor<double>`, single point `Tensor<DataVector>`, or 79 : /// single-point `Variables<DataVector>` into the given index of each 80 : /// component of a `Tensor<DataVector>` or `Variables<DataVector>`. 81 : /// 82 : /// \see extract_point 83 : /// @{ 84 : template <typename VectorType, typename... Structure> 85 1 : void overwrite_point( 86 : const gsl::not_null<Tensor<VectorType, Structure...>*> destination, 87 : const Tensor<typename VectorType::value_type, Structure...>& source, 88 : const size_t index) { 89 : for (size_t i = 0; i < destination->size(); ++i) { 90 : (*destination)[i][index] = source[i]; 91 : } 92 : } 93 : 94 : template <typename VectorType, typename... Structure> 95 1 : void overwrite_point( 96 : const gsl::not_null<Tensor<VectorType, Structure...>*> destination, 97 : const Tensor<VectorType, Structure...>& source, const size_t index) { 98 : ASSERT(source.begin()->size() == 1, 99 : "Cannot overwrite with " << source.begin()->size() << " points."); 100 : for (size_t i = 0; i < destination->size(); ++i) { 101 : (*destination)[i][index] = source[i][0]; 102 : } 103 : } 104 : 105 : template <typename... Tags> 106 1 : void overwrite_point( 107 : const gsl::not_null<Variables<tmpl::list<Tags...>>*> destination, 108 : const Variables<tmpl::list<Tags...>>& source, const size_t index) { 109 : ASSERT(source.number_of_grid_points() == 1, 110 : "Must overwrite with a single point."); 111 : expand_pack((overwrite_point(make_not_null(&get<Tags>(*destination)), 112 : extract_point(get<Tags>(source), 0), index), 113 : 0)...); 114 : } 115 : /// @}