Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
cutcell/Reconstruction.hpp
Go to the documentation of this file.
1 // Copyright (c) 2019 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_AMREX_CUTCELL_RECONSTRUCTION_HPP
22 #define FUB_AMREX_CUTCELL_RECONSTRUCTION_HPP
23 
24 #include "fub/CompleteFromCons.hpp"
25 #include "fub/CutCellData.hpp"
26 #include "fub/Execution.hpp"
27 #include "fub/ForEach.hpp"
28 #include "fub/State.hpp"
29 
30 namespace fub::amrex::cutcell {
31 namespace detail {
32 template <typename Equation, bool IsSimd = true> struct ReconstructionKernel;
33 }
34 
35 template <typename Tag, typename Equation> struct Reconstruction {
36  static constexpr int Rank = Equation::Rank();
37  static constexpr bool IsSimd = std::is_base_of<execution::SimdTag, Tag>();
38 
39  explicit Reconstruction(const Equation& eq) : Reconstruction(Tag(), eq) {}
40  Reconstruction(const Tag& tag, const Equation& eq);
41 
42  void CompleteFromCons(IntegratorContext& context, int level,
43  [[maybe_unused]] Duration dt);
44 
46 };
47 
48 template <typename Equation>
50  ->Reconstruction<execution::OpenMpSimdTag, Equation>;
51 
52 ////////////////////////////////////////////////////////////////////////////////
53 // Implementation
54 
55 namespace detail {
56 // Scalar Case
57 template <typename Equation, bool IsSimd> struct ReconstructionKernel {
58  Equation equation_;
59  Complete<Equation> complete_{equation_};
60  Conservative<Equation> cons_{equation_};
61 
62  static constexpr int Rank = Equation::Rank();
63 
64  void CompleteFromCons(const View<Complete<Equation>>& dest,
65  const View<const Conservative<Equation>>& src) {
66  ForEachIndex(Box<0>(dest), [&](auto... is) {
67  Load(cons_, src, {is...});
68  ::fub::CompleteFromCons(equation_, complete_, cons_);
69  Store(dest, complete_, {is...});
70  });
71  }
72 
73  void CompleteFromCons(
74  const View<Complete<Equation>>& dest,
75  const View<const Conservative<Equation>>& src,
77  ForEachIndex(Box<0>(dest), [&](auto... is) {
78  const double alpha = volume(is...);
79  if (alpha > 0.0) {
80  Load(cons_, src, {is...});
81  ::fub::CompleteFromCons(equation_, complete_, cons_);
82  Store(dest, complete_, {is...});
83  }
84  });
85  }
86 };
87 
88 // SIMD Case
89 template <typename Equation> struct ReconstructionKernel<Equation, true> {
90  Equation equation_;
91  CompleteArray<Equation> complete_{equation_};
92  ConservativeArray<Equation> cons_{equation_};
93 
94  static constexpr int Rank = Equation::Rank();
95 
96  void CompleteFromCons(const View<Complete<Equation>>& dest,
97  const View<const Conservative<Equation>>& src) {
98  ForEachRow(std::tuple{dest, src},
99  [&](const Row<Complete<Equation>>& dest,
100  const Row<const Conservative<Equation>>& src) {
104  constexpr std::ptrdiff_t size =
105  static_cast<std::ptrdiff_t>(kDefaultChunkSize);
106  std::ptrdiff_t n = get<0>(last) - get<0>(first);
107  while (n >= size) {
108  Load(cons_, first);
109  ::fub::CompleteFromCons(equation_, complete_, cons_);
110  Store(out, complete_);
111  Advance(first, size);
112  Advance(out, size);
113  n = get<0>(last) - get<0>(first);
114  }
115  LoadN(cons_, first, static_cast<int>(n));
116  ::fub::CompleteFromCons(equation_, complete_, cons_);
117  StoreN(out, complete_, static_cast<int>(n));
118  });
119  }
120 
121  void CompleteFromCons(
122  const View<Complete<Equation>>& dest,
123  const View<const Conservative<Equation>>& src,
125  ForEachRow(std::tuple{dest, src, volume},
126  [&](const Row<Complete<Equation>>& dest,
128  span<const double> volume) {
132  Array1d alpha = Array1d::Zero();
133  constexpr std::ptrdiff_t size =
134  static_cast<std::ptrdiff_t>(kDefaultChunkSize);
135  std::ptrdiff_t n = get<0>(last) - get<0>(first);
136  while (n >= size) {
137  Load(cons_, first);
138  alpha = Array1d::Map(volume.data());
139  MaskArray mask = alpha > 0.0;
140  ::fub::CompleteFromCons(equation_, complete_, cons_, mask);
141  Store(out, complete_);
142  Advance(first, size);
143  Advance(out, size);
144  volume = volume.subspan(size);
145  n = get<0>(last) - get<0>(first);
146  }
147  LoadN(cons_, first, static_cast<int>(n));
148  std::copy_n(volume.data(), n, alpha.data());
149  std::fill_n(alpha.data() + n, size - n, 0.0);
150  MaskArray mask = alpha > 0.0;
151  ::fub::CompleteFromCons(equation_, complete_, cons_, mask);
152  StoreN(out, complete_, static_cast<int>(n));
153  });
154  }
155 };
156 } // namespace detail
157 
158 template <typename Tag, typename Equation>
160  : kernel_() {
161 
163  detail::ReconstructionKernel<Equation, IsSimd>{eq}};
164 }
165 
166 template <typename Tag, typename Equation>
168  int level, Duration) {
169  ::amrex::MultiFab& dest = context.GetScratch(level);
170  const ::amrex::MultiFab& volumes =
171  context.GetEmbeddedBoundary(level).getVolFrac();
172  const ::amrex::MultiFab& src = context.GetScratch(level);
173 
174  ForEachFab(Tag(), dest, [&](const ::amrex::MFIter& mfi) {
175  const ::amrex::Box box = mfi.growntilebox();
176  auto state =
177  MakeView<Complete<Equation>>(dest[mfi], kernel_->equation_, box);
178  auto scratch = MakeView<const Conservative<Equation>>(
179  src[mfi], kernel_->equation_, box);
180  ::amrex::FabType type =
181  context.GetEmbeddedBoundary(level).getMultiEBCellFlagFab()[mfi].getType(
182  box);
183  if (type == ::amrex::FabType::regular) {
184  kernel_->CompleteFromCons(state, scratch);
185  } else if (type == ::amrex::FabType::singlevalued) {
186  auto volume = MakePatchDataView(volumes[mfi], 0, box);
187  kernel_->CompleteFromCons(state, scratch, volume);
188  }
189  });
190 }
191 
192 } // namespace fub::amrex::cutcell
193 
194 #endif
This class manages data and the numerical method to perform cut cell simulations with the AMReX libra...
Definition: AMReX/cutcell/IntegratorContext.hpp:46
::amrex::MultiFab & GetScratch(int level)
Returns the MultiFab associated with level data with ghost cells on the specifed level number and dir...
::amrex::EBFArrayBoxFactory & GetEmbeddedBoundary(int level)
Returns the current boundary condition for the specified level.
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
void CompleteFromCons(Equation &&equation, Complete< std::decay_t< Equation >> &complete, const Conservative< std::decay_t< Equation >> &cons)
Definition: CompleteFromCons.hpp:42
void ForEachFab(Tag, const ::amrex::FabArrayBase &fabarray, F function)
Iterate through all local FArrayBox objects in a MultiFab.
Definition: ForEachFab.hpp:34
Definition: FillCutCellData.hpp:30
Reconstruction(const Equation &) -> Reconstruction< execution::OpenMpSimdTag, Equation >
void ForEachIndex(const ::amrex::Box &box, F function)
Definition: ForEachIndex.hpp:29
PatchDataView< T, AMREX_SPACEDIM+1 > MakePatchDataView(::amrex::BaseFab< T > &fab)
Definition: ViewFArrayBox.hpp:86
std::decay_t< decltype(std::declval< T >().GetEquation())> Equation
A template typedef to detect the member function.
Definition: Meta.hpp:59
std::chrono::duration< double > Duration
Definition: Duration.hpp:31
Array< double, 1 > Array1d
Definition: Eigen.hpp:53
constexpr const int kDefaultChunkSize
Definition: Eigen.hpp:39
void StoreN(nodeduce_t< ViewPointer< Conservative< Eq >>> pointer, const ConservativeArray< Eq > &state, int n)
Definition: StateArray.hpp:416
void ForEachRow(const Tuple &views, Function f)
Definition: StateRow.hpp:172
void Load(State &state, const BasicView< const State, Layout, Rank > &view, const std::array< std::ptrdiff_t, State::Equation::Rank()> &index)
Definition: State.hpp:640
ViewPointer< State > Begin(const BasicView< State, Layout, Rank > &view)
Definition: State.hpp:769
void LoadN(CompleteArray< Eq, N > &state, const BasicView< const Complete< Eq >, Layout, Rank > &view, int size, nodeduce_t< const std::array< std::ptrdiff_t, std::size_t(Rank)> & > pos)
Definition: StateArray.hpp:310
void Advance(ViewPointer< State > &pointer, std::ptrdiff_t n) noexcept
Definition: State.hpp:825
void Store(const BasicView< Conservative< Eq >, Layout, Eq::Rank()> &view, const Conservative< Eq > &state, const std::array< std::ptrdiff_t, Eq::Rank()> &index)
Definition: State.hpp:663
ViewPointer< State > End(const BasicView< State, Layout, Rank > &view)
Definition: State.hpp:782
Array< bool, 1 > MaskArray
Definition: Eigen.hpp:59
IndexBox< Rank > Box(const BasicView< State, Layout, Rank > &view)
Definition: State.hpp:486
typename detail::LocalType< Tag, T >::type Local
Definition: Execution.hpp:56
Definition: State.hpp:403
Definition: PatchDataView.hpp:201
Definition: StateRow.hpp:51
Definition: State.hpp:750
Definition: cutcell/Reconstruction.hpp:35
Local< Tag, detail::ReconstructionKernel< Equation, IsSimd > > kernel_
Definition: cutcell/Reconstruction.hpp:45
Reconstruction(const Equation &eq)
Definition: cutcell/Reconstruction.hpp:39
static constexpr int Rank
Definition: cutcell/Reconstruction.hpp:36
static constexpr bool IsSimd
Definition: cutcell/Reconstruction.hpp:37
void CompleteFromCons(IntegratorContext &context, int level, [[maybe_unused]] Duration dt)
Definition: Execution.hpp:39