opm-common
MathToolbox.hpp
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 
19  Consult the COPYING file in the top-level source directory of this
20  module for the precise wording of the license and the list of
21  copyright holders.
22 */
32 #ifndef OPM_MATERIAL_MATH_TOOLBOX_HPP
33 #define OPM_MATERIAL_MATH_TOOLBOX_HPP
34 
35 #include <cmath>
36 #include <algorithm>
37 #include <type_traits>
38 #include <stdexcept>
39 #include <opm/common/utility/gpuDecorators.hpp>
40 
41 namespace Opm {
42 /*
43  * \brief A traits class which provides basic mathematical functions for arbitrary scalar
44  * floating point values.
45  *
46  * The reason why this is done in such a complicated way is to enable other approaches,
47  * in particular automatic differentiation based ones.
48  */
49 template <class ScalarT>
51 {
52  static_assert(std::is_floating_point<ScalarT>::value,
53  "This class expects floating point scalars! (specialization missing?)");
54 public:
58  typedef ScalarT Scalar;
59 
67  typedef ScalarT ValueType;
68 
77 
84  OPM_HOST_DEVICE static Scalar value(Scalar value)
85  { return value; }
86 
93  OPM_HOST_DEVICE static Scalar scalarValue(Scalar value)
94  { return value; }
95 
102  OPM_HOST_DEVICE static Scalar createBlank(Scalar /*value*/)
103  { return Scalar(); }
104 
112  OPM_HOST_DEVICE static Scalar createConstant(Scalar value)
113  { return value; }
114 
123  OPM_HOST_DEVICE static Scalar createConstant(unsigned numDerivatives, Scalar value)
124  {
125  if (numDerivatives != 0)
126  throw std::logic_error("Plain floating point objects cannot represent any derivatives");
127  return value;
128  }
129 
138  OPM_HOST_DEVICE static Scalar createConstant(Scalar /*x*/, Scalar value)
139  { return value; }
140 
148  OPM_HOST_DEVICE static Scalar createVariable(Scalar /*value*/, unsigned /*varIdx*/)
149  { throw std::logic_error("Plain floating point objects cannot represent variables"); }
150 
159  OPM_HOST_DEVICE static Scalar createVariable(Scalar /*x*/, Scalar /*value*/, unsigned /*varIdx*/)
160  { throw std::logic_error("Plain floating point objects cannot represent variables"); }
161 
173  template <class LhsEval>
174  OPM_HOST_DEVICE static LhsEval decay(Scalar value)
175  {
176  static_assert(std::is_floating_point<LhsEval>::value,
177  "The left-hand side must be a primitive floating point type!");
178 
179  return value;
180  }
181 
185  OPM_HOST_DEVICE static bool isSame(Scalar a, Scalar b, Scalar tolerance)
186  {
187  Scalar valueDiff = a - b;
188  Scalar denom = std::max<Scalar>(1.0, std::abs(a + b));
189 
190  return std::abs(valueDiff) < tolerance || std::abs(valueDiff)/denom < tolerance;
191  }
192 
194  // arithmetic functions
196 
198  OPM_HOST_DEVICE static Scalar max(Scalar arg1, Scalar arg2)
199  { return std::max(arg1, arg2); }
200 
202  OPM_HOST_DEVICE static Scalar min(Scalar arg1, Scalar arg2)
203  { return std::min(arg1, arg2); }
204 
206  OPM_HOST_DEVICE static Scalar abs(Scalar arg)
207  { return std::abs(arg); }
208 
210  OPM_HOST_DEVICE static Scalar tan(Scalar arg)
211  { return std::tan(arg); }
212 
214  OPM_HOST_DEVICE static Scalar atan(Scalar arg)
215  { return std::atan(arg); }
216 
218  OPM_HOST_DEVICE static Scalar atan2(Scalar arg1, Scalar arg2)
219  { return std::atan2(arg1, arg2); }
220 
222  OPM_HOST_DEVICE static Scalar sin(Scalar arg)
223  { return std::sin(arg); }
224 
226  OPM_HOST_DEVICE static Scalar asin(Scalar arg)
227  { return std::asin(arg); }
228 
230  OPM_HOST_DEVICE static Scalar sinh(Scalar arg)
231  { return std::sinh(arg); }
232 
234  OPM_HOST_DEVICE static Scalar asinh(Scalar arg)
235  { return std::asinh(arg); }
236 
238  OPM_HOST_DEVICE static Scalar cos(Scalar arg)
239  { return std::cos(arg); }
240 
242  OPM_HOST_DEVICE static Scalar acos(Scalar arg)
243  { return std::acos(arg); }
244 
246  OPM_HOST_DEVICE static Scalar cosh(Scalar arg)
247  { return std::cosh(arg); }
248 
250  OPM_HOST_DEVICE static Scalar acosh(Scalar arg)
251  { return std::acosh(arg); }
252 
254  OPM_HOST_DEVICE static Scalar sqrt(Scalar arg)
255  { return std::sqrt(arg); }
256 
258  OPM_HOST_DEVICE static Scalar exp(Scalar arg)
259  { return std::exp(arg); }
260 
262  OPM_HOST_DEVICE static Scalar log10(Scalar arg)
263  { return std::log10(arg); }
264 
266  OPM_HOST_DEVICE static Scalar log(Scalar arg)
267  { return std::log(arg); }
268 
270  OPM_HOST_DEVICE static Scalar pow(Scalar base, Scalar exp)
271  { return std::pow(base, exp); }
272 
274  OPM_HOST_DEVICE static bool isfinite(Scalar arg)
275  { return std::isfinite(arg); }
276 
278  OPM_HOST_DEVICE static bool isnan(Scalar arg)
279  { return std::isnan(arg); }
280 };
281 
282 template <class Eval1, class Eval2>
284 {
285  typedef typename std::remove_const< typename std::remove_reference<Eval1>::type >::type T;
286  typedef typename std::remove_const< typename std::remove_reference<Eval2>::type >::type U;
287 
288  //static_assert(std::is_constructible<T, U>::value || std::is_constructible<U, T>::value,
289  // "One of the argument types must be constructible to the other");
290 
291  typedef typename std::conditional<std::is_constructible<T, U>::value,
292  T,
293  U>::type type;
294 };
295 
296 // these are convenience functions for not having to type MathToolbox<Scalar>::foo()
297 template <class Evaluation>
298 OPM_HOST_DEVICE Evaluation blank(const Evaluation& x)
300 
301 template <class Evaluation, class Scalar>
302 OPM_HOST_DEVICE Evaluation constant(const Scalar& value)
304 
305 template <class Evaluation, class Scalar>
306 OPM_HOST_DEVICE Evaluation constant(unsigned numDeriv, const Scalar& value)
307 { return MathToolbox<Evaluation>::createConstant(numDeriv, value); }
308 
309 template <class Evaluation, class Scalar>
310 OPM_HOST_DEVICE Evaluation constant(const Evaluation& x, const Scalar& value)
312 
313 template <class Evaluation, class Scalar>
314 OPM_HOST_DEVICE Evaluation variable(unsigned numDeriv, const Scalar& value, unsigned idx)
315 { return MathToolbox<Evaluation>::createVariable(numDeriv, value, idx); }
316 
317 template <class Evaluation, class Scalar>
318 OPM_HOST_DEVICE Evaluation variable(const Evaluation& x, const Scalar& value, unsigned idx)
320 
321 template <class Evaluation, class Scalar>
322 OPM_HOST_DEVICE Evaluation variable(const Scalar& value, unsigned idx)
324 
325 template <class ResultEval, class Evaluation>
326 OPM_HOST_DEVICE auto decay(const Evaluation& value)
327  -> decltype(MathToolbox<Evaluation>::template decay<ResultEval>(value))
328 { return MathToolbox<Evaluation>::template decay<ResultEval>(value); }
329 
330 template <class Evaluation>
331 OPM_HOST_DEVICE auto getValue(const Evaluation& val)
332  -> decltype(MathToolbox<Evaluation>::value(val))
333 { return MathToolbox<Evaluation>::value(val); }
334 
335 template <class Evaluation>
336 OPM_HOST_DEVICE auto scalarValue(const Evaluation& val)
337  -> decltype(MathToolbox<Evaluation>::scalarValue(val))
339 
340 template <class Evaluation1, class Evaluation2>
341 typename ReturnEval_<Evaluation1, Evaluation2>::type
342 OPM_HOST_DEVICE max(const Evaluation1& arg1, const Evaluation2& arg2)
343 { return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::max(arg1, arg2); }
344 
345 template <class Evaluation1, class Evaluation2>
346 typename ReturnEval_<Evaluation1, Evaluation2>::type
347 OPM_HOST_DEVICE min(const Evaluation1& arg1, const Evaluation2& arg2)
348 { return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::min(arg1, arg2); }
349 
350 template <class Evaluation>
351 OPM_HOST_DEVICE Evaluation abs(const Evaluation& value)
353 
354 template <class Evaluation>
355 OPM_HOST_DEVICE Evaluation tan(const Evaluation& value)
357 
358 template <class Evaluation>
359 OPM_HOST_DEVICE Evaluation atan(const Evaluation& value)
361 
362 template <class Evaluation1, class Evaluation2>
363 typename ReturnEval_<Evaluation1, Evaluation2>::type
364 OPM_HOST_DEVICE atan2(const Evaluation1& value1, const Evaluation2& value2)
365 { return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::atan2(value1, value2); }
366 
367 template <class Evaluation>
368 OPM_HOST_DEVICE Evaluation sin(const Evaluation& value)
370 
371 template <class Evaluation>
372 OPM_HOST_DEVICE Evaluation asin(const Evaluation& value)
374 
375 template <class Evaluation>
376 OPM_HOST_DEVICE Evaluation sinh(const Evaluation& value)
378 
379 template <class Evaluation>
380 OPM_HOST_DEVICE Evaluation asinh(const Evaluation& value)
382 
383 template <class Evaluation>
384 OPM_HOST_DEVICE Evaluation cos(const Evaluation& value)
386 
387 template <class Evaluation>
388 OPM_HOST_DEVICE Evaluation acos(const Evaluation& value)
390 
391 template <class Evaluation>
392 OPM_HOST_DEVICE Evaluation cosh(const Evaluation& value)
394 
395 template <class Evaluation>
396 OPM_HOST_DEVICE Evaluation acosh(const Evaluation& value)
398 
399 template <class Evaluation>
400 OPM_HOST_DEVICE Evaluation sqrt(const Evaluation& value)
402 
403 template <class Evaluation>
404 OPM_HOST_DEVICE Evaluation exp(const Evaluation& value)
406 
407 template <class Evaluation>
408 OPM_HOST_DEVICE Evaluation log(const Evaluation& value)
410 
411 template <class Evaluation>
412 OPM_HOST_DEVICE Evaluation log10(const Evaluation& value)
414 
415 template <class Evaluation1, class Evaluation2>
416 typename ReturnEval_<Evaluation1, Evaluation2>::type
417 OPM_HOST_DEVICE pow(const Evaluation1& base, const Evaluation2& exp)
418 { return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::pow(base, exp); }
419 
420 template <class Evaluation>
421 OPM_HOST_DEVICE bool isfinite(const Evaluation& value)
423 
424 template <class Evaluation>
425 OPM_HOST_DEVICE bool isnan(const Evaluation& value)
427 
428 } // namespace Opm
429 
430 #endif
Definition: MathToolbox.hpp:283
static OPM_HOST_DEVICE Scalar sinh(Scalar arg)
The sine hyperbolicus of a value.
Definition: MathToolbox.hpp:230
static OPM_HOST_DEVICE Scalar createVariable(Scalar, Scalar, unsigned)
Given a scalar value, return an evaluation of a linear function that is compatible with a "template" ...
Definition: MathToolbox.hpp:159
static OPM_HOST_DEVICE bool isnan(Scalar arg)
Return true iff the argument&#39;s value or any of its derivatives are NaN values.
Definition: MathToolbox.hpp:278
static OPM_HOST_DEVICE Scalar tan(Scalar arg)
The tangens of a value.
Definition: MathToolbox.hpp:210
static OPM_HOST_DEVICE Scalar max(Scalar arg1, Scalar arg2)
The maximum of two arguments.
Definition: MathToolbox.hpp:198
static OPM_HOST_DEVICE LhsEval decay(Scalar value)
Given a function evaluation, constrain it to its value (if necessary).
Definition: MathToolbox.hpp:174
static OPM_HOST_DEVICE Scalar createBlank(Scalar)
Given a scalar value, return a "compatible" object.
Definition: MathToolbox.hpp:102
static OPM_HOST_DEVICE Scalar createConstant(Scalar, Scalar value)
Given a scalar value, return an evaluation of a constant function that is compatible to a "template" ...
Definition: MathToolbox.hpp:138
static OPM_HOST_DEVICE Scalar sqrt(Scalar arg)
The square root of a value.
Definition: MathToolbox.hpp:254
static OPM_HOST_DEVICE Scalar cos(Scalar arg)
The cosine of a value.
Definition: MathToolbox.hpp:238
static OPM_HOST_DEVICE Scalar atan2(Scalar arg1, Scalar arg2)
The arcus tangens of a value.
Definition: MathToolbox.hpp:218
static OPM_HOST_DEVICE Scalar log10(Scalar arg)
The 10 logarithm of a value.
Definition: MathToolbox.hpp:262
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
static OPM_HOST_DEVICE Scalar log(Scalar arg)
The natural logarithm of a value.
Definition: MathToolbox.hpp:266
static OPM_HOST_DEVICE Scalar acosh(Scalar arg)
The arcus cosine hyperbolicus of a value.
Definition: MathToolbox.hpp:250
ScalarT ValueType
The type used to represent values.
Definition: MathToolbox.hpp:67
static OPM_HOST_DEVICE Scalar abs(Scalar arg)
The absolute value.
Definition: MathToolbox.hpp:206
static OPM_HOST_DEVICE bool isfinite(Scalar arg)
Return true iff the argument&#39;s value and all its derivatives are finite values.
Definition: MathToolbox.hpp:274
static OPM_HOST_DEVICE Scalar asin(Scalar arg)
The arcus sine of a value.
Definition: MathToolbox.hpp:226
static OPM_HOST_DEVICE Scalar value(Scalar value)
Return the value of the function at a given evaluation point.
Definition: MathToolbox.hpp:84
Definition: MathToolbox.hpp:50
ScalarT Scalar
The type used to represent "primitive" scalar values.
Definition: MathToolbox.hpp:53
static OPM_HOST_DEVICE bool isSame(Scalar a, Scalar b, Scalar tolerance)
Returns true if two values are identical up to a specified tolerance.
Definition: MathToolbox.hpp:185
static OPM_HOST_DEVICE Scalar createConstant(unsigned numDerivatives, Scalar value)
Given a scalar value, return an evaluation of a constant function that features a given number of der...
Definition: MathToolbox.hpp:123
static OPM_HOST_DEVICE Scalar scalarValue(Scalar value)
Return the primitive scalar value of a value object.
Definition: MathToolbox.hpp:93
static OPM_HOST_DEVICE Scalar pow(Scalar base, Scalar exp)
Exponentiation to an arbitrary base.
Definition: MathToolbox.hpp:270
static OPM_HOST_DEVICE Scalar createConstant(Scalar value)
Given a scalar value, return an evaluation of a constant function.
Definition: MathToolbox.hpp:112
static OPM_HOST_DEVICE Scalar acos(Scalar arg)
The arcus cosine of a value.
Definition: MathToolbox.hpp:242
static OPM_HOST_DEVICE Scalar asinh(Scalar arg)
The arcus sine hyperbolicus of a value.
Definition: MathToolbox.hpp:234
static OPM_HOST_DEVICE Scalar atan(Scalar arg)
The arcus tangens of a value.
Definition: MathToolbox.hpp:214
static OPM_HOST_DEVICE Scalar cosh(Scalar arg)
The cosine hyperbolicus of a value.
Definition: MathToolbox.hpp:246
MathToolbox< Scalar > InnerToolbox
The toolbox for the type of value objects.
Definition: MathToolbox.hpp:76
static OPM_HOST_DEVICE Scalar exp(Scalar arg)
The natural exponentiation of a value.
Definition: MathToolbox.hpp:258
static OPM_HOST_DEVICE Scalar sin(Scalar arg)
The sine of a value.
Definition: MathToolbox.hpp:222
static OPM_HOST_DEVICE Scalar createVariable(Scalar, unsigned)
Given a scalar value, return an evaluation of a linear function.
Definition: MathToolbox.hpp:148
static OPM_HOST_DEVICE Scalar min(Scalar arg1, Scalar arg2)
The minimum of two arguments.
Definition: MathToolbox.hpp:202