Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
AnyBoundaryCondition.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_GRID_AMREX_BOUNDARY_CONDITION_HPP
22 #define FUB_GRID_AMREX_BOUNDARY_CONDITION_HPP
23 
24 #include "fub/Direction.hpp"
25 #include "fub/Duration.hpp"
26 
27 #include "fub/Meta.hpp"
28 
29 #include <memory>
30 
31 namespace fub {
32 
33 /// \ingroup GriddingAlgorithm
34 /// \defgroup BoundaryCondition Boundary Conditions
35 /// \brief This modules collects all components that fill the ghost layer of a patch
36 /// level.
37 
38 namespace detail {
39 template <typename GriddingAlgorithm> struct BoundaryConditionBase {
40  using DataReference = typename GridTraits<GriddingAlgorithm>::DataReference;
41 
42  virtual ~BoundaryConditionBase() = default;
43  virtual std::unique_ptr<BoundaryConditionBase> Clone() const = 0;
44  virtual void FillBoundary(DataReference mf, const GriddingAlgorithm& gridding,
45  int level) = 0;
46  virtual void FillBoundary(DataReference mf, const GriddingAlgorithm& gridding,
47  int level, Direction dir) = 0;
48 };
49 } // namespace detail
50 
51 /// \ingroup BoundaryCondition PolymorphicValueType
52 ///
53 /// \brief This is a polymorphic value type that wraps any BoundaryCondition
54 /// object.
55 template <typename GriddingAlgorithm> class AnyBoundaryCondition {
56 public:
58 
59  /// @{
60  /// \name Constructors
61 
62  /// \brief This constructs a method that does nothing on invocation.
63  ///
64  /// \throw Nothing.
65  AnyBoundaryCondition() = default;
66 
67  /// \brief Stores any object which satisfies the BoundaryCondition concept.
68  template <typename BC,
69  typename = std::enable_if_t<!decays_to<BC, AnyBoundaryCondition>()>>
70  AnyBoundaryCondition(BC&& bc);
71 
72  /// \brief Copies the implementation.
74 
75  /// \brief Copies the implementation.
77 
78  /// \brief Moves the `other` object without allocating and leaves an empty
79  /// method.
81 
82  /// \brief Moves the `other` object without allocating and leaves an empty
83  /// method.
85  /// @}
86 
87  /// @{
88  /// \name Actions
89 
90  /// \brief Fill the boundary layer of data.
91  void FillBoundary(DataReference data, const GriddingAlgorithm& gridding,
92  int level);
93 
94  /// \brief Fill the boundary layer of data in direction `dir` only.
95  void FillBoundary(DataReference data, const GriddingAlgorithm& gridding,
96  int level, Direction dir);
97  /// @}
98 
99 private:
100  std::unique_ptr<detail::BoundaryConditionBase<GriddingAlgorithm>>
102 };
103 
104 inline int GetSign(int side) { return (side == 0) - (side == 1); }
105 
106 ///////////////////////////////////////////////////////////////////////////////
107 // Implementation
108 
109 namespace detail {
110 template <typename GriddingAlgorithm, typename BC>
111 struct BoundaryConditionWrapper
112  : public BoundaryConditionBase<GriddingAlgorithm> {
113  using DataReference = typename GridTraits<GriddingAlgorithm>::DataReference;
114 
115  BoundaryConditionWrapper(const BC& bc) : boundary_condition_{bc} {}
116  BoundaryConditionWrapper(BC&& bc) : boundary_condition_{std::move(bc)} {}
117 
118  std::unique_ptr<BoundaryConditionBase<GriddingAlgorithm>>
119  Clone() const override {
120  return std::make_unique<BoundaryConditionWrapper<GriddingAlgorithm, BC>>(
121  boundary_condition_);
122  }
123 
124  void FillBoundary(DataReference data, const GriddingAlgorithm& gridding,
125  int level) override {
126  boundary_condition_.FillBoundary(data, gridding, level);
127  }
128 
129  void FillBoundary(DataReference data, const GriddingAlgorithm& gridding,
130  int level, Direction dir) override {
131  boundary_condition_.FillBoundary(data, gridding, level, dir);
132  }
133 
134  BC boundary_condition_;
135 };
136 } // namespace detail
137 
138 template <typename GriddingAlgorithm>
140  const AnyBoundaryCondition& other)
141  : boundary_condition_(other.boundary_condition_
142  ? other.boundary_condition_->Clone()
143  : nullptr) {}
144 
145 template <typename GriddingAlgorithm>
148  const AnyBoundaryCondition& other) {
149  AnyBoundaryCondition tmp(other);
150  return *this = std::move(tmp);
151 }
152 
153 template <typename GriddingAlgorithm>
154 template <typename BC, typename>
156  : boundary_condition_{std::make_unique<detail::BoundaryConditionWrapper<
157  GriddingAlgorithm, std::decay_t<BC>>>(std::forward<BC>(bc))} {}
158 
159 template <typename GriddingAlgorithm>
161  DataReference data, const GriddingAlgorithm& gridding, int level) {
162  if (boundary_condition_) {
163  boundary_condition_->FillBoundary(data, gridding, level);
164  }
165 }
166 
167 template <typename GriddingAlgorithm>
169  DataReference data, const GriddingAlgorithm& gridding, int level,
170  Direction dir) {
171  if (boundary_condition_) {
172  boundary_condition_->FillBoundary(data, gridding, level, dir);
173  }
174 }
175 
176 } // namespace fub
177 
178 #endif
This is a polymorphic value type that wraps any BoundaryCondition object.
Definition: AnyBoundaryCondition.hpp:55
AnyBoundaryCondition()=default
This constructs a method that does nothing on invocation.
AnyBoundaryCondition(AnyBoundaryCondition &&)=default
Moves the other object without allocating and leaves an empty method.
AnyBoundaryCondition & operator=(const AnyBoundaryCondition &other)
Copies the implementation.
Definition: AnyBoundaryCondition.hpp:147
AnyBoundaryCondition & operator=(AnyBoundaryCondition &&)=default
Moves the other object without allocating and leaves an empty method.
std::unique_ptr< detail::BoundaryConditionBase< GriddingAlgorithm > > boundary_condition_
Definition: AnyBoundaryCondition.hpp:101
void FillBoundary(DataReference data, const GriddingAlgorithm &gridding, int level)
Fill the boundary layer of data.
Definition: AnyBoundaryCondition.hpp:160
typename GridTraits< GriddingAlgorithm >::DataReference DataReference
Definition: AnyBoundaryCondition.hpp:57
std::decay_t< decltype(*std::declval< T >().GetGriddingAlgorithm())> GriddingAlgorithm
A template typedef to detect the member function.
Definition: Meta.hpp:56
The fub namespace.
Definition: AnyBoundaryCondition.hpp:31
int GetSign(int side)
Definition: AnyBoundaryCondition.hpp:104
Direction
This is a type safe type to denote a dimensional split direction.
Definition: Direction.hpp:30
Definition: Meta.hpp:67