Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
GenericPressureValveBoundary.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_BOUNDARY_CONDITION_GENERIC_PRESSURE_VALVE_HPP
22 #define FUB_AMREX_BOUNDARY_CONDITION_GENERIC_PRESSURE_VALVE_HPP
23 
28 
29 #include "fub/ext/Log.hpp"
30 
31 namespace fub::amrex {
32 
34  std::string prefix{"GenericPressureValve"};
36  int side{0};
37 };
38 
40  template <typename EulerEquation>
41  [[nodiscard]] std::optional<Duration>
42  operator()(EulerEquation& equation, std::optional<Duration> t_opened,
43  double inner_pressure,
44  const KineticState<EulerEquation>& compressor_state,
45  const GriddingAlgorithm& gridding, int) const noexcept {
46  const double p_ref = euler::Pressure(equation, compressor_state);
47  if (!t_opened && inner_pressure <= p_ref) {
48  t_opened = gridding.GetTimePoint();
49  } else if (inner_pressure > 1.1 * p_ref) {
50  t_opened.reset();
51  }
52  return t_opened;
53  }
54 };
55 
57  template <typename EulerEquation>
58  [[nodiscard]] std::optional<Duration>
59  operator()(EulerEquation& equation, std::optional<Duration> t_opened,
60  double inner_pressure,
61  const KineticState<EulerEquation>& compressor_state,
62  const GriddingAlgorithm& gridding, int) const noexcept {
63  if (!t_opened &&
64  inner_pressure <= euler::Pressure(equation, compressor_state)) {
65  t_opened = gridding.GetTimePoint();
66  } else {
67  t_opened.reset();
68  }
69  return t_opened;
70  }
71 };
72 
74  template <typename EulerEquation>
75  [[nodiscard]] bool
76  operator()(EulerEquation& equation, std::optional<Duration> /* t_opened */,
77  double inner_pressure,
78  const KineticState<EulerEquation>& compressor_state,
79  const GriddingAlgorithm& /* gridding */, int /* level */) const
80  noexcept {
81  return inner_pressure > euler::Pressure(equation, compressor_state);
82  }
83 };
84 
85 template <typename EulerEquation, typename InflowFunction,
86  typename ChangeTOpenedT,
87  typename IsBlocked = IsBlockedIfLargePressure>
89 public:
91  const EulerEquation& equation,
92  KineticState<EulerEquation> initial_compressor_state, InflowFunction fn,
93  const GenericPressureValveBoundaryOptions& options = {});
94 
95  void FillBoundary(::amrex::MultiFab& mf, const GriddingAlgorithm& gridding,
96  int level);
97 
98  void FillBoundary(::amrex::MultiFab& mf, const GriddingAlgorithm& gridding,
99  int level, Direction dir);
100 
101  std::optional<Duration> GetTimePointWhenOpened() const noexcept {
102  return t_opened_;
103  }
104 
105  const std::shared_ptr<KineticState<EulerEquation>>&
106  GetSharedCompressorState() const noexcept {
107  return compressor_state_;
108  }
109 
110 private:
111  void ChangeTOpened(double inner_pressure, const GriddingAlgorithm& gridding,
112  int level);
113 
114  EulerEquation equation_;
119 
120  std::shared_ptr<KineticState<EulerEquation>> compressor_state_;
122  std::optional<Duration> t_opened_{};
123 
124 #if __has_cpp_attribute(no_unique_address)
125  [[no_unique_address]] InflowFunction inflow_function_{};
126  [[no_unique_address]] ChangeTOpenedT change_t_opened_{};
127  [[no_unique_address]] IsBlocked is_blocked_{};
128 #else
129  InflowFunction inflow_function_{};
130  ChangeTOpenedT change_t_opened_{};
131  IsBlocked is_blocked_{};
132 #endif
133 };
134 
135 template <typename Equation, typename InflowFunction>
137  : public GenericPressureValveBoundary<Equation, InflowFunction,
138  ChangeTOpened_ReducedModelDemo> {
140  Equation, InflowFunction,
142 };
143 
144 template <typename Equation, typename InflowFunction>
146  const Equation&, KineticState<Equation>, InflowFunction,
148  ->PressureValveBoundary_ReducedModelDemo<Equation, InflowFunction>;
149 
150 template <typename Equation, typename InflowFunction>
152  InflowFunction)
153  ->PressureValveBoundary_ReducedModelDemo<Equation, InflowFunction>;
154 
155 template <typename Equation, typename InflowFunction>
157  : public GenericPressureValveBoundary<Equation, InflowFunction,
158  ChangeTOpened_Klein> {
160  Equation, InflowFunction,
162 };
163 
164 template <typename Equation, typename InflowFunction>
166  InflowFunction,
168  ->PressureValveBoundary_Klein<Equation, InflowFunction>;
169 
170 template <typename Equation, typename InflowFunction>
172  InflowFunction)
173  ->PressureValveBoundary_Klein<Equation, InflowFunction>;
174 
175 template <typename EulerEquation, typename InflowFunction,
176  typename ChangeTOpened, typename IsBlocked>
177 GenericPressureValveBoundary<EulerEquation, InflowFunction, ChangeTOpened,
178  IsBlocked>::
179  GenericPressureValveBoundary(
180  const EulerEquation& equation,
181  KineticState<EulerEquation> initial_compressor_state, InflowFunction fn,
183  : equation_(equation),
184  options_(options), constant_boundary_{options_.dir, options_.side,
185  equation_,
186  Complete<EulerEquation>(equation_)},
187  reflective_boundary_(equation_, options_.dir, options_.side),
188  compressor_state_(std::make_shared<KineticState<EulerEquation>>(
189  std::move(initial_compressor_state))),
190  inflow_function_(std::move(fn)) {}
191 
192 template <typename EulerEquation, typename InflowFunction,
193  typename ChangeTOpened, typename IsBlocked>
195  EulerEquation, InflowFunction, ChangeTOpened,
196  IsBlocked>::FillBoundary(::amrex::MultiFab& mf,
197  const GriddingAlgorithm& gridding, int level,
198  Direction dir) {
199  if (dir == options_.dir) {
200  FillBoundary(mf, gridding, level);
201  }
202 }
203 template <typename EulerEquation, typename InflowFunction,
204  typename ChangeTOpenedT, typename IsBlocked>
206  EulerEquation, InflowFunction, ChangeTOpenedT,
207  IsBlocked>::ChangeTOpened(double inner_pressure,
208  const GriddingAlgorithm& gridding, int level) {
209  std::optional<Duration> t_opened_new =
210  std::invoke(change_t_opened_, equation_, t_opened_, inner_pressure,
211  *compressor_state_, gridding, level);
212  // if (inner_pressure <= options_.open_below_pressure) {
213  const Duration t = gridding.GetTimePoint();
214  if (!t_opened_ && t_opened_new) {
216  BOOST_LOG_SCOPED_LOGGER_TAG(log, "Channel", options_.prefix);
217  BOOST_LOG_SCOPED_LOGGER_TAG(log, "Time", t.count());
218  BOOST_LOG_SCOPED_LOGGER_TAG(log, "Level", level);
219  BOOST_LOG(log) << fmt::format(
220  "Pressure valve has opened because inner pressure is {}.",
221  inner_pressure);
222  } else if (t_opened_ && !t_opened_new) {
224  BOOST_LOG_SCOPED_LOGGER_TAG(log, "Channel", options_.prefix);
225  BOOST_LOG_SCOPED_LOGGER_TAG(log, "Time", t.count());
226  BOOST_LOG_SCOPED_LOGGER_TAG(log, "Level", level);
227  BOOST_LOG(log) << fmt::format(
228  "Pressure valve has closed because inner pressure is {}.",
229  inner_pressure);
230  }
231  t_opened_ = t_opened_new;
232 }
233 
234 template <typename EulerEquation, typename InflowFunction,
235  typename ChangeTOpenedT, typename IsBlocked>
237  EulerEquation, InflowFunction, ChangeTOpenedT,
238  IsBlocked>::FillBoundary(::amrex::MultiFab& mf,
239  const GriddingAlgorithm& gridding, int level) {
240  const ::amrex::Geometry& geom =
241  gridding.GetPatchHierarchy().GetGeometry(level);
242  const ::amrex::Box domain_box = geom.Domain();
243  const ::amrex::Box inner_box =
244  GetInnerBox(domain_box, options_.side, options_.dir, 1);
245  const double inner_pressure =
246  GetMeanValueInBox(mf, inner_box, comps_.pressure);
247 
248  ChangeTOpened(inner_pressure, gridding, level);
249 
250  bool is_blocked =
251  std::invoke(is_blocked_, equation_, t_opened_, inner_pressure,
252  *compressor_state_, gridding, level);
253  if (is_blocked) {
254  reflective_boundary_.FillBoundary(mf, gridding, level);
255  } else {
256  FUB_ASSERT(t_opened_);
257  const Duration t = gridding.GetTimePoint();
258  const Duration t_diff = t - *t_opened_;
259  std::invoke(inflow_function_, equation_, constant_boundary_.state,
260  *compressor_state_, inner_pressure, t_diff, mf, gridding,
261  level);
262  constant_boundary_.FillBoundary(mf, gridding, level);
263  }
264 }
265 
266 } // namespace fub::amrex
267 
268 #endif
#define FUB_ASSERT(x)
Definition: assert.hpp:39
Definition: GenericPressureValveBoundary.hpp:88
ReflectiveBoundary< execution::SequentialTag, EulerEquation > reflective_boundary_
Definition: GenericPressureValveBoundary.hpp:118
const std::shared_ptr< KineticState< EulerEquation > > & GetSharedCompressorState() const noexcept
Definition: GenericPressureValveBoundary.hpp:106
GenericPressureValveBoundary(const EulerEquation &equation, KineticState< EulerEquation > initial_compressor_state, InflowFunction fn, const GenericPressureValveBoundaryOptions &options={})
Definition: GenericPressureValveBoundary.hpp:179
ConstantBoundary< EulerEquation > constant_boundary_
Definition: GenericPressureValveBoundary.hpp:116
GenericPressureValveBoundaryOptions options_
Definition: GenericPressureValveBoundary.hpp:115
void FillBoundary(::amrex::MultiFab &mf, const GriddingAlgorithm &gridding, int level, Direction dir)
Definition: GenericPressureValveBoundary.hpp:196
std::optional< Duration > t_opened_
Definition: GenericPressureValveBoundary.hpp:122
void ChangeTOpened(double inner_pressure, const GriddingAlgorithm &gridding, int level)
Definition: GenericPressureValveBoundary.hpp:207
EulerEquation equation_
Definition: GenericPressureValveBoundary.hpp:114
IndexMapping< EulerEquation > comps_
Definition: GenericPressureValveBoundary.hpp:121
std::optional< Duration > GetTimePointWhenOpened() const noexcept
Definition: GenericPressureValveBoundary.hpp:101
ChangeTOpenedT change_t_opened_
Definition: GenericPressureValveBoundary.hpp:130
InflowFunction inflow_function_
Definition: GenericPressureValveBoundary.hpp:129
std::shared_ptr< KineticState< EulerEquation > > compressor_state_
Definition: GenericPressureValveBoundary.hpp:120
void FillBoundary(::amrex::MultiFab &mf, const GriddingAlgorithm &gridding, int level)
Definition: GenericPressureValveBoundary.hpp:238
IsBlocked is_blocked_
Definition: GenericPressureValveBoundary.hpp:131
This class modifies and initializes a PatchLevel in a PatchHierarchy.
Definition: AMReX/GriddingAlgorithm.hpp:60
Duration GetTimePoint() const noexcept
Returns the current time point on the coarsest refinement level.
Definition: AMReX/GriddingAlgorithm.hpp:133
PatchHierarchy & GetPatchHierarchy() noexcept
Definition: AMReX/GriddingAlgorithm.hpp:108
const ::amrex::Geometry & GetGeometry(int level) const
Returns a Geometry object for a specified level.
Definition: AMReX/boundary_condition/ReflectiveBoundary.hpp:34
The amrex namespace.
Definition: AverageState.hpp:33
::amrex::Box GetInnerBox(const ::amrex::Box &box, int side, Direction dir, int width)
PressureValveBoundary_Klein(const Equation &, KineticState< Equation >, InflowFunction, const GenericPressureValveBoundaryOptions &) -> PressureValveBoundary_Klein< Equation, InflowFunction >
PressureValveBoundary_ReducedModelDemo(const Equation &, KineticState< Equation >, InflowFunction, const GenericPressureValveBoundaryOptions &) -> PressureValveBoundary_ReducedModelDemo< Equation, InflowFunction >
double GetMeanValueInBox(const ::amrex::MultiFab &data, const ::amrex::Box &box, int component)
constexpr struct fub::euler::PressureFn Pressure
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
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
SeverityLogger GetInfoLogger()
Definition: Log.hpp:48
This type has a constructor which takes an equation and might allocate any dynamically sized member v...
Definition: State.hpp:335
Definition: State.hpp:301
Definition: GenericPressureValveBoundary.hpp:56
std::optional< Duration > operator()(EulerEquation &equation, std::optional< Duration > t_opened, double inner_pressure, const KineticState< EulerEquation > &compressor_state, const GriddingAlgorithm &gridding, int) const noexcept
Definition: GenericPressureValveBoundary.hpp:59
Definition: GenericPressureValveBoundary.hpp:39
std::optional< Duration > operator()(EulerEquation &equation, std::optional< Duration > t_opened, double inner_pressure, const KineticState< EulerEquation > &compressor_state, const GriddingAlgorithm &gridding, int) const noexcept
Definition: GenericPressureValveBoundary.hpp:42
Definition: GenericPressureValveBoundary.hpp:33
Direction dir
Definition: GenericPressureValveBoundary.hpp:35
int side
Definition: GenericPressureValveBoundary.hpp:36
std::string prefix
Definition: GenericPressureValveBoundary.hpp:34
Definition: GenericPressureValveBoundary.hpp:73
bool operator()(EulerEquation &equation, std::optional< Duration >, double inner_pressure, const KineticState< EulerEquation > &compressor_state, const GriddingAlgorithm &, int) const noexcept
Definition: GenericPressureValveBoundary.hpp:76
Definition: GenericPressureValveBoundary.hpp:158
Definition: GenericPressureValveBoundary.hpp:138