SliceTensorToVariables.hpp
1 // 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"
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>
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,
33  const typename TagsToSlice::type&... tensors) noexcept {
34  const size_t interface_grid_points =
35  element_extents.slice_away(sliced_dim).product();
36  if (interface_vars->number_of_grid_points() != interface_grid_points) {
37  *interface_vars =
38  Variables<tmpl::list<TagsToSlice...>>(interface_grid_points);
39  }
40  for (SliceIterator si(element_extents, sliced_dim, fixed_index); si; ++si) {
41  const auto lambda = [&si](auto& interface_tensor,
42  const auto& volume_tensor) noexcept {
43  for (decltype(auto) interface_and_volume_tensor_components :
44  boost::combine(interface_tensor, volume_tensor)) {
45  boost::get<0>(
46  interface_and_volume_tensor_components)[si.slice_offset()] =
47  boost::get<1>(
48  interface_and_volume_tensor_components)[si.volume_offset()];
49  }
50  return '0';
51  };
52  expand_pack(lambda(get<TagsToSlice>(*interface_vars), tensors)...);
53  }
54 }
55 
56 template <typename... TagsToSlice, size_t VolumeDim>
57 Variables<tmpl::list<TagsToSlice...>> data_on_slice(
58  const Index<VolumeDim>& element_extents, const size_t sliced_dim,
59  const size_t fixed_index,
60  const typename TagsToSlice::type&... tensors) noexcept {
61  Variables<tmpl::list<TagsToSlice...>> interface_vars(
62  element_extents.slice_away(sliced_dim).product());
63  data_on_slice<TagsToSlice...>(make_not_null(&interface_vars), element_extents,
64  sliced_dim, fixed_index, tensors...);
65  return interface_vars;
66 }
67 // @}
expand_pack
constexpr void expand_pack(Ts &&...) noexcept
Allows zero-cost unordered expansion of a parameter.
Definition: TMPL.hpp:547
Index< VolumeDim >
cstddef
SliceIterator
Iterate over a (dim-1)-dimensional slice.
Definition: SliceIterator.hpp:24
Index.hpp
Variables.hpp
Gsl.hpp
Tensor.hpp
make_not_null
gsl::not_null< T * > make_not_null(T *ptr) noexcept
Construct a not_null from a pointer. Often this will be done as an implicit conversion,...
Definition: Gsl.hpp:880
data_on_slice
void data_on_slice(const gsl::not_null< Variables< tmpl::list< TagsToSlice... >> * > interface_vars, const Index< VolumeDim > &element_extents, const size_t sliced_dim, const size_t fixed_index, const typename TagsToSlice::type &... tensors) noexcept
Slices volume Tensors into a Variables
Definition: SliceTensorToVariables.hpp:29
TMPL.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: Gsl.hpp:183