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 : /// @}
|