My Project
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 
40 namespace Opm {
41 /*
42  * \brief A traits class which provides basic mathematical functions for arbitrary scalar
43  * floating point values.
44  *
45  * The reason why this is done in such a complicated way is to enable other approaches,
46  * in particular automatic differentiation based ones.
47  */
48 template <class ScalarT>
50 {
51  static_assert(std::is_floating_point<ScalarT>::value,
52  "This class expects floating point scalars! (specialization missing?)");
53 public:
57  typedef ScalarT Scalar;
58 
66  typedef ScalarT ValueType;
67 
76 
84  { return value; }
85 
93  { return value; }
94 
101  static Scalar createBlank(Scalar /*value*/)
102  { return Scalar(); }
103 
112  { return value; }
113 
122  static Scalar createConstant(unsigned numDerivatives, Scalar value)
123  {
124  if (numDerivatives != 0)
125  throw std::logic_error("Plain floating point objects cannot represent any derivatives");
126  return value;
127  }
128 
138  { return value; }
139 
147  static Scalar createVariable(Scalar /*value*/, unsigned /*varIdx*/)
148  { throw std::logic_error("Plain floating point objects cannot represent variables"); }
149 
158  static Scalar createVariable(Scalar /*x*/, Scalar /*value*/, unsigned /*varIdx*/)
159  { throw std::logic_error("Plain floating point objects cannot represent variables"); }
160 
172  template <class LhsEval>
173  static LhsEval decay(Scalar value)
174  {
175  static_assert(std::is_floating_point<LhsEval>::value,
176  "The left-hand side must be a primitive floating point type!");
177 
178  return value;
179  }
180 
184  static bool isSame(Scalar a, Scalar b, Scalar tolerance)
185  {
186  Scalar valueDiff = a - b;
187  Scalar denom = std::max<Scalar>(1.0, std::abs(a + b));
188 
189  return std::abs(valueDiff) < tolerance || std::abs(valueDiff)/denom < tolerance;
190  }
191 
193  // arithmetic functions
195 
197  static Scalar max(Scalar arg1, Scalar arg2)
198  { return std::max(arg1, arg2); }
199 
201  static Scalar min(Scalar arg1, Scalar arg2)
202  { return std::min(arg1, arg2); }
203 
205  static Scalar abs(Scalar arg)
206  { return std::abs(arg); }
207 
209  static Scalar tan(Scalar arg)
210  { return std::tan(arg); }
211 
213  static Scalar atan(Scalar arg)
214  { return std::atan(arg); }
215 
217  static Scalar atan2(Scalar arg1, Scalar arg2)
218  { return std::atan2(arg1, arg2); }
219 
221  static Scalar sin(Scalar arg)
222  { return std::sin(arg); }
223 
225  static Scalar asin(Scalar arg)
226  { return std::asin(arg); }
227 
229  static Scalar sinh(Scalar arg)
230  { return std::sinh(arg); }
231 
233  static Scalar asinh(Scalar arg)
234  { return std::asinh(arg); }
235 
237  static Scalar cos(Scalar arg)
238  { return std::cos(arg); }
239 
241  static Scalar acos(Scalar arg)
242  { return std::acos(arg); }
243 
245  static Scalar cosh(Scalar arg)
246  { return std::cosh(arg); }
247 
249  static Scalar acosh(Scalar arg)
250  { return std::acosh(arg); }
251 
253  static Scalar sqrt(Scalar arg)
254  { return std::sqrt(arg); }
255 
257  static Scalar exp(Scalar arg)
258  { return std::exp(arg); }
259 
261  static Scalar log10(Scalar arg)
262  { return std::log10(arg); }
263 
265  static Scalar log(Scalar arg)
266  { return std::log(arg); }
267 
269  static Scalar pow(Scalar base, Scalar exp)
270  { return std::pow(base, exp); }
271 
273  static bool isfinite(Scalar arg)
274  { return std::isfinite(arg); }
275 
277  static bool isnan(Scalar arg)
278  { return std::isnan(arg); }
279 };
280 
281 template <class Eval1, class Eval2>
283 {
284  typedef typename std::remove_const< typename std::remove_reference<Eval1>::type >::type T;
285  typedef typename std::remove_const< typename std::remove_reference<Eval2>::type >::type U;
286 
287  //static_assert(std::is_constructible<T, U>::value || std::is_constructible<U, T>::value,
288  // "One of the argument types must be constructible to the other");
289 
290  typedef typename std::conditional<std::is_constructible<T, U>::value,
291  T,
292  U>::type type;
293 };
294 
295 // these are convenience functions for not having to type MathToolbox<Scalar>::foo()
296 template <class Evaluation>
297 Evaluation blank(const Evaluation& x)
299 
300 template <class Evaluation, class Scalar>
301 Evaluation constant(const Scalar& value)
303 
304 template <class Evaluation, class Scalar>
305 Evaluation constant(unsigned numDeriv, const Scalar& value)
306 { return MathToolbox<Evaluation>::createConstant(numDeriv, value); }
307 
308 template <class Evaluation, class Scalar>
309 Evaluation constant(const Evaluation& x, const Scalar& value)
310 { return MathToolbox<Evaluation>::createConstant(x, value); }
311 
312 template <class Evaluation, class Scalar>
313 Evaluation variable(unsigned numDeriv, const Scalar& value, unsigned idx)
314 { return MathToolbox<Evaluation>::createVariable(numDeriv, value, idx); }
315 
316 template <class Evaluation, class Scalar>
317 Evaluation variable(const Evaluation& x, const Scalar& value, unsigned idx)
318 { return MathToolbox<Evaluation>::createVariable(x, value, idx); }
319 
320 template <class Evaluation, class Scalar>
321 Evaluation variable(const Scalar& value, unsigned idx)
322 { return MathToolbox<Evaluation>::createVariable(value, idx); }
323 
324 template <class ResultEval, class Evaluation>
325 auto decay(const Evaluation& value)
326  -> decltype(MathToolbox<Evaluation>::template decay<ResultEval>(value))
327 { return MathToolbox<Evaluation>::template decay<ResultEval>(value); }
328 
329 template <class Evaluation>
330 auto getValue(const Evaluation& val)
331  -> decltype(MathToolbox<Evaluation>::value(val))
332 { return MathToolbox<Evaluation>::value(val); }
333 
334 template <class Evaluation>
335 auto scalarValue(const Evaluation& val)
336  -> decltype(MathToolbox<Evaluation>::scalarValue(val))
338 
339 template <class Evaluation1, class Evaluation2>
340 typename ReturnEval_<Evaluation1, Evaluation2>::type
341 max(const Evaluation1& arg1, const Evaluation2& arg2)
342 { return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::max(arg1, arg2); }
343 
344 template <class Evaluation1, class Evaluation2>
345 typename ReturnEval_<Evaluation1, Evaluation2>::type
346 min(const Evaluation1& arg1, const Evaluation2& arg2)
347 { return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::min(arg1, arg2); }
348 
349 template <class Evaluation>
350 Evaluation abs(const Evaluation& value)
351 { return MathToolbox<Evaluation>::abs(value); }
352 
353 template <class Evaluation>
354 Evaluation tan(const Evaluation& value)
355 { return MathToolbox<Evaluation>::tan(value); }
356 
357 template <class Evaluation>
358 Evaluation atan(const Evaluation& value)
359 { return MathToolbox<Evaluation>::atan(value); }
360 
361 template <class Evaluation1, class Evaluation2>
362 typename ReturnEval_<Evaluation1, Evaluation2>::type
363 atan2(const Evaluation1& value1, const Evaluation2& value2)
364 { return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::atan2(value1, value2); }
365 
366 template <class Evaluation>
367 Evaluation sin(const Evaluation& value)
368 { return MathToolbox<Evaluation>::sin(value); }
369 
370 template <class Evaluation>
371 Evaluation asin(const Evaluation& value)
372 { return MathToolbox<Evaluation>::asin(value); }
373 
374 template <class Evaluation>
375 Evaluation sinh(const Evaluation& value)
376 { return MathToolbox<Evaluation>::sinh(value); }
377 
378 template <class Evaluation>
379 Evaluation asinh(const Evaluation& value)
380 { return MathToolbox<Evaluation>::asinh(value); }
381 
382 template <class Evaluation>
383 Evaluation cos(const Evaluation& value)
384 { return MathToolbox<Evaluation>::cos(value); }
385 
386 template <class Evaluation>
387 Evaluation acos(const Evaluation& value)
388 { return MathToolbox<Evaluation>::acos(value); }
389 
390 template <class Evaluation>
391 Evaluation cosh(const Evaluation& value)
392 { return MathToolbox<Evaluation>::cosh(value); }
393 
394 template <class Evaluation>
395 Evaluation acosh(const Evaluation& value)
396 { return MathToolbox<Evaluation>::acosh(value); }
397 
398 template <class Evaluation>
399 Evaluation sqrt(const Evaluation& value)
400 { return MathToolbox<Evaluation>::sqrt(value); }
401 
402 template <class Evaluation>
403 Evaluation exp(const Evaluation& value)
404 { return MathToolbox<Evaluation>::exp(value); }
405 
406 template <class Evaluation>
407 Evaluation log(const Evaluation& value)
408 { return MathToolbox<Evaluation>::log(value); }
409 
410 template <class Evaluation>
411 Evaluation log10(const Evaluation& value)
412 { return MathToolbox<Evaluation>::log10(value); }
413 
414 template <class Evaluation1, class Evaluation2>
415 typename ReturnEval_<Evaluation1, Evaluation2>::type
416 pow(const Evaluation1& base, const Evaluation2& exp)
417 { return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::pow(base, exp); }
418 
419 template <class Evaluation>
420 bool isfinite(const Evaluation& value)
421 { return MathToolbox<Evaluation>::isfinite(value); }
422 
423 template <class Evaluation>
424 bool isnan(const Evaluation& value)
425 { return MathToolbox<Evaluation>::isnan(value); }
426 
427 } // namespace Opm
428 
429 #endif
430 
Definition: MathToolbox.hpp:50
static LhsEval decay(Scalar value)
Given a function evaluation, constrain it to its value (if necessary).
Definition: MathToolbox.hpp:173
static bool isSame(Scalar a, Scalar b, Scalar tolerance)
Returns true if two values are identical up to a specified tolerance.
Definition: MathToolbox.hpp:184
static Scalar min(Scalar arg1, Scalar arg2)
The minimum of two arguments.
Definition: MathToolbox.hpp:201
static 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:137
static Scalar createBlank(Scalar)
Given a scalar value, return a "compatible" object.
Definition: MathToolbox.hpp:101
static Scalar value(Scalar value)
Return the value of the function at a given evaluation point.
Definition: MathToolbox.hpp:83
ScalarT Scalar
The type used to represent "primitive" scalar values.
Definition: MathToolbox.hpp:52
static 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:158
static Scalar atan2(Scalar arg1, Scalar arg2)
The arcus tangens of a value.
Definition: MathToolbox.hpp:217
static Scalar cos(Scalar arg)
The cosine of a value.
Definition: MathToolbox.hpp:237
static Scalar asinh(Scalar arg)
The arcus sine hyperbolicus of a value.
Definition: MathToolbox.hpp:233
static Scalar tan(Scalar arg)
The tangens of a value.
Definition: MathToolbox.hpp:209
static bool isfinite(Scalar arg)
Return true iff the argument's value and all its derivatives are finite values.
Definition: MathToolbox.hpp:273
static Scalar exp(Scalar arg)
The natural exponentiation of a value.
Definition: MathToolbox.hpp:257
static Scalar acos(Scalar arg)
The arcus cosine of a value.
Definition: MathToolbox.hpp:241
static Scalar sqrt(Scalar arg)
The square root of a value.
Definition: MathToolbox.hpp:253
static Scalar sin(Scalar arg)
The sine of a value.
Definition: MathToolbox.hpp:221
static 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:122
static Scalar pow(Scalar base, Scalar exp)
Exponentiation to an arbitrary base.
Definition: MathToolbox.hpp:269
ScalarT ValueType
The type used to represent values.
Definition: MathToolbox.hpp:66
static Scalar abs(Scalar arg)
The absolute value.
Definition: MathToolbox.hpp:205
static Scalar sinh(Scalar arg)
The sine hyperbolicus of a value.
Definition: MathToolbox.hpp:229
MathToolbox< Scalar > InnerToolbox
The toolbox for the type of value objects.
Definition: MathToolbox.hpp:75
static Scalar log10(Scalar arg)
The 10 logarithm of a value.
Definition: MathToolbox.hpp:261
static Scalar createVariable(Scalar, unsigned)
Given a scalar value, return an evaluation of a linear function.
Definition: MathToolbox.hpp:147
static Scalar log(Scalar arg)
The natural logarithm of a value.
Definition: MathToolbox.hpp:265
static Scalar acosh(Scalar arg)
The arcus cosine hyperbolicus of a value.
Definition: MathToolbox.hpp:249
static Scalar createConstant(Scalar value)
Given a scalar value, return an evaluation of a constant function.
Definition: MathToolbox.hpp:111
static Scalar atan(Scalar arg)
The arcus tangens of a value.
Definition: MathToolbox.hpp:213
static Scalar scalarValue(Scalar value)
Return the primitive scalar value of a value object.
Definition: MathToolbox.hpp:92
static Scalar asin(Scalar arg)
The arcus sine of a value.
Definition: MathToolbox.hpp:225
static Scalar cosh(Scalar arg)
The cosine hyperbolicus of a value.
Definition: MathToolbox.hpp:245
static Scalar max(Scalar arg1, Scalar arg2)
The maximum of two arguments.
Definition: MathToolbox.hpp:197
static bool isnan(Scalar arg)
Return true iff the argument's value or any of its derivatives are NaN values.
Definition: MathToolbox.hpp:277
Definition: MathToolbox.hpp:283