Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <algorithm>
7 : #include <cstddef>
8 : #include <unordered_set>
9 :
10 : #include "DataStructures/Index.hpp"
11 : #include "DataStructures/Tensor/Tensor.hpp"
12 : #include "Domain/Structure/Direction.hpp"
13 : #include "Domain/Structure/DirectionMap.hpp"
14 : #include "Domain/Structure/DirectionalId.hpp"
15 : #include "Domain/Structure/DirectionalIdMap.hpp"
16 : #include "Evolution/DgSubcell/SliceData.hpp"
17 : #include "Utilities/ContainerHelpers.hpp"
18 : #include "Utilities/Gsl.hpp"
19 :
20 : namespace evolution::dg::subcell {
21 : // template specialization for handling scalar (rank 0)
22 : template <size_t Dim, typename VectorType>
23 0 : void slice_tensor_for_subcell(
24 : const gsl::not_null<Tensor<VectorType, Symmetry<>, index_list<>>*>
25 : sliced_scalar,
26 : const Tensor<VectorType, Symmetry<>, index_list<>>& volume_scalar,
27 : const Index<Dim>& subcell_extents, size_t number_of_ghost_points,
28 : const Direction<Dim>& direction,
29 : const DirectionalIdMap<Dim, std::optional<intrp::Irregular<Dim>>>&
30 : fd_to_neighbor_fd_interpolants) {
31 : std::unordered_set directions_to_slice{direction};
32 :
33 : auto& scalar_dv = get(volume_scalar);
34 : auto sliced_data = evolution::dg::subcell::detail::slice_data_impl(
35 : gsl::make_span(scalar_dv.data(), scalar_dv.size()), subcell_extents,
36 : number_of_ghost_points, directions_to_slice, 0,
37 : fd_to_neighbor_fd_interpolants)[direction];
38 :
39 : std::copy(sliced_data.begin(), sliced_data.end(), get(*sliced_scalar).data());
40 : }
41 :
42 : /// @{
43 : /*!
44 : * \brief Slice a single volume tensor for a given direction and slicing depth
45 : * (number of ghost points).
46 : *
47 : * Note that the second to last argument has the type `Direction<Dim>`, not a
48 : * DirectionMap (cf. `evolution::dg::subcell::slice_data`)
49 : *
50 : */
51 : template <size_t Dim, typename VectorType, typename... Structure>
52 1 : void slice_tensor_for_subcell(
53 : const gsl::not_null<Tensor<VectorType, Structure...>*> sliced_tensor,
54 : const Tensor<VectorType, Structure...>& volume_tensor,
55 : const Index<Dim>& subcell_extents, size_t number_of_ghost_points,
56 : const Direction<Dim>& direction,
57 : const DirectionalIdMap<Dim, std::optional<intrp::Irregular<Dim>>>&
58 : fd_to_neighbor_fd_interpolants) {
59 : std::unordered_set directions_to_slice{direction};
60 :
61 : for (size_t i = 0; i < volume_tensor.size(); i++) {
62 : auto& ti = volume_tensor[i];
63 :
64 : auto sliced_data = evolution::dg::subcell::detail::slice_data_impl(
65 : gsl::make_span(ti.data(), ti.size()), subcell_extents,
66 : number_of_ghost_points, directions_to_slice, 0,
67 : fd_to_neighbor_fd_interpolants)[direction];
68 :
69 : std::copy(sliced_data.begin(), sliced_data.end(),
70 : (*sliced_tensor)[i].data());
71 : }
72 : }
73 :
74 : template <size_t Dim, typename VectorType, typename... Structure>
75 1 : Tensor<VectorType, Structure...> slice_tensor_for_subcell(
76 : const Tensor<VectorType, Structure...>& volume_tensor,
77 : const Index<Dim>& subcell_extents, size_t number_of_ghost_points,
78 : const Direction<Dim>& direction,
79 : const DirectionalIdMap<Dim, std::optional<intrp::Irregular<Dim>>>&
80 : fd_to_neighbor_fd_interpolants) {
81 : Tensor<VectorType, Structure...> sliced_tensor(
82 : subcell_extents.slice_away(direction.dimension()).product() *
83 : number_of_ghost_points);
84 : slice_tensor_for_subcell(make_not_null(&sliced_tensor), volume_tensor,
85 : subcell_extents, number_of_ghost_points, direction,
86 : fd_to_neighbor_fd_interpolants);
87 : return sliced_tensor;
88 : }
89 : /// @}
90 : } // namespace evolution::dg::subcell
|