ThunderEgg  1.0.0
ComponentView.h
Go to the documentation of this file.
1 /***************************************************************************
2  * ThunderEgg, a library for solvers on adaptively refined block-structured
3  * Cartesian grids.
4  *
5  * Copyright (c) 2021 Scott Aiton
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <https://www.gnu.org/licenses/>.
19  ***************************************************************************/
20 
21 #ifndef THUNDEREGG_COMPONENTVIEW_H
22 #define THUNDEREGG_COMPONENTVIEW_H
23 
28 #include <ThunderEgg/Face.h>
29 #include <ThunderEgg/View.h>
30 #include <memory>
31 namespace ThunderEgg {
37 template<typename T, int D>
38 class ComponentView : public View<T, D>
39 {
40 private:
41  template<int M>
42  struct SliceInfo
43  {
44  std::array<int, M> strides;
45  std::array<int, M> ghost_start;
46  std::array<int, M> start;
47  std::array<int, M> end;
48  std::array<int, M> ghost_end;
49  std::array<int, D> first_value;
50  };
51 
55  template<int M>
56  static std::array<int, M> DetermineGhostStart(int num_ghost_cells)
57  {
58  std::array<int, M> start;
59  start.fill(-num_ghost_cells);
60  return start;
61  }
62 
66  template<int M>
67  static std::array<int, M> DetermineStart()
68  {
69  std::array<int, M> start;
70  start.fill(0);
71  return start;
72  }
73 
77  template<int M>
78  static std::array<int, M> DetermineEnd(const std::array<int, M>& lengths)
79  {
80  std::array<int, M> end = lengths;
81  Loop::Unroll<0, M - 1>([&](int i) { end[i]--; });
82  return end;
83  }
84 
88  template<int M>
89  static std::array<int, M> DetermineGhostEnd(const std::array<int, M>& lengths,
90  int num_ghost_cells)
91  {
92  std::array<int, M> end = lengths;
93  Loop::Unroll<0, M - 1>([&](int i) { end[i] += num_ghost_cells - 1; });
94  return end;
95  }
96 
105  template<int M>
106  SliceInfo<M> getSliceOnPriv(Face<D, M> f, const std::array<int, D - M>& offset) const
107  {
108  SliceInfo<M> info;
109 
110  info.first_value = this->getGhostStart();
111 
112  std::array<Side<D>, D - M> sides = f.getSides();
113  size_t lengths_index = 0;
114  size_t sides_index = 0;
115 
116  for (size_t axis = 0; axis < (size_t)D; axis++) {
117  if (sides_index < sides.size() && sides[sides_index].getAxisIndex() == axis) {
118  if (sides[sides_index].isLowerOnAxis()) {
119  info.first_value[axis] = offset[sides_index];
120  } else {
121  info.first_value[axis] = this->getEnd()[axis] - offset[sides_index];
122  }
123  sides_index++;
124  } else {
125  info.strides[lengths_index] = this->getStrides()[axis];
126  info.ghost_start[lengths_index] = this->getGhostStart()[axis];
127  info.start[lengths_index] = this->getStart()[axis];
128  info.end[lengths_index] = this->getEnd()[axis];
129  info.ghost_end[lengths_index] = this->getGhostEnd()[axis];
130  lengths_index++;
131  }
132  }
133  return info;
134  }
135 
136 public:
137  using T_ptr = typename View<T, D>::T_ptr;
142  : View<T, D>()
143  {}
144 
154  ComponentView(T_ptr data,
155  const std::array<int, D>& strides,
156  const std::array<int, D>& ghost_start,
157  const std::array<int, D>& start,
158  const std::array<int, D>& end,
159  const std::array<int, D>& ghost_end)
160  : View<T, D>(data, strides, ghost_start, start, end, ghost_end)
161  {}
162 
172  ComponentView(T_ptr data,
173  const std::array<int, D>& strides,
174  const std::array<int, D>& lengths,
175  int num_ghost_cells)
176  : View<T, D>(data,
177  strides,
178  DetermineGhostStart<D>(num_ghost_cells),
179  DetermineStart<D>(),
180  DetermineEnd<D>(lengths),
181  DetermineGhostEnd<D>(lengths, num_ghost_cells))
182  {}
183 
193  template<int M>
194  View<T, M> getSliceOn(Face<D, M> f, const std::array<int, D - M>& offset) const
195  {
196  SliceInfo<M> info = getSliceOnPriv<M>(f, offset);
197 
198  T_ptr new_data = (&(*this)[info.first_value]);
199  return View<T, M>(
200  new_data, info.strides, info.ghost_start, info.start, info.end, info.ghost_end);
201  }
202 
212  template<int M>
214  Face<D, M> f,
215  const std::array<size_t, D - M>& offset) const
216  {
217  using noconst_T = typename std::remove_const<T>::type;
218  using noconst_T_ptr = typename std::add_pointer<noconst_T>::type;
219  std::array<int, M> new_strides;
220  std::array<int, M> new_ghost_start;
221  std::array<int, M> new_start;
222  std::array<int, M> new_end;
223  std::array<int, M> new_ghost_end;
224  std::array<int, D> first_value;
225 
226  first_value = this->getGhostStart();
227 
228  std::array<Side<D>, D - M> sides = f.getSides();
229  size_t lengths_index = 0;
230  size_t sides_index = 0;
231 
232  for (size_t axis = 0; axis < (size_t)D; axis++) {
233  if (sides_index < sides.size() && sides[sides_index].getAxisIndex() == axis) {
234  if (sides[sides_index].isLowerOnAxis()) {
235  first_value[axis] = -1 - offset[sides_index];
236  } else {
237  first_value[axis] = this->getEnd()[axis] + 1 + offset[sides_index];
238  }
239  sides_index++;
240  } else {
241  new_strides[lengths_index] = this->getStrides()[axis];
242  new_ghost_start[lengths_index] = this->getGhostStart()[axis];
243  new_start[lengths_index] = this->getStart()[axis];
244  new_end[lengths_index] = this->getEnd()[axis];
245  new_ghost_end[lengths_index] = this->getGhostEnd()[axis];
246  lengths_index++;
247  }
248  }
249 
250  noconst_T_ptr new_data = const_cast<noconst_T_ptr>(
251  &(*this)[first_value]); // Thunderegg doesn't care if values in ghosts are modified
252  return View<noconst_T, M>(
253  new_data, new_strides, new_ghost_start, new_start, new_end, new_ghost_end);
254  }
255 
256  operator ComponentView<std::add_const_t<T>, D>() const
257  {
258  return ComponentView<std::add_const_t<T>, D>(this->getData() +
259  this->getIndex(this->getGhostStart()),
260  this->getStrides(),
261  this->getGhostStart(),
262  this->getStart(),
263  this->getEnd(),
264  this->getGhostEnd());
265  }
266 };
267 extern template class ComponentView<double, 1>;
268 extern template View<double, 0>
269 ComponentView<double, 1>::getSliceOn(Face<1, 0>, const std::array<int, 1>&) const;
270 extern template View<double, 0>
271 ComponentView<double, 1>::getGhostSliceOn(Face<1, 0>, const std::array<size_t, 1>&) const;
272 extern template class ComponentView<double, 2>;
273 extern template View<double, 0>
274 ComponentView<double, 2>::getSliceOn(Face<2, 0>, const std::array<int, 2>&) const;
275 extern template View<double, 1>
276 ComponentView<double, 2>::getSliceOn(Face<2, 1>, const std::array<int, 1>&) const;
277 extern template View<double, 0>
278 ComponentView<double, 2>::getGhostSliceOn(Face<2, 0>, const std::array<size_t, 2>&) const;
279 extern template View<double, 1>
280 ComponentView<double, 2>::getGhostSliceOn(Face<2, 1>, const std::array<size_t, 1>&) const;
281 extern template class ComponentView<double, 3>;
282 extern template View<double, 0>
283 ComponentView<double, 3>::getSliceOn(Face<3, 0>, const std::array<int, 3>&) const;
284 extern template View<double, 1>
285 ComponentView<double, 3>::getSliceOn(Face<3, 1>, const std::array<int, 2>&) const;
286 extern template View<double, 2>
287 ComponentView<double, 3>::getSliceOn(Face<3, 2>, const std::array<int, 1>&) const;
288 extern template View<double, 0>
289 ComponentView<double, 3>::getGhostSliceOn(Face<3, 0>, const std::array<size_t, 3>&) const;
290 extern template View<double, 1>
291 ComponentView<double, 3>::getGhostSliceOn(Face<3, 1>, const std::array<size_t, 2>&) const;
292 extern template View<double, 2>
293 ComponentView<double, 3>::getGhostSliceOn(Face<3, 2>, const std::array<size_t, 1>&) const;
294 extern template class ComponentView<const double, 1>;
295 extern template View<const double, 0>
296 ComponentView<const double, 1>::getSliceOn(Face<1, 0>, const std::array<int, 1>&) const;
297 extern template View<double, 0>
298 ComponentView<const double, 1>::getGhostSliceOn(Face<1, 0>, const std::array<size_t, 1>&) const;
299 extern template class ComponentView<const double, 2>;
300 extern template View<const double, 0>
301 ComponentView<const double, 2>::getSliceOn(Face<2, 0>, const std::array<int, 2>&) const;
302 extern template View<const double, 1>
303 ComponentView<const double, 2>::getSliceOn(Face<2, 1>, const std::array<int, 1>&) const;
304 extern template View<double, 0>
305 ComponentView<const double, 2>::getGhostSliceOn(Face<2, 0>, const std::array<size_t, 2>&) const;
306 extern template View<double, 1>
307 ComponentView<const double, 2>::getGhostSliceOn(Face<2, 1>, const std::array<size_t, 1>&) const;
308 extern template class ComponentView<const double, 3>;
309 extern template View<const double, 0>
310 ComponentView<const double, 3>::getSliceOn(Face<3, 0>, const std::array<int, 3>&) const;
311 extern template View<const double, 1>
312 ComponentView<const double, 3>::getSliceOn(Face<3, 1>, const std::array<int, 2>&) const;
313 extern template View<const double, 2>
314 ComponentView<const double, 3>::getSliceOn(Face<3, 2>, const std::array<int, 1>&) const;
315 extern template View<double, 0>
316 ComponentView<const double, 3>::getGhostSliceOn(Face<3, 0>, const std::array<size_t, 3>&) const;
317 extern template View<double, 1>
318 ComponentView<const double, 3>::getGhostSliceOn(Face<3, 1>, const std::array<size_t, 2>&) const;
319 extern template View<double, 2>
320 ComponentView<const double, 3>::getGhostSliceOn(Face<3, 2>, const std::array<size_t, 1>&) const;
321 } // namespace ThunderEgg
322 #endif
ThunderEgg::View
Array for acessing data of a patch. It supports variable striding.
Definition: View.h:40
ThunderEgg::ComponentView::ComponentView
ComponentView(T_ptr data, const std::array< int, D > &strides, const std::array< int, D > &ghost_start, const std::array< int, D > &start, const std::array< int, D > &end, const std::array< int, D > &ghost_end)
Construct a new View object.
Definition: ComponentView.h:154
ThunderEgg::Loop::Unroll
static void Unroll(T lambda)
Unroll a fixed-length loop.
Definition: Loops.h:72
ThunderEgg::ComponentView::ComponentView
ComponentView(T_ptr data, const std::array< int, D > &strides, const std::array< int, D > &lengths, int num_ghost_cells)
Construct a new View object.
Definition: ComponentView.h:172
ThunderEgg::View::getStrides
const std::array< int, D > & getStrides() const
Get the strides of the patch in each direction.
Definition: View.h:203
Face.h
Face class.
ThunderEgg::View::getGhostStart
const std::array< int, D > & getGhostStart() const
Get the coordinate of the first ghost cell element.
Definition: View.h:215
ThunderEgg::ComponentView
Array for acessing data of a patch. It supports variable striding.
Definition: ComponentView.h:38
ThunderEgg::ComponentView::getGhostSliceOn
View< typename std::remove_const< T >::type, M > getGhostSliceOn(Face< D, M > f, const std::array< size_t, D - M > &offset) const
Get the gosts slice on a given face.
Definition: ComponentView.h:213
ThunderEgg::ComponentView::getSliceOn
View< T, M > getSliceOn(Face< D, M > f, const std::array< int, D - M > &offset) const
Get the slice on a given face.
Definition: ComponentView.h:194
ThunderEgg
The ThunderEgg namespace.
Definition: BiLinearGhostFiller.h:31
ThunderEgg::View::getEnd
const std::array< int, D > & getEnd() const
Get the coordinate of the last element.
Definition: View.h:211
ThunderEgg::Face::getSides
std::array< Face< D, D - 1 >, D - M > getSides() const
Get the Sides that this Face lies on.
Definition: Face.h:496
ThunderEgg::Face
Enum-style class for the faces of an n-dimensional cube.
Definition: Face.h:41
View.h
View class.
ThunderEgg::ComponentView::ComponentView
ComponentView()
Construct a new ComponentView with size 0.
Definition: ComponentView.h:141
ThunderEgg::View::getGhostEnd
const std::array< int, D > & getGhostEnd() const
Get the coordinate of the last ghost cell element.
Definition: View.h:219
ThunderEgg::View::getStart
const std::array< int, D > & getStart() const
Get the coordinate of the first element.
Definition: View.h:207