VertexCFD  0.0-dev
VertexCFD_Utils_SmoothRamp.hpp
1 #ifndef VERTEXCFD_UTILS_SMOOTHRAMP_HPP
2 #define VERTEXCFD_UTILS_SMOOTHRAMP_HPP
3 
4 #include "VertexCFD_Utils_Constants.hpp"
5 
6 #include <Sacado.hpp>
7 #include <Sacado_Fad_Exp_Expression.hpp>
8 #include <Sacado_Fad_Exp_ExpressionTraits.hpp>
9 
10 namespace VertexCFD
11 {
12 namespace SmoothMath
13 {
14 //---------------------------------------------------------------------------//
15 // Implementation of smooth "ramp" using Sacado expressions.
16 //---------------------------------------------------------------------------//
17 template<typename T, typename ExprSpec>
19 {
20 };
21 
22 template<typename T>
23 class SmoothRampOp<T, Sacado::Fad::Exp::ExprSpecDefault>
24  : public Sacado::Fad::Exp::Expr<
25  SmoothRampOp<T, Sacado::Fad::Exp::ExprSpecDefault>>
26 {
27  public:
28  using ExprT = typename std::remove_cv<T>::type;
29  using value_type = typename ExprT::value_type;
30  using scalar_type = typename ExprT::scalar_type;
31  using expr_spec_type = Sacado::Fad::Exp::ExprSpecDefault;
32 
33  SACADO_INLINE_FUNCTION explicit SmoothRampOp(const T& x,
34  double start,
35  double end)
36  : x_(x)
37  , start_(start)
38  , end_(end)
39  {
40  }
41 
42  SACADO_INLINE_FUNCTION int size() const { return x_.size(); }
43 
44  SACADO_INLINE_FUNCTION bool hasFastAccess() const
45  {
46  return x_.hasFastAccess();
47  }
48 
49  SACADO_INLINE_FUNCTION value_type val() const
50  {
51  using std::sin;
52  constexpr double half_pi = 0.5 * Constants::pi;
53  if (x_ <= start_)
54  {
55  return 0.0;
56  }
57  else if (x_ >= end_)
58  {
59  return 1.0;
60  }
61  else
62  {
63  return 0.5
64  * (sin(half_pi * (2.0 * x_.val() - (start_ + end_))
65  / (end_ - start_))
66  + 1.0);
67  }
68  }
69 
70  SACADO_INLINE_FUNCTION value_type dx(int i) const
71  {
72  using std::cos;
73  constexpr double half_pi = 0.5 * Constants::pi;
74  if (x_ <= start_)
75  {
76  return 0.0;
77  }
78  else if (x_ >= end_)
79  {
80  return 0.0;
81  }
82  else
83  {
84  return (half_pi / (end_ - start_))
85  * (cos(half_pi * (2.0 * x_.dx(i) - (start_ + end_))
86  / (end_ - start_)));
87  }
88  }
89 
90  SACADO_INLINE_FUNCTION value_type fastAccessDx(int i) const
91  {
92  using std::cos;
93  constexpr double half_pi = 0.5 * Constants::pi;
94  if (x_ <= start_)
95  {
96  return 0.0;
97  }
98  else if (x_ >= end_)
99  {
100  return 0.0;
101  }
102  else
103  {
104  return (half_pi / (end_ - start_))
105  * (cos(half_pi * (2.0 * x_.fastAccessDx(i) - (start_ + end_))
106  / (end_ - start_)));
107  }
108  }
109 
110  private:
111  const T& x_;
112  double start_;
113  double end_;
114 };
115 
116 // Generic implementation for POD types
117 template<typename T>
118 SACADO_INLINE_FUNCTION
119  typename std::enable_if<std::is_trivial<T>::value, T>::type
120  ramp(const T x, const double start, const double end)
121 {
122  using std::sin;
123  constexpr double half_pi = 0.5 * Constants::pi;
124  if (x <= start)
125  {
126  return 0.0;
127  }
128  else if (x >= end)
129  {
130  return 1.0;
131  }
132  else
133  {
134  return 0.5
135  * (sin(half_pi * (2.0 * x - (start + end)) / (end - start))
136  + 1.0);
137  }
138 }
139 
140 using Sacado::Fad::Exp::Expr;
141 
142 // Specialization for FAD types
143 template<typename T>
144 SACADO_INLINE_FUNCTION
145  SmoothRampOp<typename Expr<T>::derived_type, typename T::expr_spec_type>
146  ramp(const Expr<T>& x, double start, double end)
147 {
148  using expr_t = SmoothRampOp<typename Expr<T>::derived_type,
149  typename T::expr_spec_type>;
150  return expr_t(x.derived(), start, end);
151 }
152 
153 } // end namespace SmoothMath
154 } // end namespace VertexCFD
155 
156 namespace Sacado
157 {
158 
160 
161 namespace Fad
162 {
163 namespace Exp
164 {
165 
166 //
167 // Specializations for Sacado traits
168 //
169 
170 template<typename T, typename E>
171 struct ExprLevel<SmoothRampOp<T, E>>
172 {
173  static const unsigned value = ExprLevel<T>::value;
174 };
175 
176 template<typename T, typename E>
177 struct IsFadExpr<SmoothRampOp<T, E>>
178 {
179  static const unsigned value = true;
180 };
181 
182 } // namespace Exp
183 } // namespace Fad
184 
185 template<typename T, typename E>
186 struct IsExpr<SmoothRampOp<T, E>>
187 {
188  static const unsigned value = true;
189 };
190 
191 template<typename T, typename E>
192 struct BaseExprType<SmoothRampOp<T, E>>
193 {
194  using type = typename BaseExprType<T>::type;
195 };
196 
197 template<typename T, typename E>
198 struct IsSimdType<SmoothRampOp<T, E>>
199 {
200  static const bool value
201  = IsSimdType<typename SmoothRampOp<T, E>::scalar_type>::value;
202 };
203 
204 template<typename T, typename E>
205 struct ValueType<SmoothRampOp<T, E>>
206 {
207  using type = typename SmoothRampOp<T, E>::value_type;
208 };
209 
210 template<typename T, typename E>
211 struct ScalarType<SmoothRampOp<T, E>>
212 {
213  using type = typename SmoothRampOp<T, E>::scalar_type;
214 };
215 
216 } // namespace Sacado
217 
218 #endif // end VERTEXCFD_UTILS_SMOOTHRAMP_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23
VertexCFD::SmoothMath::SmoothRampOp
Definition: VertexCFD_Utils_SmoothRamp.hpp:19