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 
36 
37 #include <cmath>
38 #include <algorithm>
39 #include <type_traits>
40 #include <stdexcept>
41 
42 namespace Opm {
43 /*
44  * \brief A traits class which provides basic mathematical functions for arbitrary scalar
45  * floating point values.
46  *
47  * The reason why this is done in such a complicated way is to enable other approaches,
48  * in particular automatic differentiation based ones.
49  */
50 template <class ScalarT>
52 {
53  static_assert(std::is_floating_point<ScalarT>::value,
54  "This class expects floating point scalars! (specialization missing?)");
55 public:
59  typedef ScalarT Scalar;
60 
68  typedef ScalarT ValueType;
69 
78 
86  { return value; }
87 
95  { return value; }
96 
104  { return Scalar(); }
105 
114  { return value; }
115 
124  static Scalar createConstant(unsigned numDerivatives, Scalar value)
125  {
126  if (numDerivatives != 0)
127  throw std::logic_error("Plain floating point objects cannot represent any derivatives");
128  return value;
129  }
130 
140  { return value; }
141 
149  static Scalar createVariable(Scalar, unsigned)
150  { throw std::logic_error("Plain floating point objects cannot represent variables"); }
151 
160  static Scalar createVariable(Scalar, Scalar, unsigned)
161  { throw std::logic_error("Plain floating point objects cannot represent variables"); }
162 
174  template <class LhsEval>
175  static LhsEval decay(Scalar value)
176  {
177  static_assert(std::is_floating_point<LhsEval>::value,
178  "The left-hand side must be a primitive floating point type!");
179 
180  return value;
181  }
182 
186  static bool isSame(Scalar a, Scalar b, Scalar tolerance)
187  {
188  Scalar valueDiff = a - b;
189  Scalar denom = std::max<Scalar>(1.0, std::abs(a + b));
190 
191  return std::abs(valueDiff) < tolerance || std::abs(valueDiff)/denom < tolerance;
192  }
193 
195  // arithmetic functions
197 
199  static Scalar max(Scalar arg1, Scalar arg2)
200  { return std::max(arg1, arg2); }
201 
203  static Scalar min(Scalar arg1, Scalar arg2)
204  { return std::min(arg1, arg2); }
205 
207  static Scalar abs(Scalar arg)
208  { return std::abs(arg); }
209 
211  static Scalar tan(Scalar arg)
212  { return std::tan(arg); }
213 
215  static Scalar atan(Scalar arg)
216  { return std::atan(arg); }
217 
219  static Scalar atan2(Scalar arg1, Scalar arg2)
220  { return std::atan2(arg1, arg2); }
221 
223  static Scalar sin(Scalar arg)
224  { return std::sin(arg); }
225 
227  static Scalar asin(Scalar arg)
228  { return std::asin(arg); }
229 
231  static Scalar cos(Scalar arg)
232  { return std::cos(arg); }
233 
235  static Scalar acos(Scalar arg)
236  { return std::acos(arg); }
237 
239  static Scalar sqrt(Scalar arg)
240  { return std::sqrt(arg); }
241 
243  static Scalar exp(Scalar arg)
244  { return std::exp(arg); }
245 
247  static Scalar log10(Scalar arg)
248  { return std::log10(arg); }
249 
251  static Scalar log(Scalar arg)
252  { return std::log(arg); }
253 
255  static Scalar pow(Scalar base, Scalar exp)
256  { return std::pow(base, exp); }
257 
259  static bool isfinite(Scalar arg)
260  { return std::isfinite(arg); }
261 
263  static bool isnan(Scalar arg)
264  { return std::isnan(arg); }
265 };
266 
267 template <class Eval1, class Eval2>
269 {
270  typedef typename std::remove_const< typename std::remove_reference<Eval1>::type >::type T;
271  typedef typename std::remove_const< typename std::remove_reference<Eval2>::type >::type U;
272 
273  //static_assert(std::is_constructible<T, U>::value || std::is_constructible<U, T>::value,
274  // "One of the argument types must be constructible to the other");
275 
276  typedef typename std::conditional<std::is_constructible<T, U>::value,
277  T,
278  U>::type type;
279 };
280 
281 // these are convenience functions for not having to type MathToolbox<Scalar>::foo()
282 template <class Evaluation>
283 Evaluation blank(const Evaluation& x)
285 
286 template <class Evaluation, class Scalar>
287 Evaluation constant(const Scalar& value)
289 
290 template <class Evaluation, class Scalar>
291 Evaluation constant(unsigned numDeriv, const Scalar& value)
292 { return MathToolbox<Evaluation>::createConstant(numDeriv, value); }
293 
294 template <class Evaluation, class Scalar>
295 Evaluation constant(const Evaluation& x, const Scalar& value)
296 { return MathToolbox<Evaluation>::createConstant(x, value); }
297 
298 template <class Evaluation, class Scalar>
299 Evaluation variable(unsigned numDeriv, const Scalar& value, unsigned idx)
300 { return MathToolbox<Evaluation>::createVariable(numDeriv, value, idx); }
301 
302 template <class Evaluation, class Scalar>
303 Evaluation variable(const Evaluation& x, const Scalar& value, unsigned idx)
304 { return MathToolbox<Evaluation>::createVariable(x, value, idx); }
305 
306 template <class Evaluation, class Scalar>
307 Evaluation variable(const Scalar& value, unsigned idx)
308 { return MathToolbox<Evaluation>::createVariable(value, idx); }
309 
310 template <class ResultEval, class Evaluation>
311 auto decay(const Evaluation& value)
312  -> decltype(MathToolbox<Evaluation>::template decay<ResultEval>(value))
313 { return MathToolbox<Evaluation>::template decay<ResultEval>(value); }
314 
315 template <class Evaluation>
316 auto getValue(const Evaluation& val)
317  -> decltype(MathToolbox<Evaluation>::value(val))
318 { return MathToolbox<Evaluation>::value(val); }
319 
320 template <class Evaluation>
321 auto scalarValue(const Evaluation& val)
322  -> decltype(MathToolbox<Evaluation>::scalarValue(val))
324 
325 template <class Evaluation1, class Evaluation2>
326 typename ReturnEval_<Evaluation1, Evaluation2>::type
327 max(const Evaluation1& arg1, const Evaluation2& arg2)
328 { return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::max(arg1, arg2); }
329 
330 template <class Evaluation1, class Evaluation2>
331 typename ReturnEval_<Evaluation1, Evaluation2>::type
332 min(const Evaluation1& arg1, const Evaluation2& arg2)
333 { return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::min(arg1, arg2); }
334 
335 template <class Evaluation>
336 Evaluation abs(const Evaluation& value)
337 { return MathToolbox<Evaluation>::abs(value); }
338 
339 template <class Evaluation>
340 Evaluation tan(const Evaluation& value)
341 { return MathToolbox<Evaluation>::tan(value); }
342 
343 template <class Evaluation>
344 Evaluation atan(const Evaluation& value)
345 { return MathToolbox<Evaluation>::atan(value); }
346 
347 template <class Evaluation1, class Evaluation2>
348 typename ReturnEval_<Evaluation1, Evaluation2>::type
349 atan2(const Evaluation1& value1, const Evaluation2& value2)
350 { return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::atan2(value1, value2); }
351 
352 template <class Evaluation>
353 Evaluation sin(const Evaluation& value)
354 { return MathToolbox<Evaluation>::sin(value); }
355 
356 template <class Evaluation>
357 Evaluation asin(const Evaluation& value)
358 { return MathToolbox<Evaluation>::asin(value); }
359 
360 template <class Evaluation>
361 Evaluation cos(const Evaluation& value)
362 { return MathToolbox<Evaluation>::cos(value); }
363 
364 template <class Evaluation>
365 Evaluation acos(const Evaluation& value)
366 { return MathToolbox<Evaluation>::acos(value); }
367 
368 template <class Evaluation>
369 Evaluation sqrt(const Evaluation& value)
370 { return MathToolbox<Evaluation>::sqrt(value); }
371 
372 template <class Evaluation>
373 Evaluation exp(const Evaluation& value)
374 { return MathToolbox<Evaluation>::exp(value); }
375 
376 template <class Evaluation>
377 Evaluation log(const Evaluation& value)
378 { return MathToolbox<Evaluation>::log(value); }
379 
380 template <class Evaluation>
381 Evaluation log10(const Evaluation& value)
382 { return MathToolbox<Evaluation>::log10(value); }
383 
384 template <class Evaluation1, class Evaluation2>
385 typename ReturnEval_<Evaluation1, Evaluation2>::type
386 pow(const Evaluation1& base, const Evaluation2& exp)
387 { return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::pow(base, exp); }
388 
389 template <class Evaluation>
390 bool isfinite(const Evaluation& value)
391 { return MathToolbox<Evaluation>::isfinite(value); }
392 
393 template <class Evaluation>
394 bool isnan(const Evaluation& value)
395 { return MathToolbox<Evaluation>::isnan(value); }
396 
397 } // namespace Opm
398 
399 #endif
400 
Provides the OPM_UNUSED macro.
Definition: MathToolbox.hpp:52
static LhsEval decay(Scalar value)
Given a function evaluation, constrain it to its value (if necessary).
Definition: MathToolbox.hpp:175
static bool isSame(Scalar a, Scalar b, Scalar tolerance)
Returns true if two values are identical up to a specified tolerance.
Definition: MathToolbox.hpp:186
static Scalar min(Scalar arg1, Scalar arg2)
The minimum of two arguments.
Definition: MathToolbox.hpp:203
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:139
static Scalar createBlank(Scalar)
Given a scalar value, return a "compatible" object.
Definition: MathToolbox.hpp:103
static Scalar value(Scalar value)
Return the value of the function at a given evaluation point.
Definition: MathToolbox.hpp:85
ScalarT Scalar
The type used to represent "primitive" scalar values.
Definition: MathToolbox.hpp:54
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:160
static Scalar atan2(Scalar arg1, Scalar arg2)
The arcus tangens of a value.
Definition: MathToolbox.hpp:219
static Scalar cos(Scalar arg)
The cosine of a value.
Definition: MathToolbox.hpp:231
static Scalar tan(Scalar arg)
The tangens of a value.
Definition: MathToolbox.hpp:211
static bool isfinite(Scalar arg)
Return true iff the argument's value and all its derivatives are finite values.
Definition: MathToolbox.hpp:259
static Scalar exp(Scalar arg)
The natural exponentiation of a value.
Definition: MathToolbox.hpp:243
static Scalar acos(Scalar arg)
The arcus cosine of a value.
Definition: MathToolbox.hpp:235
static Scalar sqrt(Scalar arg)
The square root of a value.
Definition: MathToolbox.hpp:239
static Scalar sin(Scalar arg)
The sine of a value.
Definition: MathToolbox.hpp:223
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:124
static Scalar pow(Scalar base, Scalar exp)
Exponentiation to an arbitrary base.
Definition: MathToolbox.hpp:255
ScalarT ValueType
The type used to represent values.
Definition: MathToolbox.hpp:68
static Scalar abs(Scalar arg)
The absolute value.
Definition: MathToolbox.hpp:207
MathToolbox< Scalar > InnerToolbox
The toolbox for the type of value objects.
Definition: MathToolbox.hpp:77
static Scalar log10(Scalar arg)
The 10 logarithm of a value.
Definition: MathToolbox.hpp:247
static Scalar createVariable(Scalar, unsigned)
Given a scalar value, return an evaluation of a linear function.
Definition: MathToolbox.hpp:149
static Scalar log(Scalar arg)
The natural logarithm of a value.
Definition: MathToolbox.hpp:251
static Scalar createConstant(Scalar value)
Given a scalar value, return an evaluation of a constant function.
Definition: MathToolbox.hpp:113
static Scalar atan(Scalar arg)
The arcus tangens of a value.
Definition: MathToolbox.hpp:215
static Scalar scalarValue(Scalar value)
Return the primitive scalar value of a value object.
Definition: MathToolbox.hpp:94
static Scalar asin(Scalar arg)
The arcus sine of a value.
Definition: MathToolbox.hpp:227
static Scalar max(Scalar arg1, Scalar arg2)
The maximum of two arguments.
Definition: MathToolbox.hpp:199
static bool isnan(Scalar arg)
Return true iff the argument's value or any of its derivatives are NaN values.
Definition: MathToolbox.hpp:263
Definition: MathToolbox.hpp:269