ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_EBIF.H
Go to the documentation of this file.
1 #ifndef INCFLO_IF_LIST_
2 #define INCFLO_IF_LIST_
3 
4 #include <AMReX_EB2.H>
5 #include <AMReX_Vector.H>
6 
7 #include <algorithm>
8 #include <type_traits>
9 
10 /********************************************************************************
11  * *
12  * Union of a list (std::vector) of the same kind of implicit function. *
13  * *
14  ********************************************************************************/
15 
16 template <class F>
18 {
19 
20 public:
21  UnionListIF(const amrex::Vector<F>& a_ifs)
22  : m_ifs(a_ifs),
23  empty(!a_ifs.empty())
24  {}
25 
26  [[nodiscard]] bool is_empty() const
27  {
28  return empty;
29  }
30 
31  amrex::Real operator()(const amrex::RealArray& p) const
32  {
33 
34  // NOTE: this assumes that m_ifs is not empty
35  amrex::Real vmax = m_ifs[0](p);
36  for(int i = 1; i < m_ifs.size(); i++)
37  {
38  amrex::Real vcur = m_ifs[i](p);
39  if(vmax < vcur)
40  vmax = vcur;
41  }
42 
43  return vmax;
44 
45  // NOTE: this would have been nice, but for some reason it does not work :(
46  // even though according to https://en.cppreference.com/w/cpp/algorithm/max
47  // it should ... ?
48  //F & f_max = std::max( m_ifs,
49  // [&](const F & f1, const F & f2) {
50  // return f1(p) < f2(p);
51  // });
52  //return f_max(p);
53  }
54 
55 private:
56  amrex::Vector<F> m_ifs;
57  bool empty;
58 };
59 
60 /********************************************************************************
61  * *
62  * Conditional Implicit Functions => CIF *
63  * Can be "turned off" based on run-time parameters *
64  * *
65  ********************************************************************************/
66 
67 /********************************************************************************
68  * *
69  * Conditional implicit function: a "normal" implicit function is given the *
70  * additional property `active` (getter: `is_active()`, setter *
71  * `set_active(bool)`) allowing ConditionalUnion and ConditionalIntersection *
72  * operations. *
73  * *
74  ********************************************************************************/
75 
76 template <class F>
77 class CIF : public F
78 {
79 
80 public:
81  CIF(F&& f, bool a_active)
82  : F(f)
83  , m_active(a_active)
84  {
85  }
86 
87  ~CIF()
88  = default;
89 
90  CIF(const CIF& rhs) = default;
91  CIF(CIF&& rhs) noexcept = default;
92  CIF& operator=(const CIF& rhs) = default;
93  CIF& operator=(CIF&& rhs) noexcept = default;
94 
95  void set_active(bool a_active)
96  {
97  m_active = a_active;
98  }
99  [[nodiscard]] bool is_active() const
100  {
101  return m_active;
102  }
103 
104 private:
105  bool m_active;
106 };
107 
108 /********************************************************************************
109  * *
110  * Conditional Union of two (different) conditional implicit functions. *
111  * NOTE: at least one of the conditional implicit functions must be active. *
112  * *
113  ********************************************************************************/
114 
115 template <class F1, class F2>
116 class UnionCIF
117 {
118 
119 public:
120  // Assuming that one always active
121  UnionCIF(const F1& f1, const F2& f2)
122  : m_f1(f1)
123  , m_f2(f2)
124  , f1_active(f1.is_acive())
125  , f2_active(f2.is_active())
126  {
127  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(f1.is_active() || f2.is_active(),
128  "You must specify at least one active implicit function.");
129  }
130 
132  = default;
133 
134  UnionCIF(const UnionCIF& rhs) = default;
135  UnionCIF(UnionCIF&& rhs) noexcept = default;
136  UnionCIF& operator=(const UnionCIF& rhs) = default;
137  UnionCIF& operator=(UnionCIF&& rhs) noexcept = default;
138 
139  [[nodiscard]] bool is_active() const
140  {
141  return true;
142  }
143 
144  amrex::Real operator()(const amrex::RealArray& p) const
145  {
146 
147  if(!f1_active)
148  return m_f2(p);
149  if(!f2_active)
150  return m_f1(p);
151 
152  return std::max(m_f1(p), m_f2(p));
153  }
154 
155 private:
156  F1 m_f1;
157  F2 m_f2;
158  bool f1_active;
159  bool f2_active;
160 };
161 
162 /********************************************************************************
163  * *
164  * Conditional Intersection of two (different) conditional implicit functions. *
165  * NOTE: at least one of the conditional implicit functions must be active. *
166  * *
167  ********************************************************************************/
168 
169 template <class F1, class F2>
171 {
172 
173 public:
174  // Assuming that one always active
175  IntersectionCIF(const F1& f1, const F2& f2)
176  : m_f1(f1)
177  , m_f2(f2)
178  , f1_active(f1.is_acive())
179  , f2_active(f2.is_active())
180  {
181  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(f1.is_active() || f2.is_active(),
182  "You must specify at least one active implicit function.");
183  }
184 
186  = default;
187 
188  IntersectionCIF(const IntersectionCIF& rhs) = default;
189  IntersectionCIF(IntersectionCIF&& rhs) noexcept = default;
190  IntersectionCIF& operator=(const IntersectionCIF& rhs) = default;
191  IntersectionCIF& operator=(IntersectionCIF&& rhs) noexcept = default;
192 
193  [[nodiscard]] bool is_active() const
194  {
195  return true;
196  }
197 
198  amrex::Real operator()(const amrex::RealArray& p) const
199  {
200 
201  if(!f1_active)
202  return m_f2(p);
203  if(!f2_active)
204  return m_f1(p);
205 
206  return std::min(m_f1(p), m_f2(p));
207  }
208 
209 private:
210  F1 m_f1;
211  F2 m_f2;
212  bool f1_active;
213  bool f2_active;
214 };
215 
216 #endif
Definition: ERF_EBIF.H:78
CIF & operator=(CIF &&rhs) noexcept=default
CIF(F &&f, bool a_active)
Definition: ERF_EBIF.H:81
bool m_active
Definition: ERF_EBIF.H:105
bool is_active() const
Definition: ERF_EBIF.H:99
void set_active(bool a_active)
Definition: ERF_EBIF.H:95
CIF & operator=(const CIF &rhs)=default
~CIF()=default
CIF(CIF &&rhs) noexcept=default
CIF(const CIF &rhs)=default
Definition: ERF_EBIF.H:171
F1 m_f1
Definition: ERF_EBIF.H:210
amrex::Real operator()(const amrex::RealArray &p) const
Definition: ERF_EBIF.H:198
IntersectionCIF(IntersectionCIF &&rhs) noexcept=default
bool is_active() const
Definition: ERF_EBIF.H:193
IntersectionCIF & operator=(IntersectionCIF &&rhs) noexcept=default
bool f2_active
Definition: ERF_EBIF.H:213
IntersectionCIF(const F1 &f1, const F2 &f2)
Definition: ERF_EBIF.H:175
~IntersectionCIF()=default
bool f1_active
Definition: ERF_EBIF.H:212
IntersectionCIF & operator=(const IntersectionCIF &rhs)=default
F2 m_f2
Definition: ERF_EBIF.H:211
IntersectionCIF(const IntersectionCIF &rhs)=default
Definition: ERF_EBIF.H:117
UnionCIF & operator=(UnionCIF &&rhs) noexcept=default
F2 m_f2
Definition: ERF_EBIF.H:157
bool f1_active
Definition: ERF_EBIF.H:158
UnionCIF(const UnionCIF &rhs)=default
F1 m_f1
Definition: ERF_EBIF.H:156
bool f2_active
Definition: ERF_EBIF.H:159
UnionCIF & operator=(const UnionCIF &rhs)=default
UnionCIF(UnionCIF &&rhs) noexcept=default
UnionCIF(const F1 &f1, const F2 &f2)
Definition: ERF_EBIF.H:121
amrex::Real operator()(const amrex::RealArray &p) const
Definition: ERF_EBIF.H:144
bool is_active() const
Definition: ERF_EBIF.H:139
~UnionCIF()=default
Definition: ERF_EBIF.H:18
bool is_empty() const
Definition: ERF_EBIF.H:26
amrex::Real operator()(const amrex::RealArray &p) const
Definition: ERF_EBIF.H:31
UnionListIF(const amrex::Vector< F > &a_ifs)
Definition: ERF_EBIF.H:21
amrex::Vector< F > m_ifs
Definition: ERF_EBIF.H:56
bool empty
Definition: ERF_EBIF.H:57