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
40namespace 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 */
48template <class ScalarT>
50{
51 static_assert(std::is_floating_point<ScalarT>::value,
52 "This class expects floating point scalars! (specialization missing?)");
53public:
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
281template <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,
293};
294
295// these are convenience functions for not having to type MathToolbox<Scalar>::foo()
296template <class Evaluation>
297Evaluation blank(const Evaluation& x)
299
300template <class Evaluation, class Scalar>
301Evaluation constant(const Scalar& value)
303
304template <class Evaluation, class Scalar>
305Evaluation constant(unsigned numDeriv, const Scalar& value)
306{ return MathToolbox<Evaluation>::createConstant(numDeriv, value); }
307
308template <class Evaluation, class Scalar>
309Evaluation constant(const Evaluation& x, const Scalar& value)
310{ return MathToolbox<Evaluation>::createConstant(x, value); }
311
312template <class Evaluation, class Scalar>
313Evaluation variable(unsigned numDeriv, const Scalar& value, unsigned idx)
314{ return MathToolbox<Evaluation>::createVariable(numDeriv, value, idx); }
315
316template <class Evaluation, class Scalar>
317Evaluation variable(const Evaluation& x, const Scalar& value, unsigned idx)
318{ return MathToolbox<Evaluation>::createVariable(x, value, idx); }
319
320template <class Evaluation, class Scalar>
321Evaluation variable(const Scalar& value, unsigned idx)
322{ return MathToolbox<Evaluation>::createVariable(value, idx); }
323
324template <class ResultEval, class Evaluation>
325auto decay(const Evaluation& value)
326 -> decltype(MathToolbox<Evaluation>::template decay<ResultEval>(value))
327{ return MathToolbox<Evaluation>::template decay<ResultEval>(value); }
328
329template <class Evaluation>
330auto getValue(const Evaluation& val)
331 -> decltype(MathToolbox<Evaluation>::value(val))
332{ return MathToolbox<Evaluation>::value(val); }
333
334template <class Evaluation>
335auto scalarValue(const Evaluation& val)
338
339template <class Evaluation1, class Evaluation2>
341max(const Evaluation1& arg1, const Evaluation2& arg2)
343
344template <class Evaluation1, class Evaluation2>
346min(const Evaluation1& arg1, const Evaluation2& arg2)
348
349template <class Evaluation>
350Evaluation abs(const Evaluation& value)
351{ return MathToolbox<Evaluation>::abs(value); }
352
353template <class Evaluation>
354Evaluation tan(const Evaluation& value)
355{ return MathToolbox<Evaluation>::tan(value); }
356
357template <class Evaluation>
358Evaluation atan(const Evaluation& value)
359{ return MathToolbox<Evaluation>::atan(value); }
360
361template <class Evaluation1, class Evaluation2>
363atan2(const Evaluation1& value1, const Evaluation2& value2)
365
366template <class Evaluation>
367Evaluation sin(const Evaluation& value)
368{ return MathToolbox<Evaluation>::sin(value); }
369
370template <class Evaluation>
371Evaluation asin(const Evaluation& value)
372{ return MathToolbox<Evaluation>::asin(value); }
373
374template <class Evaluation>
375Evaluation sinh(const Evaluation& value)
376{ return MathToolbox<Evaluation>::sinh(value); }
377
378template <class Evaluation>
379Evaluation asinh(const Evaluation& value)
380{ return MathToolbox<Evaluation>::asinh(value); }
381
382template <class Evaluation>
383Evaluation cos(const Evaluation& value)
384{ return MathToolbox<Evaluation>::cos(value); }
385
386template <class Evaluation>
387Evaluation acos(const Evaluation& value)
388{ return MathToolbox<Evaluation>::acos(value); }
389
390template <class Evaluation>
391Evaluation cosh(const Evaluation& value)
392{ return MathToolbox<Evaluation>::cosh(value); }
393
394template <class Evaluation>
395Evaluation acosh(const Evaluation& value)
396{ return MathToolbox<Evaluation>::acosh(value); }
397
398template <class Evaluation>
399Evaluation sqrt(const Evaluation& value)
400{ return MathToolbox<Evaluation>::sqrt(value); }
401
402template <class Evaluation>
403Evaluation exp(const Evaluation& value)
404{ return MathToolbox<Evaluation>::exp(value); }
405
406template <class Evaluation>
407Evaluation log(const Evaluation& value)
408{ return MathToolbox<Evaluation>::log(value); }
409
410template <class Evaluation>
411Evaluation log10(const Evaluation& value)
412{ return MathToolbox<Evaluation>::log10(value); }
413
414template <class Evaluation1, class Evaluation2>
416pow(const Evaluation1& base, const Evaluation2& exp)
418
419template <class Evaluation>
420bool isfinite(const Evaluation& value)
421{ return MathToolbox<Evaluation>::isfinite(value); }
422
423template <class Evaluation>
424bool isnan(const Evaluation& value)
425{ return MathToolbox<Evaluation>::isnan(value); }
426
427} // namespace Opm
428
429#endif
430
Definition: Air_Mesitylene.hpp:34
Evaluation cos(const Evaluation &value)
Definition: MathToolbox.hpp:383
bool isfinite(const Evaluation &value)
Definition: MathToolbox.hpp:420
Evaluation sin(const Evaluation &value)
Definition: MathToolbox.hpp:367
Evaluation acosh(const Evaluation &value)
Definition: MathToolbox.hpp:395
Evaluation constant(const Scalar &value)
Definition: MathToolbox.hpp:301
Evaluation atan(const Evaluation &value)
Definition: MathToolbox.hpp:358
Evaluation log10(const Evaluation &value)
Definition: MathToolbox.hpp:411
Evaluation blank(const Evaluation &x)
Definition: MathToolbox.hpp:297
Evaluation exp(const Evaluation &value)
Definition: MathToolbox.hpp:403
Evaluation sqrt(const Evaluation &value)
Definition: MathToolbox.hpp:399
ReturnEval_< Evaluation1, Evaluation2 >::type min(const Evaluation1 &arg1, const Evaluation2 &arg2)
Definition: MathToolbox.hpp:346
bool isnan(const Evaluation &value)
Definition: MathToolbox.hpp:424
ReturnEval_< Evaluation1, Evaluation2 >::type max(const Evaluation1 &arg1, const Evaluation2 &arg2)
Definition: MathToolbox.hpp:341
Evaluation variable(unsigned numDeriv, const Scalar &value, unsigned idx)
Definition: MathToolbox.hpp:313
Evaluation log(const Evaluation &value)
Definition: MathToolbox.hpp:407
Evaluation tan(const Evaluation &value)
Definition: MathToolbox.hpp:354
auto getValue(const Evaluation &val) -> decltype(MathToolbox< Evaluation >::value(val))
Definition: MathToolbox.hpp:330
Evaluation asinh(const Evaluation &value)
Definition: MathToolbox.hpp:379
ReturnEval_< Evaluation1, Evaluation2 >::type atan2(const Evaluation1 &value1, const Evaluation2 &value2)
Definition: MathToolbox.hpp:363
auto scalarValue(const Evaluation &val) -> decltype(MathToolbox< Evaluation >::scalarValue(val))
Definition: MathToolbox.hpp:335
Evaluation asin(const Evaluation &value)
Definition: MathToolbox.hpp:371
Evaluation acos(const Evaluation &value)
Definition: MathToolbox.hpp:387
Evaluation abs(const Evaluation &value)
Definition: MathToolbox.hpp:350
auto decay(const Evaluation &value) -> decltype(MathToolbox< Evaluation >::template decay< ResultEval >(value))
Definition: MathToolbox.hpp:325
Evaluation cosh(const Evaluation &value)
Definition: MathToolbox.hpp:391
Evaluation sinh(const Evaluation &value)
Definition: MathToolbox.hpp:375
ReturnEval_< Evaluation1, Evaluation2 >::type pow(const Evaluation1 &base, const Evaluation2 &exp)
Definition: MathToolbox.hpp:416
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:57
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
std::conditional< std::is_constructible< T, U >::value, T, U >::type type
Definition: MathToolbox.hpp:292
std::remove_const< typenamestd::remove_reference< Eval1 >::type >::type T
Definition: MathToolbox.hpp:284
std::remove_const< typenamestd::remove_reference< Eval2 >::type >::type U
Definition: MathToolbox.hpp:285