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 : #include <vector>
8 :
9 : #include "Utilities/ErrorHandling/Assert.hpp"
10 : #include "Utilities/Gsl.hpp"
11 : #include "Utilities/TMPL.hpp"
12 :
13 : /// \cond
14 : template <size_t VolumeDim>
15 : class Mesh;
16 : template <size_t VolumeDim>
17 : class OrientationMap;
18 : template <size_t>
19 : class Index;
20 : template <typename TagsList>
21 : class Variables;
22 : /// \endcond
23 :
24 : /// \ingroup ComputationalDomainGroup
25 : /// \brief Orient a sliced Mesh to the logical frame of a neighbor element with
26 : /// the given orientation.
27 : template <size_t VolumeDim>
28 1 : Mesh<VolumeDim - 1> orient_mesh_on_slice(
29 : const Mesh<VolumeDim - 1>& mesh_on_slice, size_t sliced_dim,
30 : const OrientationMap<VolumeDim>& orientation_of_neighbor);
31 :
32 : /// @{
33 : /// \ingroup ComputationalDomainGroup
34 : /// \brief Orient a `DataVector`, `ComplexDataVector`, `std::vector<double>`, or
35 : /// `std::vector<std::complex<double>>` to the data-storage order of a neighbor
36 : /// element with the given orientation.
37 : ///
38 : /// The vector may represent more than one tensor component over the grid
39 : /// represented by `extents`.
40 : ///
41 : /// \warning The result is *not* resized and assumes to be of the correct size
42 : /// (`variables.size()`).
43 : ///
44 : /// In most cases the `Variables` version of `orient_variables` should be
45 : /// called. However, in some cases the tags and thus the type of the data being
46 : /// sent is determined at runtime. In these cases the `std::vector` version of
47 : /// `orient_variables` is useful. A concrete example of this is when hybridizing
48 : /// DG with finite difference methods, where sometimes the data sent is both the
49 : /// variables for reconstruction and the fluxes for either the DG or finite
50 : /// difference scheme, while at other points only one of these three is sent.
51 : template <typename VectorType, size_t VolumeDim>
52 1 : void orient_variables(gsl::not_null<VectorType*> result,
53 : const VectorType& variables,
54 : const Index<VolumeDim>& extents,
55 : const OrientationMap<VolumeDim>& orientation_of_neighbor);
56 :
57 : template <typename VectorType, size_t VolumeDim>
58 1 : VectorType orient_variables(
59 : const VectorType& variables, const Index<VolumeDim>& extents,
60 : const OrientationMap<VolumeDim>& orientation_of_neighbor);
61 :
62 : template <typename VectorType, size_t VolumeDim>
63 1 : void orient_variables_on_slice(
64 : gsl::not_null<VectorType*> result, const VectorType& variables_on_slice,
65 : const Index<VolumeDim - 1>& slice_extents, size_t sliced_dim,
66 : const OrientationMap<VolumeDim>& orientation_of_neighbor);
67 :
68 : template <typename VectorType, size_t VolumeDim>
69 1 : VectorType orient_variables_on_slice(
70 : const VectorType& variables_on_slice,
71 : const Index<VolumeDim - 1>& slice_extents, size_t sliced_dim,
72 : const OrientationMap<VolumeDim>& orientation_of_neighbor);
73 : /// @}
74 :
75 : /// @{
76 : /// \ingroup ComputationalDomainGroup
77 : /// Orient variables to the data-storage order of a neighbor element with
78 : /// the given orientation.
79 : template <size_t VolumeDim, typename TagsList>
80 1 : Variables<TagsList> orient_variables(
81 : const Variables<TagsList>& variables, const Index<VolumeDim>& extents,
82 : const OrientationMap<VolumeDim>& orientation_of_neighbor) {
83 : // Skip work (aside from a copy) if neighbor is aligned
84 : if (orientation_of_neighbor.is_aligned()) {
85 : return variables;
86 : }
87 :
88 : const size_t number_of_grid_points = extents.product();
89 : ASSERT(variables.number_of_grid_points() == number_of_grid_points,
90 : "Inconsistent `variables` and `extents`:\n"
91 : " variables.number_of_grid_points() = "
92 : << variables.number_of_grid_points()
93 : << "\n"
94 : " extents.product() = "
95 : << extents.product());
96 : Variables<TagsList> oriented_variables(number_of_grid_points);
97 : using VectorType = typename Variables<TagsList>::vector_type;
98 : using ValueType = typename Variables<TagsList>::value_type;
99 : VectorType result(oriented_variables.data(), oriented_variables.size());
100 : orient_variables(
101 : make_not_null(&result),
102 : // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
103 : VectorType(const_cast<ValueType*>(variables.data()), variables.size()),
104 : extents, orientation_of_neighbor);
105 : return oriented_variables;
106 : }
107 :
108 : template <size_t VolumeDim, typename TagsList>
109 1 : Variables<TagsList> orient_variables_on_slice(
110 : const Variables<TagsList>& variables_on_slice,
111 : const Index<VolumeDim - 1>& slice_extents, const size_t sliced_dim,
112 : const OrientationMap<VolumeDim>& orientation_of_neighbor) {
113 : // Skip work (aside from a copy) if neighbor slice is aligned
114 : if (orientation_of_neighbor.is_aligned()) {
115 : return variables_on_slice;
116 : }
117 :
118 : const size_t number_of_grid_points = slice_extents.product();
119 : ASSERT(variables_on_slice.number_of_grid_points() == number_of_grid_points,
120 : "Inconsistent `variables_on_slice` and `slice_extents`:\n"
121 : " variables_on_slice.number_of_grid_points() = "
122 : << variables_on_slice.number_of_grid_points()
123 : << "\n"
124 : " slice_extents.product() = "
125 : << slice_extents.product());
126 :
127 : Variables<TagsList> oriented_variables(number_of_grid_points);
128 : using VectorType = typename Variables<TagsList>::vector_type;
129 : using ValueType = typename Variables<TagsList>::value_type;
130 : VectorType result(oriented_variables.data(), oriented_variables.size());
131 : orient_variables_on_slice(
132 : make_not_null(&result),
133 : // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
134 : VectorType(const_cast<ValueType*>(variables_on_slice.data()),
135 : variables_on_slice.size()),
136 : slice_extents, sliced_dim, orientation_of_neighbor);
137 : return oriented_variables;
138 : }
139 : /// @}
|