My Project
Loading...
Searching...
No Matches
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
41namespace 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 */
49template <class ScalarT>
51{
52 static_assert(std::is_floating_point<ScalarT>::value,
53 "This class expects floating point scalars! (specialization missing?)");
54public:
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
282template <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()
297template <class Evaluation>
298OPM_HOST_DEVICE Evaluation blank(const Evaluation& x)
300
301template <class Evaluation, class Scalar>
302OPM_HOST_DEVICE Evaluation constant(const Scalar& value)
304
305template <class Evaluation, class Scalar>
306OPM_HOST_DEVICE Evaluation constant(unsigned numDeriv, const Scalar& value)
307{ return MathToolbox<Evaluation>::createConstant(numDeriv, value); }
308
309template <class Evaluation, class Scalar>
310OPM_HOST_DEVICE Evaluation constant(const Evaluation& x, const Scalar& value)
311{ return MathToolbox<Evaluation>::createConstant(x, value); }
312
313template <class Evaluation, class Scalar>
314OPM_HOST_DEVICE Evaluation variable(unsigned numDeriv, const Scalar& value, unsigned idx)
315{ return MathToolbox<Evaluation>::createVariable(numDeriv, value, idx); }
316
317template <class Evaluation, class Scalar>
318OPM_HOST_DEVICE Evaluation variable(const Evaluation& x, const Scalar& value, unsigned idx)
319{ return MathToolbox<Evaluation>::createVariable(x, value, idx); }
320
321template <class Evaluation, class Scalar>
322OPM_HOST_DEVICE Evaluation variable(const Scalar& value, unsigned idx)
323{ return MathToolbox<Evaluation>::createVariable(value, idx); }
324
325template <class ResultEval, class Evaluation>
326OPM_HOST_DEVICE auto decay(const Evaluation& value)
327 -> decltype(MathToolbox<Evaluation>::template decay<ResultEval>(value))
328{ return MathToolbox<Evaluation>::template decay<ResultEval>(value); }
329
330template <class Evaluation>
331OPM_HOST_DEVICE auto getValue(const Evaluation& val)
332 -> decltype(MathToolbox<Evaluation>::value(val))
333{ return MathToolbox<Evaluation>::value(val); }
334
335template <class Evaluation>
336OPM_HOST_DEVICE auto scalarValue(const Evaluation& val)
339
340template <class Evaluation1, class Evaluation2>
341typename ReturnEval_<Evaluation1, Evaluation2>::type
342OPM_HOST_DEVICE max(const Evaluation1& arg1, const Evaluation2& arg2)
343{ return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::max(arg1, arg2); }
344
345template <class Evaluation1, class Evaluation2>
346typename ReturnEval_<Evaluation1, Evaluation2>::type
347OPM_HOST_DEVICE min(const Evaluation1& arg1, const Evaluation2& arg2)
348{ return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::min(arg1, arg2); }
349
350template <class Evaluation>
351OPM_HOST_DEVICE Evaluation abs(const Evaluation& value)
352{ return MathToolbox<Evaluation>::abs(value); }
353
354template <class Evaluation>
355OPM_HOST_DEVICE Evaluation tan(const Evaluation& value)
356{ return MathToolbox<Evaluation>::tan(value); }
357
358template <class Evaluation>
359OPM_HOST_DEVICE Evaluation atan(const Evaluation& value)
360{ return MathToolbox<Evaluation>::atan(value); }
361
362template <class Evaluation1, class Evaluation2>
363typename ReturnEval_<Evaluation1, Evaluation2>::type
364OPM_HOST_DEVICE atan2(const Evaluation1& value1, const Evaluation2& value2)
365{ return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::atan2(value1, value2); }
366
367template <class Evaluation>
368OPM_HOST_DEVICE Evaluation sin(const Evaluation& value)
369{ return MathToolbox<Evaluation>::sin(value); }
370
371template <class Evaluation>
372OPM_HOST_DEVICE Evaluation asin(const Evaluation& value)
373{ return MathToolbox<Evaluation>::asin(value); }
374
375template <class Evaluation>
376OPM_HOST_DEVICE Evaluation sinh(const Evaluation& value)
377{ return MathToolbox<Evaluation>::sinh(value); }
378
379template <class Evaluation>
380OPM_HOST_DEVICE Evaluation asinh(const Evaluation& value)
381{ return MathToolbox<Evaluation>::asinh(value); }
382
383template <class Evaluation>
384OPM_HOST_DEVICE Evaluation cos(const Evaluation& value)
385{ return MathToolbox<Evaluation>::cos(value); }
386
387template <class Evaluation>
388OPM_HOST_DEVICE Evaluation acos(const Evaluation& value)
389{ return MathToolbox<Evaluation>::acos(value); }
390
391template <class Evaluation>
392OPM_HOST_DEVICE Evaluation cosh(const Evaluation& value)
393{ return MathToolbox<Evaluation>::cosh(value); }
394
395template <class Evaluation>
396OPM_HOST_DEVICE Evaluation acosh(const Evaluation& value)
397{ return MathToolbox<Evaluation>::acosh(value); }
398
399template <class Evaluation>
400OPM_HOST_DEVICE Evaluation sqrt(const Evaluation& value)
401{ return MathToolbox<Evaluation>::sqrt(value); }
402
403template <class Evaluation>
404OPM_HOST_DEVICE Evaluation exp(const Evaluation& value)
405{ return MathToolbox<Evaluation>::exp(value); }
406
407template <class Evaluation>
408OPM_HOST_DEVICE Evaluation log(const Evaluation& value)
409{ return MathToolbox<Evaluation>::log(value); }
410
411template <class Evaluation>
412OPM_HOST_DEVICE Evaluation log10(const Evaluation& value)
413{ return MathToolbox<Evaluation>::log10(value); }
414
415template <class Evaluation1, class Evaluation2>
416typename ReturnEval_<Evaluation1, Evaluation2>::type
417OPM_HOST_DEVICE pow(const Evaluation1& base, const Evaluation2& exp)
418{ return MathToolbox<typename ReturnEval_<Evaluation1, Evaluation2>::type>::pow(base, exp); }
419
420template <class Evaluation>
421OPM_HOST_DEVICE bool isfinite(const Evaluation& value)
422{ return MathToolbox<Evaluation>::isfinite(value); }
423
424template <class Evaluation>
425OPM_HOST_DEVICE bool isnan(const Evaluation& value)
426{ return MathToolbox<Evaluation>::isnan(value); }
427
428} // namespace Opm
429
430#endif
431
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
Definition MathToolbox.hpp:51
static OPM_HOST_DEVICE Scalar acosh(Scalar arg)
The arcus cosine hyperbolicus of a value.
Definition MathToolbox.hpp:250
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 Scalar sin(Scalar arg)
The sine of a value.
Definition MathToolbox.hpp:222
static OPM_HOST_DEVICE bool isnan(Scalar arg)
Return true iff the argument's value or any of its derivatives are NaN values.
Definition MathToolbox.hpp:278
static OPM_HOST_DEVICE Scalar exp(Scalar arg)
The natural exponentiation of a value.
Definition MathToolbox.hpp:258
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 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
ScalarT Scalar
The type used to represent "primitive" scalar values.
Definition MathToolbox.hpp:58
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 value)
Given a scalar value, return an evaluation of a constant function.
Definition MathToolbox.hpp:112
static OPM_HOST_DEVICE Scalar sqrt(Scalar arg)
The square root of a value.
Definition MathToolbox.hpp:254
static OPM_HOST_DEVICE Scalar atan(Scalar arg)
The arcus tangens of a value.
Definition MathToolbox.hpp:214
static OPM_HOST_DEVICE Scalar value(Scalar value)
Return the value of the function at a given evaluation point.
Definition MathToolbox.hpp:84
static OPM_HOST_DEVICE Scalar asinh(Scalar arg)
The arcus sine hyperbolicus of a value.
Definition MathToolbox.hpp:234
static OPM_HOST_DEVICE bool isfinite(Scalar arg)
Return true iff the argument's value and all its derivatives are finite values.
Definition MathToolbox.hpp:274
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 LhsEval decay(Scalar value)
Given a function evaluation, constrain it to its value (if necessary).
Definition MathToolbox.hpp:174
static OPM_HOST_DEVICE Scalar sinh(Scalar arg)
The sine hyperbolicus of a value.
Definition MathToolbox.hpp:230
static OPM_HOST_DEVICE Scalar min(Scalar arg1, Scalar arg2)
The minimum of two arguments.
Definition MathToolbox.hpp:202
ScalarT ValueType
The type used to represent values.
Definition MathToolbox.hpp:67
static OPM_HOST_DEVICE Scalar cosh(Scalar arg)
The cosine hyperbolicus of a value.
Definition MathToolbox.hpp:246
static OPM_HOST_DEVICE Scalar asin(Scalar arg)
The arcus sine of a value.
Definition MathToolbox.hpp:226
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 pow(Scalar base, Scalar exp)
Exponentiation to an arbitrary base.
Definition MathToolbox.hpp:270
MathToolbox< Scalar > InnerToolbox
The toolbox for the type of value objects.
Definition MathToolbox.hpp:76
static OPM_HOST_DEVICE Scalar cos(Scalar arg)
The cosine of a value.
Definition MathToolbox.hpp:238
static OPM_HOST_DEVICE Scalar log(Scalar arg)
The natural logarithm of a value.
Definition MathToolbox.hpp:266
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 abs(Scalar arg)
The absolute value.
Definition MathToolbox.hpp:206
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 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 acos(Scalar arg)
The arcus cosine of a value.
Definition MathToolbox.hpp:242
static OPM_HOST_DEVICE Scalar log10(Scalar arg)
The 10 logarithm of a value.
Definition MathToolbox.hpp:262
Definition MathToolbox.hpp:284