Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <boost/range/combine.hpp> 7 : #include <boost/tuple/tuple.hpp> 8 : #include <cstddef> 9 : 10 : #include "DataStructures/Index.hpp" 11 : #include "DataStructures/SliceIterator.hpp" 12 : #include "DataStructures/Tensor/Tensor.hpp" 13 : #include "DataStructures/Variables.hpp" 14 : #include "Utilities/Gsl.hpp" 15 : #include "Utilities/TMPL.hpp" 16 : 17 : /// @{ 18 : /*! 19 : * \ingroup DataStructuresGroup 20 : * \brief Slices volume `Tensor`s into a `Variables` 21 : * 22 : * The slice has a constant logical coordinate in direction `sliced_dim`, 23 : * slicing the volume at `fixed_index` in that dimension. For 24 : * example, to get the lower boundary of `sliced_dim`, pass `0` for 25 : * `fixed_index`; to get the upper boundary, pass 26 : * `extents[sliced_dim] - 1`. 27 : */ 28 : template <typename... TagsToSlice, size_t VolumeDim> 29 1 : void data_on_slice( 30 : const gsl::not_null<Variables<tmpl::list<TagsToSlice...>>*> interface_vars, 31 : const Index<VolumeDim>& element_extents, const size_t sliced_dim, 32 : const size_t fixed_index, const typename TagsToSlice::type&... tensors) { 33 : const size_t interface_grid_points = 34 : element_extents.slice_away(sliced_dim).product(); 35 : if (interface_vars->number_of_grid_points() != interface_grid_points) { 36 : *interface_vars = 37 : Variables<tmpl::list<TagsToSlice...>>(interface_grid_points); 38 : } 39 : for (SliceIterator si(element_extents, sliced_dim, fixed_index); si; ++si) { 40 : const auto lambda = [&si](auto& interface_tensor, 41 : const auto& volume_tensor) { 42 : for (decltype(auto) interface_and_volume_tensor_components : 43 : boost::combine(interface_tensor, volume_tensor)) { 44 : boost::get<0>( 45 : interface_and_volume_tensor_components)[si.slice_offset()] = 46 : boost::get<1>( 47 : interface_and_volume_tensor_components)[si.volume_offset()]; 48 : } 49 : return '0'; 50 : }; 51 : expand_pack(lambda(get<TagsToSlice>(*interface_vars), tensors)...); 52 : } 53 : } 54 : 55 : template <typename... TagsToSlice, size_t VolumeDim> 56 1 : Variables<tmpl::list<TagsToSlice...>> data_on_slice( 57 : const Index<VolumeDim>& element_extents, const size_t sliced_dim, 58 : const size_t fixed_index, const typename TagsToSlice::type&... tensors) { 59 : Variables<tmpl::list<TagsToSlice...>> interface_vars( 60 : element_extents.slice_away(sliced_dim).product()); 61 : data_on_slice<TagsToSlice...>(make_not_null(&interface_vars), element_extents, 62 : sliced_dim, fixed_index, tensors...); 63 : return interface_vars; 64 : } 65 : /// @}