My Project
Loading...
Searching...
No Matches
Math.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_LOCAL_AD_MATH_HPP
33#define OPM_LOCAL_AD_MATH_HPP
34
35#include "Evaluation.hpp"
36
38
39#include <opm/common/utility/gpuDecorators.hpp>
40namespace Opm {
41namespace DenseAd {
42// forward declaration of the Evaluation template class
43template <class ValueT, int numVars, unsigned staticSize>
44class Evaluation;
45
46// provide some algebraic functions
47template <class ValueType, int numVars, unsigned staticSize>
48OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> abs(const Evaluation<ValueType, numVars, staticSize>& x)
49{ return (x > 0.0)?x:-x; }
50
51template <class ValueType, int numVars, unsigned staticSize>
52OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> min(const Evaluation<ValueType, numVars, staticSize>& x1,
53 const Evaluation<ValueType, numVars, staticSize>& x2)
54{ return (x1 < x2)?x1:x2; }
55
56template <class Arg1ValueType, class ValueType, int numVars, unsigned staticSize>
57OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> min(const Arg1ValueType& x1,
58 const Evaluation<ValueType, numVars, staticSize>& x2)
59{
60 if (x1 < x2) {
61 Evaluation<ValueType, numVars, staticSize> ret(x2);
62 ret = x1;
63 return ret;
64 }
65 else
66 return x2;
67}
68
69template <class ValueType, int numVars, unsigned staticSize, class Arg2ValueType>
70OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> min(const Evaluation<ValueType, numVars, staticSize>& x1,
71 const Arg2ValueType& x2)
72{ return min(x2, x1); }
73
74template <class ValueType, int numVars, unsigned staticSize>
75OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> max(const Evaluation<ValueType, numVars, staticSize>& x1,
76 const Evaluation<ValueType, numVars, staticSize>& x2)
77{ return (x1 > x2)?x1:x2; }
78
79template <class Arg1ValueType, class ValueType, int numVars, unsigned staticSize>
80OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> max(const Arg1ValueType& x1,
81 const Evaluation<ValueType, numVars, staticSize>& x2)
82{
83 if (x1 > x2) {
84 Evaluation<ValueType, numVars, staticSize> ret(x2);
85 ret = x1;
86 return ret;
87 }
88 else
89 return x2;
90}
91
92template <class ValueType, int numVars, unsigned staticSize, class Arg2ValueType>
93OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> max(const Evaluation<ValueType, numVars, staticSize>& x1,
94 const Arg2ValueType& x2)
95{ return max(x2, x1); }
96
97template <class ValueType, int numVars, unsigned staticSize>
98OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> tan(const Evaluation<ValueType, numVars, staticSize>& x)
99{
100 typedef MathToolbox<ValueType> ValueTypeToolbox;
101
102 Evaluation<ValueType, numVars, staticSize> result(x);
103
104 const ValueType& tmp = ValueTypeToolbox::tan(x.value());
105 result.setValue(tmp);
106
107 // derivatives use the chain rule
108 const ValueType& df_dx = 1 + tmp*tmp;
109 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
110 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
111
112 return result;
113}
114
115template <class ValueType, int numVars, unsigned staticSize>
116OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> atan(const Evaluation<ValueType, numVars, staticSize>& x)
117{
118 typedef MathToolbox<ValueType> ValueTypeToolbox;
119
120 Evaluation<ValueType, numVars, staticSize> result(x);
121
122 result.setValue(ValueTypeToolbox::atan(x.value()));
123
124 // derivatives use the chain rule
125 const ValueType& df_dx = 1/(1 + x.value()*x.value());
126 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
127 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
128
129 return result;
130}
131
132template <class ValueType, int numVars, unsigned staticSize>
133OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> atan2(const Evaluation<ValueType, numVars, staticSize>& x,
134 const Evaluation<ValueType, numVars, staticSize>& y)
135{
136 typedef MathToolbox<ValueType> ValueTypeToolbox;
137
138 Evaluation<ValueType, numVars, staticSize> result(x);
139
140 result.setValue(ValueTypeToolbox::atan2(x.value(), y.value()));
141
142 // derivatives use the chain rule
143 const ValueType& alpha = 1/(1 + (x.value()*x.value())/(y.value()*y.value()));
144 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
145 result.setDerivative(curVarIdx,
146 alpha/(y.value()*y.value())
147 *(x.derivative(curVarIdx)*y.value() - x.value()*y.derivative(curVarIdx)));
148 }
149
150 return result;
151}
152
153template <class ValueType, int numVars, unsigned staticSize>
154OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> atan2(const Evaluation<ValueType, numVars, staticSize>& x,
155 const ValueType& y)
156{
157 typedef MathToolbox<ValueType> ValueTypeToolbox;
158
159 Evaluation<ValueType, numVars, staticSize> result(x);
160
161 result.setValue(ValueTypeToolbox::atan2(x.value(), y));
162
163 // derivatives use the chain rule
164 const ValueType& alpha = 1/(1 + (x.value()*x.value())/(y*y));
165 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
166 result.setDerivative(curVarIdx,
167 alpha/(y*y)
168 *(x.derivative(curVarIdx)*y));
169 }
170
171 return result;
172}
173
174template <class ValueType, int numVars, unsigned staticSize>
175OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> atan2(const ValueType& x,
176 const Evaluation<ValueType, numVars, staticSize>& y)
177{
178 typedef MathToolbox<ValueType> ValueTypeToolbox;
179
180 Evaluation<ValueType, numVars, staticSize> result(y);
181
182 result.setValue(ValueTypeToolbox::atan2(x, y.value()));
183
184 // derivatives use the chain rule
185 const ValueType& alpha = 1/(1 + (x.value()*x.value())/(y.value()*y.value()));
186 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
187 result.setDerivative(curVarIdx,
188 alpha/(y.value()*y.value())
189 *x*y.derivative(curVarIdx));
190 }
191
192 return result;
193}
194
195template <class ValueType, int numVars, unsigned staticSize>
196OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> sin(const Evaluation<ValueType, numVars, staticSize>& x)
197{
198 typedef MathToolbox<ValueType> ValueTypeToolbox;
199
200 Evaluation<ValueType, numVars, staticSize> result(x);
201
202 result.setValue(ValueTypeToolbox::sin(x.value()));
203
204 // derivatives use the chain rule
205 const ValueType& df_dx = ValueTypeToolbox::cos(x.value());
206 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
207 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
208
209 return result;
210}
211
212template <class ValueType, int numVars, unsigned staticSize>
213OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> asin(const Evaluation<ValueType, numVars, staticSize>& x)
214{
215 typedef MathToolbox<ValueType> ValueTypeToolbox;
216
217 Evaluation<ValueType, numVars, staticSize> result(x);
218
219 result.setValue(ValueTypeToolbox::asin(x.value()));
220
221 // derivatives use the chain rule
222 const ValueType& df_dx = 1.0/ValueTypeToolbox::sqrt(1 - x.value()*x.value());
223 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
224 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
225
226 return result;
227}
228
229template <class ValueType, int numVars, unsigned staticSize>
230OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> sinh(const Evaluation<ValueType, numVars, staticSize>& x)
231{
232 typedef MathToolbox<ValueType> ValueTypeToolbox;
233
234 Evaluation<ValueType, numVars, staticSize> result(x);
235
236 result.setValue(ValueTypeToolbox::sinh(x.value()));
237
238 // derivatives use the chain rule
239 const ValueType& df_dx = ValueTypeToolbox::cosh(x.value());
240 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
241 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
242
243 return result;
244}
245
246template <class ValueType, int numVars, unsigned staticSize>
247OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> asinh(const Evaluation<ValueType, numVars, staticSize>& x)
248{
249 typedef MathToolbox<ValueType> ValueTypeToolbox;
250
251 Evaluation<ValueType, numVars, staticSize> result(x);
252
253 result.setValue(ValueTypeToolbox::asinh(x.value()));
254
255 // derivatives use the chain rule
256 const ValueType& df_dx = 1.0/ValueTypeToolbox::sqrt(x.value()*x.value() + 1);
257 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
258 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
259
260 return result;
261}
262
263template <class ValueType, int numVars, unsigned staticSize>
264OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> cos(const Evaluation<ValueType, numVars, staticSize>& x)
265{
266 typedef MathToolbox<ValueType> ValueTypeToolbox;
267
268 Evaluation<ValueType, numVars, staticSize> result(x);
269
270 result.setValue(ValueTypeToolbox::cos(x.value()));
271
272 // derivatives use the chain rule
273 const ValueType& df_dx = -ValueTypeToolbox::sin(x.value());
274 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
275 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
276
277 return result;
278}
279
280template <class ValueType, int numVars, unsigned staticSize>
281OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> acos(const Evaluation<ValueType, numVars, staticSize>& x)
282{
283 typedef MathToolbox<ValueType> ValueTypeToolbox;
284
285 Evaluation<ValueType, numVars, staticSize> result(x);
286
287 result.setValue(ValueTypeToolbox::acos(x.value()));
288
289 // derivatives use the chain rule
290 const ValueType& df_dx = - 1.0/ValueTypeToolbox::sqrt(1 - x.value()*x.value());
291 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
292 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
293
294 return result;
295}
296
297template <class ValueType, int numVars, unsigned staticSize>
298OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> cosh(const Evaluation<ValueType, numVars, staticSize>& x)
299{
300 typedef MathToolbox<ValueType> ValueTypeToolbox;
301
302 Evaluation<ValueType, numVars, staticSize> result(x);
303
304 result.setValue(ValueTypeToolbox::cosh(x.value()));
305
306 // derivatives use the chain rule
307 const ValueType& df_dx = ValueTypeToolbox::sinh(x.value());
308 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
309 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
310
311 return result;
312}
313
314template <class ValueType, int numVars, unsigned staticSize>
315OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> acosh(const Evaluation<ValueType, numVars, staticSize>& x)
316{
317 typedef MathToolbox<ValueType> ValueTypeToolbox;
318
319 Evaluation<ValueType, numVars, staticSize> result(x);
320
321 result.setValue(ValueTypeToolbox::acosh(x.value()));
322
323 // derivatives use the chain rule
324 const ValueType& df_dx = 1.0/ValueTypeToolbox::sqrt(x.value()*x.value() - 1);
325 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
326 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
327
328 return result;
329}
330
331template <class ValueType, int numVars, unsigned staticSize>
332OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> sqrt(const Evaluation<ValueType, numVars, staticSize>& x)
333{
334 typedef MathToolbox<ValueType> ValueTypeToolbox;
335
336 Evaluation<ValueType, numVars, staticSize> result(x);
337
338 const ValueType& sqrt_x = ValueTypeToolbox::sqrt(x.value());
339 result.setValue(sqrt_x);
340
341 // derivatives use the chain rule
342 ValueType df_dx = 0.5/sqrt_x;
343 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
344 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
345 }
346
347 return result;
348}
349
350template <class ValueType, int numVars, unsigned staticSize>
351OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> exp(const Evaluation<ValueType, numVars, staticSize>& x)
352{
353 typedef MathToolbox<ValueType> ValueTypeToolbox;
354 Evaluation<ValueType, numVars, staticSize> result(x);
355
356 const ValueType& exp_x = ValueTypeToolbox::exp(x.value());
357 result.setValue(exp_x);
358
359 // derivatives use the chain rule
360 const ValueType& df_dx = exp_x;
361 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
362 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
363
364 return result;
365}
366
367// exponentiation of arbitrary base with a fixed constant
368template <class ValueType, int numVars, unsigned staticSize, class ExpType>
369OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> pow(const Evaluation<ValueType, numVars, staticSize>& base,
370 const ExpType& exp)
371{
372 typedef MathToolbox<ValueType> ValueTypeToolbox;
373 Evaluation<ValueType, numVars, staticSize> result(base);
374
375 const ValueType& pow_x = ValueTypeToolbox::pow(base.value(), exp);
376 result.setValue(pow_x);
377
378 if (base == 0.0) {
379 // we special case the base 0 case because 0.0 is in the valid range of the
380 // base but the generic code leads to NaNs.
381 result = 0.0;
382 }
383 else {
384 // derivatives use the chain rule
385 const ValueType& df_dx = pow_x/base.value()*exp;
386 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
387 result.setDerivative(curVarIdx, df_dx*base.derivative(curVarIdx));
388 }
389
390 return result;
391}
392
393// exponentiation of constant base with an arbitrary exponent
394template <class BaseType, class ValueType, int numVars, unsigned staticSize>
395OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> pow(const BaseType& base,
396 const Evaluation<ValueType, numVars, staticSize>& exp)
397{
398 typedef MathToolbox<ValueType> ValueTypeToolbox;
399
400 Evaluation<ValueType, numVars, staticSize> result(exp);
401
402 if (base == 0.0) {
403 // we special case the base 0 case because 0.0 is in the valid range of the
404 // base but the generic code leads to NaNs.
405 result = 0.0;
406 }
407 else {
408 const ValueType& lnBase = ValueTypeToolbox::log(base);
409 result.setValue(ValueTypeToolbox::exp(lnBase*exp.value()));
410
411 // derivatives use the chain rule
412 const ValueType& df_dx = lnBase*result.value();
413 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
414 result.setDerivative(curVarIdx, df_dx*exp.derivative(curVarIdx));
415 }
416
417 return result;
418}
419
420// this is the most expensive power function. Computationally it is pretty expensive, so
421// one of the above two variants above should be preferred if possible.
422template <class ValueType, int numVars, unsigned staticSize>
423OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> pow(const Evaluation<ValueType, numVars, staticSize>& base,
424 const Evaluation<ValueType, numVars, staticSize>& exp)
425{
426 typedef MathToolbox<ValueType> ValueTypeToolbox;
427
428 Evaluation<ValueType, numVars, staticSize> result(base);
429
430 if (base == 0.0) {
431 // we special case the base 0 case because 0.0 is in the valid range of the
432 // base but the generic code leads to NaNs.
433 result = 0.0;
434 }
435 else {
436 ValueType valuePow = ValueTypeToolbox::pow(base.value(), exp.value());
437 result.setValue(valuePow);
438
439 // use the chain rule for the derivatives. since both, the base and the exponent can
440 // potentially depend on the variable set, calculating these is quite elaborate...
441 const ValueType& f = base.value();
442 const ValueType& g = exp.value();
443 const ValueType& logF = ValueTypeToolbox::log(f);
444 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
445 const ValueType& fPrime = base.derivative(curVarIdx);
446 const ValueType& gPrime = exp.derivative(curVarIdx);
447 result.setDerivative(curVarIdx, (g*fPrime/f + logF*gPrime) * valuePow);
448 }
449 }
450
451 return result;
452}
453
454template <class ValueType, int numVars, unsigned staticSize>
455OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> log(const Evaluation<ValueType, numVars, staticSize>& x)
456{
457 typedef MathToolbox<ValueType> ValueTypeToolbox;
458
459 Evaluation<ValueType, numVars, staticSize> result(x);
460
461 result.setValue(ValueTypeToolbox::log(x.value()));
462
463 // derivatives use the chain rule
464 const ValueType& df_dx = 1/x.value();
465 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
466 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
467
468 return result;
469}
470
471
472template <class ValueType, int numVars, unsigned staticSize>
473OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> log10(const Evaluation<ValueType, numVars, staticSize>& x)
474{
475 typedef MathToolbox<ValueType> ValueTypeToolbox;
476
477 Evaluation<ValueType, numVars, staticSize> result(x);
478
479 result.setValue(ValueTypeToolbox::log10(x.value()));
480
481 // derivatives use the chain rule
482 const ValueType& df_dx = 1/x.value() * ValueTypeToolbox::log10(ValueTypeToolbox::exp(1.0));
483 for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
484 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
485
486 return result;
487}
488
489} // namespace DenseAd
490
491// a kind of traits class for the automatic differentiation case. (The toolbox for the
492// scalar case is provided by the MathToolbox.hpp header file.)
493template <class ValueT, int numVars, unsigned staticSize>
494struct MathToolbox<DenseAd::Evaluation<ValueT, numVars, staticSize> >
495{
496private:
497public:
498 typedef ValueT ValueType;
500 typedef typename InnerToolbox::Scalar Scalar;
502
503 OPM_HOST_DEVICE static ValueType value(const Evaluation& eval)
504 { return eval.value(); }
505
506 OPM_HOST_DEVICE static decltype(InnerToolbox::scalarValue(0.0)) scalarValue(const Evaluation& eval)
507 { return InnerToolbox::scalarValue(eval.value()); }
508
509 OPM_HOST_DEVICE static Evaluation createBlank(const Evaluation& x)
510 { return Evaluation::createBlank(x); }
511
512 OPM_HOST_DEVICE static Evaluation createConstantZero(const Evaluation& x)
513 { return Evaluation::createConstantZero(x); }
514
515 OPM_HOST_DEVICE static Evaluation createConstantOne(const Evaluation& x)
516 { return Evaluation::createConstantOne(x); }
517
518 OPM_HOST_DEVICE static Evaluation createConstant(ValueType value)
519 { return Evaluation::createConstant(value); }
520
521 OPM_HOST_DEVICE static Evaluation createConstant(unsigned numDeriv, const ValueType value)
522 { return Evaluation::createConstant(numDeriv, value); }
523
524 OPM_HOST_DEVICE static Evaluation createConstant(const Evaluation& x, const ValueType value)
525 { return Evaluation::createConstant(x, value); }
526
527 OPM_HOST_DEVICE static Evaluation createVariable(ValueType value, int varIdx)
528 { return Evaluation::createVariable(value, varIdx); }
529
530 template <class LhsEval>
531 OPM_HOST_DEVICE static typename std::enable_if<std::is_same<Evaluation, LhsEval>::value,
532 LhsEval>::type
533 decay(const Evaluation& eval)
534 { return eval; }
535
536 template <class LhsEval>
537 OPM_HOST_DEVICE static typename std::enable_if<std::is_same<Evaluation, LhsEval>::value,
538 LhsEval>::type
539 decay(const Evaluation&& eval)
540 { return eval; }
541
542 template <class LhsEval>
543 OPM_HOST_DEVICE static typename std::enable_if<std::is_floating_point<LhsEval>::value,
544 LhsEval>::type
545 decay(const Evaluation& eval)
546 { return eval.value(); }
547
548 // comparison
549 OPM_HOST_DEVICE static bool isSame(const Evaluation& a, const Evaluation& b, Scalar tolerance)
550 {
551 typedef MathToolbox<ValueType> ValueTypeToolbox;
552
553 // make sure that the value of the evaluation is identical
554 if (!ValueTypeToolbox::isSame(a.value(), b.value(), tolerance))
555 return false;
556
557 // make sure that the derivatives are identical
558 for (int curVarIdx = 0; curVarIdx < numVars; ++curVarIdx)
559 if (!ValueTypeToolbox::isSame(a.derivative(curVarIdx), b.derivative(curVarIdx), tolerance))
560 return false;
561
562 return true;
563 }
564
565 // arithmetic functions
566 template <class Arg1Eval, class Arg2Eval>
567 OPM_HOST_DEVICE static Evaluation max(const Arg1Eval& arg1, const Arg2Eval& arg2)
568 { return DenseAd::max(arg1, arg2); }
569
570 template <class Arg1Eval, class Arg2Eval>
571 OPM_HOST_DEVICE static Evaluation min(const Arg1Eval& arg1, const Arg2Eval& arg2)
572 { return DenseAd::min(arg1, arg2); }
573
574 OPM_HOST_DEVICE static Evaluation abs(const Evaluation& arg)
575 { return DenseAd::abs(arg); }
576
577 OPM_HOST_DEVICE static Evaluation tan(const Evaluation& arg)
578 { return DenseAd::tan(arg); }
579
580 OPM_HOST_DEVICE static Evaluation atan(const Evaluation& arg)
581 { return DenseAd::atan(arg); }
582
583 OPM_HOST_DEVICE static Evaluation atan2(const Evaluation& arg1, const Evaluation& arg2)
584 { return DenseAd::atan2(arg1, arg2); }
585
586 template <class Eval2>
587 OPM_HOST_DEVICE static Evaluation atan2(const Evaluation& arg1, const Eval2& arg2)
588 { return DenseAd::atan2(arg1, arg2); }
589
590 template <class Eval1>
591 OPM_HOST_DEVICE static Evaluation atan2(const Eval1& arg1, const Evaluation& arg2)
592 { return DenseAd::atan2(arg1, arg2); }
593
594 OPM_HOST_DEVICE static Evaluation sin(const Evaluation& arg)
595 { return DenseAd::sin(arg); }
596
597 OPM_HOST_DEVICE static Evaluation asin(const Evaluation& arg)
598 { return DenseAd::asin(arg); }
599
600 OPM_HOST_DEVICE static Evaluation cos(const Evaluation& arg)
601 { return DenseAd::cos(arg); }
602
603 OPM_HOST_DEVICE static Evaluation acos(const Evaluation& arg)
604 { return DenseAd::acos(arg); }
605
606 OPM_HOST_DEVICE static Evaluation sqrt(const Evaluation& arg)
607 { return DenseAd::sqrt(arg); }
608
609 OPM_HOST_DEVICE static Evaluation exp(const Evaluation& arg)
610 { return DenseAd::exp(arg); }
611
612 OPM_HOST_DEVICE static Evaluation log(const Evaluation& arg)
613 { return DenseAd::log(arg); }
614
615 OPM_HOST_DEVICE static Evaluation log10(const Evaluation& arg)
616 { return DenseAd::log10(arg); }
617
618 template <class RhsValueType>
619 OPM_HOST_DEVICE static Evaluation pow(const Evaluation& arg1, const RhsValueType& arg2)
620 { return DenseAd::pow(arg1, arg2); }
621
622 template <class RhsValueType>
623 OPM_HOST_DEVICE static Evaluation pow(const RhsValueType& arg1, const Evaluation& arg2)
624 { return DenseAd::pow(arg1, arg2); }
625
626 OPM_HOST_DEVICE static Evaluation pow(const Evaluation& arg1, const Evaluation& arg2)
627 { return DenseAd::pow(arg1, arg2); }
628
629 OPM_HOST_DEVICE static bool isfinite(const Evaluation& arg)
630 {
631 if (!InnerToolbox::isfinite(arg.value()))
632 return false;
633
634 for (int i = 0; i < numVars; ++i)
635 if (!InnerToolbox::isfinite(arg.derivative(i)))
636 return false;
637
638 return true;
639 }
640
641 OPM_HOST_DEVICE static bool isnan(const Evaluation& arg)
642 {
643 if (InnerToolbox::isnan(arg.value()))
644 return true;
645
646 for (int i = 0; i < numVars; ++i)
647 if (InnerToolbox::isnan(arg.derivative(i)))
648 return true;
649
650 return false;
651 }
652};
653
654}
655
656#endif
Representation of an evaluation of a function and its derivatives w.r.t.
A traits class which provides basic mathematical functions for arbitrary scalar floating point values...
Represents a function evaluation and its derivatives w.r.t.
Definition Evaluation.hpp:59
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 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
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 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 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 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 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