Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
ViewPatch.hpp
Go to the documentation of this file.
1 // Copyright (c) 2018 Maikel Nadolski
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #ifndef FUB_SAMRAI_PATCH_VIEW_HPP
22 #define FUB_SAMRAI_PATCH_VIEW_HPP
23 
24 #include "fub/Equation.hpp"
25 
26 #include <SAMRAI/hier/Patch.h>
27 #include <SAMRAI/pdat/ArrayData.h>
28 #include <SAMRAI/pdat/CellData.h>
29 #include <SAMRAI/pdat/SideData.h>
30 
31 namespace fub {
32 namespace samrai {
33 
34 template <int Rank, typename T>
35 mdspan<T, Rank> MakeMdSpan(SAMRAI::pdat::ArrayData<T>& array) {
36  const SAMRAI::hier::Box& box = array.getBox();
37  const int dim = box.getDim().getValue();
38  const int depth = array.getDepth();
39  if ((depth > 1 && Rank < dim + 1) || (depth == 1 && Rank < dim)) {
40  throw std::invalid_argument("Dimension mismatch in make_mdspan.");
41  }
42  std::array<std::ptrdiff_t, Rank> extents;
43  extents.fill(1);
44  for (int d = 0; d < dim; ++d) {
45  extents[d] = box.numberCells(d);
46  }
47  if (depth > 1) {
48  extents[dim] = depth;
49  }
50  T* pointer = array.getPointer();
51  return mdspan<T, Rank>(pointer, extents);
52 }
53 
54 template <int Rank, typename T>
55 mdspan<const T, Rank> MakeMdSpan(const SAMRAI::pdat::ArrayData<T>& array) {
56  const SAMRAI::hier::Box& box = array.getBox();
57  const int dim = box.getDim().getValue();
58  const int depth = array.getDepth();
59  if ((depth > 1 && Rank < dim + 1) || (depth == 1 && Rank < dim)) {
60  throw std::invalid_argument("Dimension mismatch in make_mdspan.");
61  }
62  std::array<std::ptrdiff_t, Rank> extents;
63  extents.fill(1);
64  for (int d = 0; d < dim; ++d) {
65  extents[d] = box.numberCells(d);
66  }
67  if (depth > 1) {
68  extents[dim] = depth;
69  }
70  const T* pointer = array.getPointer();
71  return mdspan<const T, Rank>(pointer, extents);
72 }
73 
74 template <int Rank> IndexBox<Rank> AsIndexBox(const SAMRAI::hier::Box& box) {
75  IndexBox<Rank> index_box{};
76  const std::size_t dim = static_cast<std::size_t>(box.getDim().getValue());
77  for (std::size_t i = 0; i < dim; ++i) {
78  index_box.lower[i] = box.lower(static_cast<SAMRAI::hier::Box::dir_t>(i));
79  index_box.upper[i] =
80  box.upper(static_cast<SAMRAI::hier::Box::dir_t>(i)) + 1;
81  }
82  return index_box;
83 }
84 
85 template <int Rank, typename T>
87 MakePatchDataView(const SAMRAI::pdat::ArrayData<T>& array) {
88  IndexBox<Rank> box = AsIndexBox<Rank>(array.getBox());
89  return PatchDataView<const T, Rank>(MakeMdSpan<Rank, T>(array), box.lower);
90 }
91 
92 template <int Rank, typename T>
93 PatchDataView<T, Rank> MakePatchDataView(SAMRAI::pdat::ArrayData<T>& array) {
94  IndexBox<Rank> box = AsIndexBox<Rank>(array.getBox());
95  return PatchDataView<T, Rank>(MakeMdSpan<Rank, T>(array), box.lower);
96 }
97 
98 template <typename PatchData>
99 std::enable_if_t<std::is_pointer_v<PatchData>, void>
100 GetPatchData(span<PatchData> patch_datas, SAMRAI::hier::Patch& patch,
101  span<const int> data_ids) {
102  FUB_ASSERT(data_ids.size() == patch_datas.size());
103  std::transform(data_ids.begin(), data_ids.end(), patch_datas.begin(),
104  [&patch](int id) {
105  PatchData pointer_to_data =
106  dynamic_cast<PatchData>(patch.getPatchData(id).get());
107  FUB_ASSERT(pointer_to_data);
108  return pointer_to_data;
109  });
110 }
111 
112 template <typename PatchData>
113 std::enable_if_t<std::is_pointer_v<PatchData>, void>
114 GetPatchData(span<PatchData> patch_datas, const SAMRAI::hier::Patch& patch,
115  span<const int> data_ids) {
116  FUB_ASSERT(data_ids.size() == patch_datas.size());
117  std::transform(data_ids.begin(), data_ids.end(), patch_datas.begin(),
118  [&patch](int id) {
119  PatchData pointer_to_data =
120  dynamic_cast<PatchData>(patch.getPatchData(id).get());
121  FUB_ASSERT(pointer_to_data);
122  return pointer_to_data;
123  });
124 }
125 
126 template <typename State>
127 BasicView<State> MakeView(span<SAMRAI::pdat::SideData<double>*> span,
128  const typename State::Equation& /* equation */,
129  Direction dir) {
130  BasicView<State> view;
131  int i = 0;
132  const int dir_value = static_cast<int>(dir);
134  [&](auto& variable) {
135  using type = typename remove_cvref<decltype(variable)>::type;
136  constexpr int Rank = type::rank();
137  variable = MakePatchDataView<Rank>(span[i]->getArrayData(dir_value));
138  ++i;
139  },
140  view);
141  return view;
142 }
143 
144 template <typename State>
145 BasicView<State> MakeView(span<SAMRAI::pdat::CellData<double>*> span,
146  const typename State::Equation& /* equation */) {
147  BasicView<State> view;
148  int i = 0;
149  static constexpr int Rank = State::Equation::Rank();
150  using T = std::conditional_t<std::is_const_v<State>, const double, double>;
152  overloaded{[&](PatchDataView<T, Rank>& variable) {
153  variable = MakePatchDataView<Rank>(span[i]->getArrayData());
154  ++i;
155  },
156  [&](PatchDataView<T, Rank + 1>& variable) {
157  variable =
158  MakePatchDataView<Rank + 1>(span[i]->getArrayData());
159  ++i;
160  }},
161  view);
162  return view;
163 }
164 
165 template <typename State>
167 MakeView(span<SAMRAI::pdat::CellData<double> const*> span,
168  const typename State::Equation& /* equation */) {
170  int i = 0;
171  static constexpr int Rank = State::Equation::Rank();
174  variable = MakePatchDataView<Rank>(span[i]->getArrayData());
175  ++i;
176  },
178  variable =
179  MakePatchDataView<Rank + 1>(span[i]->getArrayData());
180  ++i;
181  }},
182  view);
183  return view;
184 }
185 
186 template <typename State, typename Range>
187 View<State> MakeView(Range&& span, const typename State::Equation& equation,
188  const IndexBox<State::Equation::Rank()>& box) {
189  return Subview(MakeView<State>(std::forward<Range>(span), equation), box);
190 }
191 
192 template <typename State, typename Range>
193 View<State> MakeView(Range&& span, const typename State::Equation& equation,
194  Direction dir,
195  const IndexBox<State::Equation::Rank()>& box) {
196  return Subview(MakeView<State>(std::forward<Range>(span), equation, dir),
197  box);
198 }
199 
200 int GetDirection(const SAMRAI::hier::IntVector& directions);
201 
202 // template <typename State, typename Equation>
203 // auto MakeView(span<SAMRAI::pdat::SideData<double>*> span,
204 // const Equation& equation) {
205 // return MakeView(std::make_index_sequence<NumVariables<State>::value>(),
206 // span,
207 // equation);
208 //}
209 
210 } // namespace samrai
211 } // namespace fub
212 
213 #endif
#define FUB_ASSERT(x)
Definition: assert.hpp:39
Definition: mdspan.hpp:573
An extents object defines a multidimensional index space which is the Cartesian product of integers e...
Definition: mdspan.hpp:208
A span is a view over a contiguous sequence of objects, the storage of which is owned by some other o...
Definition: span.hpp:81
constexpr index_type size() const noexcept
Returns the number of elements in the span.
Definition: span.hpp:392
constexpr iterator begin() const noexcept
Returns an iterator pointing to the first element of the span.
Definition: span.hpp:428
constexpr iterator end() const noexcept
Returns an iterator pointing one after the last element of the span.
Definition: span.hpp:438
std::decay_t< decltype(std::declval< T >().GetEquation())> Equation
A template typedef to detect the member function.
Definition: Meta.hpp:59
mdspan< T, Rank > MakeMdSpan(SAMRAI::pdat::ArrayData< T > &array)
Definition: ViewPatch.hpp:35
IndexBox< Rank > AsIndexBox(const SAMRAI::hier::Box &box)
Definition: ViewPatch.hpp:74
int GetDirection(const SAMRAI::hier::IntVector &directions)
std::enable_if_t< std::is_pointer_v< PatchData >, void > GetPatchData(span< PatchData > patch_datas, SAMRAI::hier::Patch &patch, span< const int > data_ids)
Definition: ViewPatch.hpp:100
PatchDataView< const T, Rank > MakePatchDataView(const SAMRAI::pdat::ArrayData< T > &array)
Definition: ViewPatch.hpp:87
BasicView< State > MakeView(span< SAMRAI::pdat::SideData< double > * > span, const typename State::Equation &, Direction dir)
Definition: ViewPatch.hpp:127
The fub namespace.
Definition: AnyBoundaryCondition.hpp:31
View< State > Subview(const BasicView< State, Layout, Rank > &state, const IndexBox< Rank > &box)
Definition: Equation.hpp:86
void ForEachVariable(F function, Ts &&... states)
Definition: State.hpp:89
Direction
This is a type safe type to denote a dimensional split direction.
Definition: Direction.hpp:30
IndexBox< Rank > Box(const BasicView< State, Layout, Rank > &view)
Definition: State.hpp:486
Definition: State.hpp:403
Definition: PatchDataView.hpp:56
Index< Rank > lower
Definition: PatchDataView.hpp:57
Definition: PatchDataView.hpp:201
Definition: type_traits.hpp:291
This is equivalent to std::remove_cv_t<std::remove_reference_t<T>>.
Definition: type_traits.hpp:223