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