Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
MultiBlockBoundary2.hpp
Go to the documentation of this file.
1 // Copyright (c) 2020 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_MULTI_BLOCK_BOUNDARY2_HPP
22 #define FUB_AMREX_MULTI_BLOCK_BOUNDARY2_HPP
23 
25 
26 #include "fub/Direction.hpp"
27 #include "fub/Duration.hpp"
28 #include "fub/PatchDataView.hpp"
29 
30 #include <AMReX.H>
31 #include <AMReX_MultiFab.H>
32 
33 #include <vector>
34 
35 namespace fub::amrex {
36 
37 class MultiBlockGriddingAlgorithm2;
38 
39 /// \ingroup BoundaryCondition
40 ///
42  virtual void
43  FillTubeGhostLayer(::amrex::FArrayBox& tube_ghost_data,
44  const ::amrex::FArrayBox& plenum_mirror_data) = 0;
45  virtual void
46  FillPlenumGhostLayer(::amrex::FArrayBox& plenum_ghost_data,
47  const ::amrex::FArrayBox& tube_mirror_data) = 0;
48 
49  virtual std::unique_ptr<MultiBlockBoundaryBase> Clone() const = 0;
50 };
51 
52 template <typename Boundary>
54  MultiBlockBoundaryWrapper(const Boundary& impl) : impl_(std::make_unique<Boundary>(impl)) {}
55  MultiBlockBoundaryWrapper(Boundary&& impl) : impl_(std::make_unique<Boundary>(std::move(impl))) {}
56 
57  std::unique_ptr<MultiBlockBoundaryBase> Clone() const override final {
58  return std::make_unique<MultiBlockBoundaryWrapper>(*impl_);
59  }
60 
62  ::amrex::FArrayBox& tube_ghost_data,
63  const ::amrex::FArrayBox& plenum_mirror_data) override final {
64  impl_->FillTubeGhostLayer(tube_ghost_data, plenum_mirror_data);
65  }
67  ::amrex::FArrayBox& plenum_ghost_data,
68  const ::amrex::FArrayBox& tube_mirror_data) override final {
69  impl_->FillPlenumGhostLayer(plenum_ghost_data, tube_mirror_data);
70  }
71 
72  std::unique_ptr<Boundary> impl_;
73 };
74 
75 /// \ingroup BoundaryCondition
76 ///
78 public:
79  /// Constructs coupled boundary states by pre computing mirror and ghost
80  /// states for each of the specified domains.
81  ///
82  /// This function might grow the specified mirror boxes to an extent which is
83  /// required to fulfill the specified ghost cell width requirements.
84  template <typename Boundary>
85  AnyMultiBlockBoundary(Boundary boundary,
86  const MultiBlockGriddingAlgorithm2& gridding,
87  const BlockConnection& connection, int gcw, int level)
88  : impl_(std::make_unique<MultiBlockBoundaryWrapper<Boundary>>(
89  std::move(boundary))),
90  dir_{connection.direction}, side_{connection.side}, level_{level},
91  gcw_{gcw} {
92  Initialize(gridding, connection, gcw, level);
93  }
94 
96 
97  /// Precompute Boundary states for each domain.
98  ///
99  /// Subsequent calls to FillBoundary will use these computed boundary states.
100  ///
101  /// \param[in] plenum The higher dimensional patch hierarchy with geometry
102  /// information. States here will be conservatively averaged and projected
103  /// onto a one-dimesnional space.
104  ///
105  /// \param[in] tube The low dimensional tube data.
107  const PatchHierarchy& tube);
108 
109  /// Assuming that mf represents a MultiFab living in the higher dimensional
110  /// plenum simulation its ghost layer will be filled with data from the tube
111  /// simulation.
112  void FillBoundary(::amrex::MultiFab& mf,
113  const cutcell::GriddingAlgorithm& gridding, int level);
114 
115  void FillBoundary(::amrex::MultiFab& mf,
116  const cutcell::GriddingAlgorithm& gridding, int level,
117  Direction dir) {
118  if (dir == dir_) {
119  FillBoundary(mf, gridding, level);
120  }
121  }
122 
123  /// Assuming that mf represents a MultiFab living in the one dimensional tube
124  /// simulation its ghost layer will be filled with data from the plenum
125  /// simulation.
126  void FillBoundary(::amrex::MultiFab& mf, const GriddingAlgorithm& gridding,
127  int level);
128 
129  void FillBoundary(::amrex::MultiFab& mf, const GriddingAlgorithm& gridding,
130  int level, Direction dir) {
131  if (dir == dir_) {
132  FillBoundary(mf, gridding, level);
133  }
134  }
135 
136 private:
138  const BlockConnection& connection, int gcw, int level);
139 
140  std::unique_ptr<MultiBlockBoundaryBase> impl_;
141 
144 
145  std::unique_ptr<::amrex::FArrayBox> plenum_mirror_data_{};
146  std::unique_ptr<::amrex::FArrayBox> tube_ghost_data_{};
147 
148  std::unique_ptr<::amrex::FArrayBox> tube_mirror_data_{};
149  std::unique_ptr<::amrex::FArrayBox> plenum_ghost_data_{};
150 
152  int side_{};
153  int level_{};
154  int gcw_{};
155 };
156 
157 template <typename TubeEquation, typename PlenumEquation>
158 void ReduceStateDimension(TubeEquation& tube_equation,
160  PlenumEquation& /* plenum_equation */,
161  const Conservative<PlenumEquation>& src) {
162  dest.density = src.density;
163  for (int i = 0; i < dest.momentum.size(); ++i) {
164  dest.momentum[i] = src.momentum[i];
165  }
166  dest.species = src.species;
167  dest.energy = src.energy;
168  CompleteFromCons(tube_equation, dest, AsCons(dest));
169 }
170 
171 template <typename PlenumEquation, typename TubeEquation>
172 void EmbedState(PlenumEquation& plenum_equation, Complete<PlenumEquation>& dest,
173  TubeEquation& /* tube_equation */,
174  const Conservative<TubeEquation>& src) {
175  dest.density = src.density;
176  dest.momentum.setZero();
177  for (int i = 0; i < src.momentum.size(); ++i) {
178  dest.momentum[i] = src.momentum[i];
179  }
180  dest.species = src.species;
181  dest.energy = src.energy;
182  CompleteFromCons(plenum_equation, dest, AsCons(dest));
183 }
184 
185 template <typename TubeEquation, typename PlenumEquation>
187  static_assert(TubeEquation::Rank() <= PlenumEquation::Rank());
188 
189  MultiBlockBoundary2(const TubeEquation& tube_equation,
190  const PlenumEquation& plenum_equation)
191  : tube_equation_(tube_equation), plenum_equation_(plenum_equation) {}
192 
196 
197  TubeEquation tube_equation_;
198  PlenumEquation plenum_equation_;
199 
201  ::amrex::FArrayBox& tube_ghost_data,
202  const ::amrex::FArrayBox& plenum_mirror_data) {
203  BasicView cons_states = MakeView<const Conservative<PlenumEquation>>(
204  plenum_mirror_data, plenum_equation_);
205  BasicView complete_states =
206  MakeView<Complete<TubeEquation>>(tube_ghost_data, tube_equation_);
209  const std::ptrdiff_t i0 = plenum_mirror_data.box().smallEnd(0);
210  const std::ptrdiff_t j0 = tube_ghost_data.box().smallEnd(0);
211  ForEachIndex(Box<0>(complete_states), [&](std::ptrdiff_t j) {
212  const std::ptrdiff_t k = j - j0;
213  const std::ptrdiff_t i = i0 + k;
214  Load(cons, cons_states, {i});
215  if (cons.density > 0.0) {
217  Store(complete_states, complete, {j});
218  }
219  });
220  }
221 
223  ::amrex::FArrayBox& plenum_ghost_data,
224  const ::amrex::FArrayBox& tube_mirror_data) {
225  BasicView cons_states =
226  MakeView<const Conservative<TubeEquation>>(tube_mirror_data, tube_equation_);
227  BasicView complete_states =
228  MakeView<Complete<PlenumEquation>>(plenum_ghost_data, plenum_equation_);
231  const std::ptrdiff_t i0 = Box<0>(cons_states).lower[0];
232  const std::ptrdiff_t j0 = Box<0>(complete_states).lower[0];
233  ForEachIndex(Box<0>(cons_states), [&](std::ptrdiff_t i) {
234  const std::ptrdiff_t k = i - i0;
235  const std::ptrdiff_t j = j0 + k;
236  Load(cons, cons_states, {i});
237  if (cons.density > 0.0) {
238  EmbedState(plenum_equation_, complete, tube_equation_, cons);
239  Store(complete_states, complete, {j});
240  }
241  });
242  }
243 };
244 
245 } // namespace fub::amrex
246 
247 #endif
Definition: MultiBlockBoundary2.hpp:77
void FillBoundary(::amrex::MultiFab &mf, const cutcell::GriddingAlgorithm &gridding, int level, Direction dir)
Definition: MultiBlockBoundary2.hpp:115
int gcw_
Definition: MultiBlockBoundary2.hpp:154
void FillBoundary(::amrex::MultiFab &mf, const cutcell::GriddingAlgorithm &gridding, int level)
Assuming that mf represents a MultiFab living in the higher dimensional plenum simulation its ghost l...
AnyMultiBlockBoundary(Boundary boundary, const MultiBlockGriddingAlgorithm2 &gridding, const BlockConnection &connection, int gcw, int level)
Constructs coupled boundary states by pre computing mirror and ghost states for each of the specified...
Definition: MultiBlockBoundary2.hpp:85
std::unique_ptr<::amrex::FArrayBox > plenum_mirror_data_
Definition: MultiBlockBoundary2.hpp:145
int level_
Definition: MultiBlockBoundary2.hpp:153
void FillBoundary(::amrex::MultiFab &mf, const GriddingAlgorithm &gridding, int level)
Assuming that mf represents a MultiFab living in the one dimensional tube simulation its ghost layer ...
Direction dir_
Definition: MultiBlockBoundary2.hpp:151
::amrex::Box plenum_mirror_box_
Definition: MultiBlockBoundary2.hpp:142
AnyMultiBlockBoundary(const AnyMultiBlockBoundary &other)
void ComputeBoundaryData(const cutcell::PatchHierarchy &plenum, const PatchHierarchy &tube)
Precompute Boundary states for each domain.
::amrex::Box tube_mirror_box_
Definition: MultiBlockBoundary2.hpp:143
std::unique_ptr<::amrex::FArrayBox > tube_ghost_data_
Definition: MultiBlockBoundary2.hpp:146
void Initialize(const MultiBlockGriddingAlgorithm2 &gridding, const BlockConnection &connection, int gcw, int level)
void FillBoundary(::amrex::MultiFab &mf, const GriddingAlgorithm &gridding, int level, Direction dir)
Definition: MultiBlockBoundary2.hpp:129
int side_
Definition: MultiBlockBoundary2.hpp:152
std::unique_ptr<::amrex::FArrayBox > tube_mirror_data_
Definition: MultiBlockBoundary2.hpp:148
std::unique_ptr< MultiBlockBoundaryBase > impl_
Definition: MultiBlockBoundary2.hpp:140
std::unique_ptr<::amrex::FArrayBox > plenum_ghost_data_
Definition: MultiBlockBoundary2.hpp:149
This class modifies and initializes a PatchLevel in a PatchHierarchy.
Definition: AMReX/GriddingAlgorithm.hpp:60
Definition: MultiBlockGriddingAlgorithm2.hpp:37
The PatchHierarchy holds simulation data on multiple refinement levels.
Definition: AMReX/PatchHierarchy.hpp:156
This class modifies and initializes a cutcell::PatchLevel in a cutcell::PatchHierarchy.
Definition: AMReX/cutcell/GriddingAlgorithm.hpp:56
Definition: AMReX/cutcell/PatchHierarchy.hpp:139
void CompleteFromCons(Equation &&equation, Complete< std::decay_t< Equation >> &complete, const Conservative< std::decay_t< Equation >> &cons)
Definition: CompleteFromCons.hpp:42
The amrex namespace.
Definition: AverageState.hpp:33
void ForEachIndex(const ::amrex::Box &box, F function)
Definition: ForEachIndex.hpp:29
void ReduceStateDimension(TubeEquation &tube_equation, Complete< TubeEquation > &dest, PlenumEquation &, const Conservative< PlenumEquation > &src)
Definition: MultiBlockBoundary2.hpp:158
void EmbedState(PlenumEquation &plenum_equation, Complete< PlenumEquation > &dest, TubeEquation &, const Conservative< TubeEquation > &src)
Definition: MultiBlockBoundary2.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
Direction
This is a type safe type to denote a dimensional split direction.
Definition: Direction.hpp:30
const Conservative< Eq > & AsCons(const Conservative< Eq > &x)
Definition: State.hpp:438
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
IndexBox< Rank > Box(const BasicView< State, Layout, Rank > &view)
Definition: State.hpp:486
Definition: State.hpp:403
This type has a constructor which takes an equation and might allocate any dynamically sized member v...
Definition: State.hpp:335
This type has a constructor which takes an equation and might allocate any dynamically sized member v...
Definition: State.hpp:251
Definition: MultiBlockBoundary.hpp:54
Definition: MultiBlockBoundary2.hpp:186
void FillTubeGhostLayer(::amrex::FArrayBox &tube_ghost_data, const ::amrex::FArrayBox &plenum_mirror_data)
Definition: MultiBlockBoundary2.hpp:200
PlenumEquation plenum_equation_
Definition: MultiBlockBoundary2.hpp:198
MultiBlockBoundary2(const MultiBlockBoundary2 &other)
Definition: MultiBlockBoundary2.hpp:193
void FillPlenumGhostLayer(::amrex::FArrayBox &plenum_ghost_data, const ::amrex::FArrayBox &tube_mirror_data)
Definition: MultiBlockBoundary2.hpp:222
TubeEquation tube_equation_
Definition: MultiBlockBoundary2.hpp:197
MultiBlockBoundary2(const TubeEquation &tube_equation, const PlenumEquation &plenum_equation)
Definition: MultiBlockBoundary2.hpp:189
Definition: MultiBlockBoundary2.hpp:41
virtual void FillPlenumGhostLayer(::amrex::FArrayBox &plenum_ghost_data, const ::amrex::FArrayBox &tube_mirror_data)=0
virtual void FillTubeGhostLayer(::amrex::FArrayBox &tube_ghost_data, const ::amrex::FArrayBox &plenum_mirror_data)=0
virtual std::unique_ptr< MultiBlockBoundaryBase > Clone() const =0
Definition: MultiBlockBoundary2.hpp:53
std::unique_ptr< MultiBlockBoundaryBase > Clone() const override final
Definition: MultiBlockBoundary2.hpp:57
MultiBlockBoundaryWrapper(Boundary &&impl)
Definition: MultiBlockBoundary2.hpp:55
std::unique_ptr< Boundary > impl_
Definition: MultiBlockBoundary2.hpp:72
MultiBlockBoundaryWrapper(const Boundary &impl)
Definition: MultiBlockBoundary2.hpp:54
void FillPlenumGhostLayer(::amrex::FArrayBox &plenum_ghost_data, const ::amrex::FArrayBox &tube_mirror_data) override final
Definition: MultiBlockBoundary2.hpp:66
void FillTubeGhostLayer(::amrex::FArrayBox &tube_ghost_data, const ::amrex::FArrayBox &plenum_mirror_data) override final
Definition: MultiBlockBoundary2.hpp:61