00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00032 #ifndef OPM_MATERIAL_MATH_TOOLBOX_HPP
00033 #define OPM_MATERIAL_MATH_TOOLBOX_HPP
00034
00035 #include <cmath>
00036 #include <algorithm>
00037 #include <type_traits>
00038
00039 namespace Opm {
00040
00041
00042
00043
00044
00045
00046
00047 template <class ScalarT>
00048 struct MathToolbox
00049 {
00050 static_assert(std::is_floating_point<ScalarT>::value,
00051 "This class expects floating point scalars! (specialization missing?)");
00052 public:
00056 typedef ScalarT Scalar;
00057
00065 typedef ScalarT ValueType;
00066
00074 typedef Opm::MathToolbox<Scalar> InnerToolbox;
00075
00082 static Scalar value(Scalar value)
00083 { return value; }
00084
00091 static Scalar scalarValue(Scalar value)
00092 { return value; }
00093
00101 static Scalar createConstant(Scalar value)
00102 { return value; }
00103
00111 static Scalar createVariable(Scalar value, unsigned )
00112 { return value; }
00113
00125 template <class LhsEval>
00126 static LhsEval decay(Scalar value)
00127 {
00128 static_assert(std::is_floating_point<LhsEval>::value,
00129 "The left-hand side must be a primitive floating point type!");
00130
00131 return value;
00132 }
00133
00137 static bool isSame(Scalar a, Scalar b, Scalar tolerance)
00138 {
00139 Scalar valueDiff = a - b;
00140 Scalar denom = std::max<Scalar>(1.0, std::abs(a + b));
00141
00142 return std::abs(valueDiff) < tolerance || std::abs(valueDiff)/denom < tolerance;
00143 }
00144
00146
00148
00150 static Scalar max(Scalar arg1, Scalar arg2)
00151 { return std::max(arg1, arg2); }
00152
00154 static Scalar min(Scalar arg1, Scalar arg2)
00155 { return std::min(arg1, arg2); }
00156
00158 static Scalar abs(Scalar arg)
00159 { return std::abs(arg); }
00160
00162 static Scalar tan(Scalar arg)
00163 { return std::tan(arg); }
00164
00166 static Scalar atan(Scalar arg)
00167 { return std::atan(arg); }
00168
00170 static Scalar atan2(Scalar arg1, Scalar arg2)
00171 { return std::atan2(arg1, arg2); }
00172
00174 static Scalar sin(Scalar arg)
00175 { return std::sin(arg); }
00176
00178 static Scalar asin(Scalar arg)
00179 { return std::asin(arg); }
00180
00182 static Scalar cos(Scalar arg)
00183 { return std::cos(arg); }
00184
00186 static Scalar acos(Scalar arg)
00187 { return std::acos(arg); }
00188
00190 static Scalar sqrt(Scalar arg)
00191 { return std::sqrt(arg); }
00192
00194 static Scalar exp(Scalar arg)
00195 { return std::exp(arg); }
00196
00198 static Scalar log(Scalar arg)
00199 { return std::log(arg); }
00200
00202 static Scalar pow(Scalar base, Scalar exp)
00203 { return std::pow(base, exp); }
00204
00206 static bool isfinite(Scalar arg)
00207 { return std::isfinite(arg); }
00208
00210 static bool isnan(Scalar arg)
00211 { return std::isnan(arg); }
00212 };
00213
00214 template <class Eval1, class Eval2>
00215 struct ReturnEval_
00216 {
00217 typedef typename std::remove_const< typename std::remove_reference<Eval1>::type >::type T;
00218 typedef typename std::remove_const< typename std::remove_reference<Eval2>::type >::type U;
00219
00220
00221
00222
00223 typedef typename std::conditional<std::is_constructible<T, U>::value,
00224 T,
00225 U>::type type;
00226 };
00227
00228
00229 template <class Evaluation, class Scalar>
00230 Evaluation constant(const Scalar& value)
00231 { return Opm::MathToolbox<Evaluation>::createConstant(value); }
00232
00233 template <class Evaluation, class Scalar>
00234 Evaluation variable(const Scalar& value, unsigned idx)
00235 { return Opm::MathToolbox<Evaluation>::createVariable(value, idx); }
00236
00237 template <class ResultEval, class Evaluation>
00238 auto decay(const Evaluation& value)
00239 -> decltype(Opm::MathToolbox<Evaluation>::template decay<ResultEval>(value))
00240 { return Opm::MathToolbox<Evaluation>::template decay<ResultEval>(value); }
00241
00242 template <class Evaluation>
00243 auto getValue(const Evaluation& val)
00244 -> decltype(Opm::MathToolbox<Evaluation>::value(val))
00245 { return Opm::MathToolbox<Evaluation>::value(val); }
00246
00247 template <class Evaluation>
00248 auto scalarValue(const Evaluation& val)
00249 -> decltype(Opm::MathToolbox<Evaluation>::scalarValue(val))
00250 { return Opm::MathToolbox<Evaluation>::scalarValue(val); }
00251
00252 template <class Evaluation1, class Evaluation2>
00253 typename ReturnEval_<Evaluation1, Evaluation2>::type
00254 max(const Evaluation1& arg1, const Evaluation2& arg2)
00255 { return Opm::MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::max(arg1, arg2); }
00256
00257 template <class Evaluation1, class Evaluation2>
00258 typename ReturnEval_<Evaluation1, Evaluation2>::type
00259 min(const Evaluation1& arg1, const Evaluation2& arg2)
00260 { return Opm::MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::min(arg1, arg2); }
00261
00262 template <class Evaluation>
00263 Evaluation abs(const Evaluation& value)
00264 { return Opm::MathToolbox<Evaluation>::abs(value); }
00265
00266 template <class Evaluation>
00267 Evaluation tan(const Evaluation& value)
00268 { return Opm::MathToolbox<Evaluation>::tan(value); }
00269
00270 template <class Evaluation>
00271 Evaluation atan(const Evaluation& value)
00272 { return Opm::MathToolbox<Evaluation>::atan(value); }
00273
00274 template <class Evaluation1, class Evaluation2>
00275 typename ReturnEval_<Evaluation1, Evaluation2>::type
00276 atan2(const Evaluation1& value1, const Evaluation2& value2)
00277 { return Opm::MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::atan2(value1, value2); }
00278
00279 template <class Evaluation>
00280 Evaluation sin(const Evaluation& value)
00281 { return Opm::MathToolbox<Evaluation>::sin(value); }
00282
00283 template <class Evaluation>
00284 Evaluation asin(const Evaluation& value)
00285 { return Opm::MathToolbox<Evaluation>::asin(value); }
00286
00287 template <class Evaluation>
00288 Evaluation cos(const Evaluation& value)
00289 { return Opm::MathToolbox<Evaluation>::cos(value); }
00290
00291 template <class Evaluation>
00292 Evaluation acos(const Evaluation& value)
00293 { return Opm::MathToolbox<Evaluation>::acos(value); }
00294
00295 template <class Evaluation>
00296 Evaluation sqrt(const Evaluation& value)
00297 { return Opm::MathToolbox<Evaluation>::sqrt(value); }
00298
00299 template <class Evaluation>
00300 Evaluation exp(const Evaluation& value)
00301 { return Opm::MathToolbox<Evaluation>::exp(value); }
00302
00303 template <class Evaluation>
00304 Evaluation log(const Evaluation& value)
00305 { return Opm::MathToolbox<Evaluation>::log(value); }
00306
00307 template <class Evaluation1, class Evaluation2>
00308 typename ReturnEval_<Evaluation1, Evaluation2>::type
00309 pow(const Evaluation1& base, const Evaluation2& exp)
00310 { return Opm::MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::pow(base, exp); }
00311
00312 template <class Evaluation>
00313 bool isfinite(const Evaluation& value)
00314 { return Opm::MathToolbox<Evaluation>::isfinite(value); }
00315
00316 template <class Evaluation>
00317 bool isnan(const Evaluation& value)
00318 { return Opm::MathToolbox<Evaluation>::isnan(value); }
00319
00320 }
00321
00322 #endif
00323