32#ifndef OPM_LOCAL_AD_MATH_HPP
33#define OPM_LOCAL_AD_MATH_HPP
39#include <opm/common/utility/gpuDecorators.hpp>
43template <
class ValueT,
int numVars,
unsigned staticSize>
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; }
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; }
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)
61 Evaluation<ValueType, numVars, staticSize> ret(x2);
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); }
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; }
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)
84 Evaluation<ValueType, numVars, staticSize> ret(x2);
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); }
97template <
class ValueType,
int numVars,
unsigned staticSize>
98OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> tan(
const Evaluation<ValueType, numVars, staticSize>& x)
100 typedef MathToolbox<ValueType> ValueTypeToolbox;
102 Evaluation<ValueType, numVars, staticSize> result(x);
104 const ValueType& tmp = ValueTypeToolbox::tan(x.value());
105 result.setValue(tmp);
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));
115template <
class ValueType,
int numVars,
unsigned staticSize>
116OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> atan(
const Evaluation<ValueType, numVars, staticSize>& x)
118 typedef MathToolbox<ValueType> ValueTypeToolbox;
120 Evaluation<ValueType, numVars, staticSize> result(x);
122 result.setValue(ValueTypeToolbox::atan(x.value()));
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));
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)
136 typedef MathToolbox<ValueType> ValueTypeToolbox;
138 Evaluation<ValueType, numVars, staticSize> result(x);
140 result.setValue(ValueTypeToolbox::atan2(x.value(), y.value()));
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)));
153template <
class ValueType,
int numVars,
unsigned staticSize>
154OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> atan2(
const Evaluation<ValueType, numVars, staticSize>& x,
157 typedef MathToolbox<ValueType> ValueTypeToolbox;
159 Evaluation<ValueType, numVars, staticSize> result(x);
161 result.setValue(ValueTypeToolbox::atan2(x.value(), y));
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,
168 *(x.derivative(curVarIdx)*y));
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)
178 typedef MathToolbox<ValueType> ValueTypeToolbox;
180 Evaluation<ValueType, numVars, staticSize> result(y);
182 result.setValue(ValueTypeToolbox::atan2(x, y.value()));
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));
195template <
class ValueType,
int numVars,
unsigned staticSize>
196OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> sin(
const Evaluation<ValueType, numVars, staticSize>& x)
198 typedef MathToolbox<ValueType> ValueTypeToolbox;
200 Evaluation<ValueType, numVars, staticSize> result(x);
202 result.setValue(ValueTypeToolbox::sin(x.value()));
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));
212template <
class ValueType,
int numVars,
unsigned staticSize>
213OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> asin(
const Evaluation<ValueType, numVars, staticSize>& x)
215 typedef MathToolbox<ValueType> ValueTypeToolbox;
217 Evaluation<ValueType, numVars, staticSize> result(x);
219 result.setValue(ValueTypeToolbox::asin(x.value()));
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));
229template <
class ValueType,
int numVars,
unsigned staticSize>
230OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> sinh(
const Evaluation<ValueType, numVars, staticSize>& x)
232 typedef MathToolbox<ValueType> ValueTypeToolbox;
234 Evaluation<ValueType, numVars, staticSize> result(x);
236 result.setValue(ValueTypeToolbox::sinh(x.value()));
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));
246template <
class ValueType,
int numVars,
unsigned staticSize>
247OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> asinh(
const Evaluation<ValueType, numVars, staticSize>& x)
249 typedef MathToolbox<ValueType> ValueTypeToolbox;
251 Evaluation<ValueType, numVars, staticSize> result(x);
253 result.setValue(ValueTypeToolbox::asinh(x.value()));
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));
263template <
class ValueType,
int numVars,
unsigned staticSize>
264OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> cos(
const Evaluation<ValueType, numVars, staticSize>& x)
266 typedef MathToolbox<ValueType> ValueTypeToolbox;
268 Evaluation<ValueType, numVars, staticSize> result(x);
270 result.setValue(ValueTypeToolbox::cos(x.value()));
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));
280template <
class ValueType,
int numVars,
unsigned staticSize>
281OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> acos(
const Evaluation<ValueType, numVars, staticSize>& x)
283 typedef MathToolbox<ValueType> ValueTypeToolbox;
285 Evaluation<ValueType, numVars, staticSize> result(x);
287 result.setValue(ValueTypeToolbox::acos(x.value()));
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));
297template <
class ValueType,
int numVars,
unsigned staticSize>
298OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> cosh(
const Evaluation<ValueType, numVars, staticSize>& x)
300 typedef MathToolbox<ValueType> ValueTypeToolbox;
302 Evaluation<ValueType, numVars, staticSize> result(x);
304 result.setValue(ValueTypeToolbox::cosh(x.value()));
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));
314template <
class ValueType,
int numVars,
unsigned staticSize>
315OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> acosh(
const Evaluation<ValueType, numVars, staticSize>& x)
317 typedef MathToolbox<ValueType> ValueTypeToolbox;
319 Evaluation<ValueType, numVars, staticSize> result(x);
321 result.setValue(ValueTypeToolbox::acosh(x.value()));
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));
331template <
class ValueType,
int numVars,
unsigned staticSize>
332OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> sqrt(
const Evaluation<ValueType, numVars, staticSize>& x)
334 typedef MathToolbox<ValueType> ValueTypeToolbox;
336 Evaluation<ValueType, numVars, staticSize> result(x);
338 const ValueType& sqrt_x = ValueTypeToolbox::sqrt(x.value());
339 result.setValue(sqrt_x);
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));
350template <
class ValueType,
int numVars,
unsigned staticSize>
351OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> exp(
const Evaluation<ValueType, numVars, staticSize>& x)
353 typedef MathToolbox<ValueType> ValueTypeToolbox;
354 Evaluation<ValueType, numVars, staticSize> result(x);
356 const ValueType& exp_x = ValueTypeToolbox::exp(x.value());
357 result.setValue(exp_x);
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));
368template <
class ValueType,
int numVars,
unsigned staticSize,
class ExpType>
369OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> pow(
const Evaluation<ValueType, numVars, staticSize>& base,
372 typedef MathToolbox<ValueType> ValueTypeToolbox;
373 Evaluation<ValueType, numVars, staticSize> result(base);
375 const ValueType& pow_x = ValueTypeToolbox::pow(base.value(), exp);
376 result.setValue(pow_x);
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));
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)
398 typedef MathToolbox<ValueType> ValueTypeToolbox;
400 Evaluation<ValueType, numVars, staticSize> result(exp);
408 const ValueType& lnBase = ValueTypeToolbox::log(base);
409 result.setValue(ValueTypeToolbox::exp(lnBase*exp.value()));
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));
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)
426 typedef MathToolbox<ValueType> ValueTypeToolbox;
428 Evaluation<ValueType, numVars, staticSize> result(base);
436 ValueType valuePow = ValueTypeToolbox::pow(base.value(), exp.value());
437 result.setValue(valuePow);
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);
454template <
class ValueType,
int numVars,
unsigned staticSize>
455OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> log(
const Evaluation<ValueType, numVars, staticSize>& x)
457 typedef MathToolbox<ValueType> ValueTypeToolbox;
459 Evaluation<ValueType, numVars, staticSize> result(x);
461 result.setValue(ValueTypeToolbox::log(x.value()));
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));
472template <
class ValueType,
int numVars,
unsigned staticSize>
473OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> log10(
const Evaluation<ValueType, numVars, staticSize>& x)
475 typedef MathToolbox<ValueType> ValueTypeToolbox;
477 Evaluation<ValueType, numVars, staticSize> result(x);
479 result.setValue(ValueTypeToolbox::log10(x.value()));
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));
493template <
class ValueT,
int numVars,
unsigned staticSize>
503 OPM_HOST_DEVICE
static ValueType value(
const Evaluation& eval)
504 {
return eval.value(); }
510 {
return Evaluation::createBlank(x); }
513 {
return Evaluation::createConstantZero(x); }
516 {
return Evaluation::createConstantOne(x); }
519 {
return Evaluation::createConstant(value); }
522 {
return Evaluation::createConstant(numDeriv, value); }
525 {
return Evaluation::createConstant(x, value); }
528 {
return Evaluation::createVariable(value, varIdx); }
530 template <
class LhsEval>
531 OPM_HOST_DEVICE
static typename std::enable_if<std::is_same<Evaluation, LhsEval>::value,
536 template <
class LhsEval>
537 OPM_HOST_DEVICE
static typename std::enable_if<std::is_same<Evaluation, LhsEval>::value,
542 template <
class LhsEval>
543 OPM_HOST_DEVICE
static typename std::enable_if<std::is_floating_point<LhsEval>::value,
546 {
return eval.value(); }
554 if (!ValueTypeToolbox::isSame(a.value(), b.value(), tolerance))
558 for (
int curVarIdx = 0; curVarIdx < numVars; ++curVarIdx)
559 if (!ValueTypeToolbox::isSame(a.derivative(curVarIdx), b.derivative(curVarIdx), tolerance))
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); }
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); }
575 {
return DenseAd::abs(arg); }
578 {
return DenseAd::tan(arg); }
581 {
return DenseAd::atan(arg); }
584 {
return DenseAd::atan2(arg1, arg2); }
586 template <
class Eval2>
588 {
return DenseAd::atan2(arg1, arg2); }
590 template <
class Eval1>
592 {
return DenseAd::atan2(arg1, arg2); }
595 {
return DenseAd::sin(arg); }
598 {
return DenseAd::asin(arg); }
601 {
return DenseAd::cos(arg); }
604 {
return DenseAd::acos(arg); }
607 {
return DenseAd::sqrt(arg); }
610 {
return DenseAd::exp(arg); }
613 {
return DenseAd::log(arg); }
616 {
return DenseAd::log10(arg); }
618 template <
class RhsValueType>
620 {
return DenseAd::pow(arg1, arg2); }
622 template <
class RhsValueType>
624 {
return DenseAd::pow(arg1, arg2); }
627 {
return DenseAd::pow(arg1, arg2); }
634 for (
int i = 0; i < numVars; ++i)
646 for (
int i = 0; i < numVars; ++i)
Representation of an evaluation of a function and its derivatives w.r.t.
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