Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
MachnumberBoundary.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_MASSFLOW_BOUNDARY2_HPP
22 #define FUB_AMREX_CUTCELL_MASSFLOW_BOUNDARY2_HPP
23 
26 
27 #include "fub/ext/Log.hpp"
28 #include "fub/Direction.hpp"
29 
30 #include <AMReX.H>
31 
32 namespace fub::amrex::cutcell {
33 /// \ingroup BoundaryCondition
34 ///
38 
39  void Print(SeverityLogger& log) const;
40 
41  std::string channel_name{"MachnumberBoundary"};
43  double required_mach_number = 1.0;
45  int side = 0;
46 };
47 
48 /// \ingroup BoundaryCondition
49 ///
50 template <typename EulerEquation> class MachnumberBoundary {
51 public:
53 
54  MachnumberBoundary(const EulerEquation& eq,
55  const MachnumberBoundaryOptions& options);
56 
57  void FillBoundary(::amrex::MultiFab& mf, const GriddingAlgorithm& gridding,
58  int level);
59 
60  void FillBoundary(::amrex::MultiFab& mf, const ::amrex::MultiFab& alphas,
61  const ::amrex::Geometry& geom);
62 
63  void FillBoundary(::amrex::MultiFab& mf, const GriddingAlgorithm& gridding,
64  int level, Direction dir) {
65  if (dir == options_.dir) {
66  FillBoundary(mf, gridding, level);
67  }
68  }
69 
70  void ExpandState(Complete& expanded, const Complete& source);
71 
72 private:
73  EulerEquation equation_;
75 };
76 
77 template <typename EulerEquation>
79  const EulerEquation& eq, const MachnumberBoundaryOptions& options)
80  : equation_{eq}, options_{options} {}
81 
82 template <typename EulerEquation>
84  ::amrex::MultiFab& mf, const GriddingAlgorithm& grid, int level) {
85  auto factory = grid.GetPatchHierarchy().GetEmbeddedBoundary(level);
86  const ::amrex::MultiFab& alphas = factory->getVolFrac();
87  FillBoundary(mf, alphas, grid.GetPatchHierarchy().GetGeometry(level));
88 }
89 
90 template <typename EulerEquation>
92  ::amrex::MultiFab& mf, const ::amrex::MultiFab& alphas,
93  const ::amrex::Geometry& geom) {
94  Complete state{equation_};
95  Complete expanded{equation_};
96  ForEachFab(execution::seq, mf, [&](const ::amrex::MFIter& mfi) {
97  ::amrex::FArrayBox& fab = mf[mfi];
98  const ::amrex::FArrayBox& alpha = alphas[mfi];
99  ::amrex::Box box_to_fill =
100  mfi.growntilebox() & options_.boundary_section;
101  if (!box_to_fill.isEmpty()) {
102  auto states = MakeView<Complete>(fab, equation_, mfi.growntilebox());
103  ForEachIndex(
104  AsIndexBox<EulerEquation::Rank()>(box_to_fill), [&](auto... is) {
105  Index<EulerEquation::Rank()> dest{is...};
106  Index<EulerEquation::Rank()> src =
107  MapToSrc(dest, geom, options_.side, options_.dir);
108  ::amrex::IntVect src_iv{
109  AMREX_D_DECL(int(src[0]), int(src[1]), int(src[2]))};
110  ::amrex::IntVect iv{
111  AMREX_D_DECL(int(dest[0]), int(dest[1]), int(dest[2]))};
112  if (alpha(iv) > 0.0 && alpha(src_iv) > 0.0) {
113  Load(state, states, src);
114  ExpandState(expanded, state);
115  Store(states, expanded, dest);
116  }
117  });
118  }
119  });
120 }
121 
122 template <typename EulerEquation>
124  const Complete& source) {
125  Primitive<EulerEquation> prim(equation_);
126  PrimFromComplete(equation_, prim, source);
127  const double rho = euler::Density(equation_, source);
128  const double p = euler::Pressure(equation_, source);
129  const double gamma = euler::Gamma(equation_, source);
130  const double c = euler::SpeedOfSound(equation_, source);
131  const double c2 = c*c;
132  const int dir_v = static_cast<int>(options_.dir);
133  const double u = prim.velocity[dir_v];
134  const double u2 = u * u;
135  const double Ma2 = u2 / c2;
136 
137  const double gammaMinus = gamma - 1.0;
138  const double gammaPlus = gamma + 1.0;
139 
140  // compute total pressure and total density
141  const double p_0 = p * std::pow(1.0 + 0.5 * Ma2 * gammaMinus, gamma / gammaMinus);
142  const double rho_0 = rho * std::pow(1.0 + 0.5 * Ma2 * gammaMinus, 1.0 / gammaMinus);
143 
144  const double Ma_r = options_.required_mach_number;
145  const double Ma2_r = Ma_r * Ma_r;
146  const double laval2_n = Ma2_r * gammaPlus / (Ma2_r * gammaMinus + 2.0);
147 
148  // Use required laval number to determine new static values
149  const double p_n = p_0 * std::pow(1.0 - gammaMinus / gammaPlus * laval2_n, gamma / gammaMinus);
150  const double rho_n = rho_0 * std::pow(1.0 - gammaMinus / gammaPlus * laval2_n, 1.0 / gammaPlus);
151  prim.density = rho_n;
152  prim.pressure = p_n;
153 
154  const double c2_critical = (c2 + 0.5 * gammaMinus * u2) * 2.0 / gammaPlus;
155  const double u2_n = laval2_n * c2_critical;
156  prim.velocity[dir_v] = std::sqrt(u2_n);
157  CompleteFromPrim(equation_, expanded, prim);
158 }
159 
160 } // namespace fub::amrex::cutcell
161 
162 #endif // !FUB_AMREX_CUTCELL_ISENTROPIC_PRESSURE_BOUNDARY_HPP
This class modifies and initializes a cutcell::PatchLevel in a cutcell::PatchHierarchy.
Definition: AMReX/cutcell/GriddingAlgorithm.hpp:56
const PatchHierarchy & GetPatchHierarchy() const noexcept
Definition: MachnumberBoundary.hpp:50
void FillBoundary(::amrex::MultiFab &mf, const GriddingAlgorithm &gridding, int level)
Definition: MachnumberBoundary.hpp:83
MachnumberBoundary(const EulerEquation &eq, const MachnumberBoundaryOptions &options)
Definition: MachnumberBoundary.hpp:78
MachnumberBoundaryOptions options_
Definition: MachnumberBoundary.hpp:74
void ExpandState(Complete &expanded, const Complete &source)
Definition: MachnumberBoundary.hpp:123
void FillBoundary(::amrex::MultiFab &mf, const GriddingAlgorithm &gridding, int level, Direction dir)
Definition: MachnumberBoundary.hpp:63
EulerEquation equation_
Definition: MachnumberBoundary.hpp:73
const std::shared_ptr<::amrex::EBFArrayBoxFactory > & GetEmbeddedBoundary(int level) const
Returns the number of cycles done for a specific level.
const ::amrex::Geometry & GetGeometry(int level) const
Returns the number of cycles done for a specific level.
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
void ExpandState(EulerEquation &eq, Complete< EulerEquation > &dest, const Complete< EulerEquation > &src, double pressure_dest, double efficiency)
Definition: boundary_condition/IsentropicPressureExpansion.hpp:71
constexpr struct fub::euler::SpeedOfSoundFn SpeedOfSound
constexpr struct fub::euler::GammaFn Gamma
constexpr struct fub::euler::PressureFn Pressure
constexpr struct fub::euler::DensityFn Density
constexpr SequentialTag seq
Definition: Execution.hpp:31
void PrimFromComplete(const PerfectGas< Rank > &, Primitive< PerfectGas< Rank >> &prim, const Complete< PerfectGas< Rank >> &complete)
Definition: PerfectGas.hpp:322
void CompleteFromPrim(const PerfectGas< Rank > &equation, Complete< PerfectGas< Rank >> &complete, const Primitive< PerfectGas< Rank >> &prim)
Definition: PerfectGas.hpp:314
boost::log::sources::severity_logger< boost::log::trivial::severity_level > SeverityLogger
Definition: Log.hpp:46
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
std::map< std::string, pybind11::object > ProgramOptions
Definition: ProgramOptions.hpp:40
Definition: MachnumberBoundary.hpp:35
std::string channel_name
Definition: MachnumberBoundary.hpp:41
double required_mach_number
Definition: MachnumberBoundary.hpp:43
int side
Definition: MachnumberBoundary.hpp:45
::amrex::Box boundary_section
Definition: MachnumberBoundary.hpp:42
void Print(SeverityLogger &log) const
MachnumberBoundaryOptions(const ProgramOptions &options)
Direction dir
Definition: MachnumberBoundary.hpp:44