32#ifndef OPM_LOCAL_AD_MATH_HPP
33#define OPM_LOCAL_AD_MATH_HPP
42template <
class ValueT,
int numVars,
unsigned staticSize>
46template <
class ValueType,
int numVars,
unsigned staticSize>
47Evaluation<ValueType, numVars, staticSize> abs(
const Evaluation<ValueType, numVars, staticSize>& x)
48{
return (x > 0.0)?x:-x; }
50template <
class ValueType,
int numVars,
unsigned staticSize>
51Evaluation<ValueType, numVars, staticSize> min(
const Evaluation<ValueType, numVars, staticSize>& x1,
52 const Evaluation<ValueType, numVars, staticSize>& x2)
53{
return (x1 < x2)?x1:x2; }
55template <
class Arg1ValueType,
class ValueType,
int numVars,
unsigned staticSize>
56Evaluation<ValueType, numVars, staticSize> min(
const Arg1ValueType& x1,
57 const Evaluation<ValueType, numVars, staticSize>& x2)
60 Evaluation<ValueType, numVars, staticSize> ret(x2);
68template <
class ValueType,
int numVars,
unsigned staticSize,
class Arg2ValueType>
69Evaluation<ValueType, numVars, staticSize> min(
const Evaluation<ValueType, numVars, staticSize>& x1,
70 const Arg2ValueType& x2)
71{
return min(x2, x1); }
73template <
class ValueType,
int numVars,
unsigned staticSize>
74Evaluation<ValueType, numVars, staticSize> max(
const Evaluation<ValueType, numVars, staticSize>& x1,
75 const Evaluation<ValueType, numVars, staticSize>& x2)
76{
return (x1 > x2)?x1:x2; }
78template <
class Arg1ValueType,
class ValueType,
int numVars,
unsigned staticSize>
79Evaluation<ValueType, numVars, staticSize> max(
const Arg1ValueType& x1,
80 const Evaluation<ValueType, numVars, staticSize>& x2)
83 Evaluation<ValueType, numVars, staticSize> ret(x2);
91template <
class ValueType,
int numVars,
unsigned staticSize,
class Arg2ValueType>
92Evaluation<ValueType, numVars, staticSize> max(
const Evaluation<ValueType, numVars, staticSize>& x1,
93 const Arg2ValueType& x2)
94{
return max(x2, x1); }
96template <
class ValueType,
int numVars,
unsigned staticSize>
97Evaluation<ValueType, numVars, staticSize> tan(
const Evaluation<ValueType, numVars, staticSize>& x)
99 typedef MathToolbox<ValueType> ValueTypeToolbox;
101 Evaluation<ValueType, numVars, staticSize> result(x);
103 const ValueType& tmp = ValueTypeToolbox::tan(x.value());
104 result.setValue(tmp);
107 const ValueType& df_dx = 1 + tmp*tmp;
108 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
109 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
114template <
class ValueType,
int numVars,
unsigned staticSize>
115Evaluation<ValueType, numVars, staticSize> atan(
const Evaluation<ValueType, numVars, staticSize>& x)
117 typedef MathToolbox<ValueType> ValueTypeToolbox;
119 Evaluation<ValueType, numVars, staticSize> result(x);
121 result.setValue(ValueTypeToolbox::atan(x.value()));
124 const ValueType& df_dx = 1/(1 + x.value()*x.value());
125 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
126 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
131template <
class ValueType,
int numVars,
unsigned staticSize>
132Evaluation<ValueType, numVars, staticSize> atan2(
const Evaluation<ValueType, numVars, staticSize>& x,
133 const Evaluation<ValueType, numVars, staticSize>& y)
135 typedef MathToolbox<ValueType> ValueTypeToolbox;
137 Evaluation<ValueType, numVars, staticSize> result(x);
139 result.setValue(ValueTypeToolbox::atan2(x.value(), y.value()));
142 const ValueType& alpha = 1/(1 + (x.value()*x.value())/(y.value()*y.value()));
143 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
144 result.setDerivative(curVarIdx,
145 alpha/(y.value()*y.value())
146 *(x.derivative(curVarIdx)*y.value() - x.value()*y.derivative(curVarIdx)));
152template <
class ValueType,
int numVars,
unsigned staticSize>
153Evaluation<ValueType, numVars, staticSize> atan2(
const Evaluation<ValueType, numVars, staticSize>& x,
156 typedef MathToolbox<ValueType> ValueTypeToolbox;
158 Evaluation<ValueType, numVars, staticSize> result(x);
160 result.setValue(ValueTypeToolbox::atan2(x.value(), y));
163 const ValueType& alpha = 1/(1 + (x.value()*x.value())/(y*y));
164 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
165 result.setDerivative(curVarIdx,
167 *(x.derivative(curVarIdx)*y));
173template <
class ValueType,
int numVars,
unsigned staticSize>
174Evaluation<ValueType, numVars, staticSize> atan2(
const ValueType& x,
175 const Evaluation<ValueType, numVars, staticSize>& y)
177 typedef MathToolbox<ValueType> ValueTypeToolbox;
179 Evaluation<ValueType, numVars, staticSize> result(y);
181 result.setValue(ValueTypeToolbox::atan2(x, y.value()));
184 const ValueType& alpha = 1/(1 + (x.value()*x.value())/(y.value()*y.value()));
185 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
186 result.setDerivative(curVarIdx,
187 alpha/(y.value()*y.value())
188 *x*y.derivative(curVarIdx));
194template <
class ValueType,
int numVars,
unsigned staticSize>
195Evaluation<ValueType, numVars, staticSize> sin(
const Evaluation<ValueType, numVars, staticSize>& x)
197 typedef MathToolbox<ValueType> ValueTypeToolbox;
199 Evaluation<ValueType, numVars, staticSize> result(x);
201 result.setValue(ValueTypeToolbox::sin(x.value()));
204 const ValueType& df_dx = ValueTypeToolbox::cos(x.value());
205 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
206 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
211template <
class ValueType,
int numVars,
unsigned staticSize>
212Evaluation<ValueType, numVars, staticSize> asin(
const Evaluation<ValueType, numVars, staticSize>& x)
214 typedef MathToolbox<ValueType> ValueTypeToolbox;
216 Evaluation<ValueType, numVars, staticSize> result(x);
218 result.setValue(ValueTypeToolbox::asin(x.value()));
221 const ValueType& df_dx = 1.0/ValueTypeToolbox::sqrt(1 - x.value()*x.value());
222 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
223 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
228template <
class ValueType,
int numVars,
unsigned staticSize>
229Evaluation<ValueType, numVars, staticSize> sinh(
const Evaluation<ValueType, numVars, staticSize>& x)
231 typedef MathToolbox<ValueType> ValueTypeToolbox;
233 Evaluation<ValueType, numVars, staticSize> result(x);
235 result.setValue(ValueTypeToolbox::sinh(x.value()));
238 const ValueType& df_dx = ValueTypeToolbox::cosh(x.value());
239 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
240 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
245template <
class ValueType,
int numVars,
unsigned staticSize>
246Evaluation<ValueType, numVars, staticSize> asinh(
const Evaluation<ValueType, numVars, staticSize>& x)
248 typedef MathToolbox<ValueType> ValueTypeToolbox;
250 Evaluation<ValueType, numVars, staticSize> result(x);
252 result.setValue(ValueTypeToolbox::asinh(x.value()));
255 const ValueType& df_dx = 1.0/ValueTypeToolbox::sqrt(x.value()*x.value() + 1);
256 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
257 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
262template <
class ValueType,
int numVars,
unsigned staticSize>
263Evaluation<ValueType, numVars, staticSize> cos(
const Evaluation<ValueType, numVars, staticSize>& x)
265 typedef MathToolbox<ValueType> ValueTypeToolbox;
267 Evaluation<ValueType, numVars, staticSize> result(x);
269 result.setValue(ValueTypeToolbox::cos(x.value()));
272 const ValueType& df_dx = -ValueTypeToolbox::sin(x.value());
273 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
274 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
279template <
class ValueType,
int numVars,
unsigned staticSize>
280Evaluation<ValueType, numVars, staticSize> acos(
const Evaluation<ValueType, numVars, staticSize>& x)
282 typedef MathToolbox<ValueType> ValueTypeToolbox;
284 Evaluation<ValueType, numVars, staticSize> result(x);
286 result.setValue(ValueTypeToolbox::acos(x.value()));
289 const ValueType& df_dx = - 1.0/ValueTypeToolbox::sqrt(1 - x.value()*x.value());
290 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
291 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
296template <
class ValueType,
int numVars,
unsigned staticSize>
297Evaluation<ValueType, numVars, staticSize> cosh(
const Evaluation<ValueType, numVars, staticSize>& x)
299 typedef MathToolbox<ValueType> ValueTypeToolbox;
301 Evaluation<ValueType, numVars, staticSize> result(x);
303 result.setValue(ValueTypeToolbox::cosh(x.value()));
306 const ValueType& df_dx = ValueTypeToolbox::sinh(x.value());
307 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
308 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
313template <
class ValueType,
int numVars,
unsigned staticSize>
314Evaluation<ValueType, numVars, staticSize> acosh(
const Evaluation<ValueType, numVars, staticSize>& x)
316 typedef MathToolbox<ValueType> ValueTypeToolbox;
318 Evaluation<ValueType, numVars, staticSize> result(x);
320 result.setValue(ValueTypeToolbox::acosh(x.value()));
323 const ValueType& df_dx = 1.0/ValueTypeToolbox::sqrt(x.value()*x.value() - 1);
324 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
325 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
330template <
class ValueType,
int numVars,
unsigned staticSize>
331Evaluation<ValueType, numVars, staticSize> sqrt(
const Evaluation<ValueType, numVars, staticSize>& x)
333 typedef MathToolbox<ValueType> ValueTypeToolbox;
335 Evaluation<ValueType, numVars, staticSize> result(x);
337 const ValueType& sqrt_x = ValueTypeToolbox::sqrt(x.value());
338 result.setValue(sqrt_x);
341 ValueType df_dx = 0.5/sqrt_x;
342 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
343 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
349template <
class ValueType,
int numVars,
unsigned staticSize>
350Evaluation<ValueType, numVars, staticSize> exp(
const Evaluation<ValueType, numVars, staticSize>& x)
352 typedef MathToolbox<ValueType> ValueTypeToolbox;
353 Evaluation<ValueType, numVars, staticSize> result(x);
355 const ValueType& exp_x = ValueTypeToolbox::exp(x.value());
356 result.setValue(exp_x);
359 const ValueType& df_dx = exp_x;
360 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
361 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
367template <
class ValueType,
int numVars,
unsigned staticSize,
class ExpType>
368Evaluation<ValueType, numVars, staticSize> pow(
const Evaluation<ValueType, numVars, staticSize>& base,
371 typedef MathToolbox<ValueType> ValueTypeToolbox;
372 Evaluation<ValueType, numVars, staticSize> result(base);
374 const ValueType& pow_x = ValueTypeToolbox::pow(base.value(), exp);
375 result.setValue(pow_x);
384 const ValueType& df_dx = pow_x/base.value()*exp;
385 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
386 result.setDerivative(curVarIdx, df_dx*base.derivative(curVarIdx));
393template <
class BaseType,
class ValueType,
int numVars,
unsigned staticSize>
394Evaluation<ValueType, numVars, staticSize> pow(
const BaseType& base,
395 const Evaluation<ValueType, numVars, staticSize>& exp)
397 typedef MathToolbox<ValueType> ValueTypeToolbox;
399 Evaluation<ValueType, numVars, staticSize> result(exp);
407 const ValueType& lnBase = ValueTypeToolbox::log(base);
408 result.setValue(ValueTypeToolbox::exp(lnBase*exp.value()));
411 const ValueType& df_dx = lnBase*result.value();
412 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
413 result.setDerivative(curVarIdx, df_dx*exp.derivative(curVarIdx));
421template <
class ValueType,
int numVars,
unsigned staticSize>
422Evaluation<ValueType, numVars, staticSize> pow(
const Evaluation<ValueType, numVars, staticSize>& base,
423 const Evaluation<ValueType, numVars, staticSize>& exp)
425 typedef MathToolbox<ValueType> ValueTypeToolbox;
427 Evaluation<ValueType, numVars, staticSize> result(base);
435 ValueType valuePow = ValueTypeToolbox::pow(base.value(), exp.value());
436 result.setValue(valuePow);
440 const ValueType& f = base.value();
441 const ValueType& g = exp.value();
442 const ValueType& logF = ValueTypeToolbox::log(f);
443 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
444 const ValueType& fPrime = base.derivative(curVarIdx);
445 const ValueType& gPrime = exp.derivative(curVarIdx);
446 result.setDerivative(curVarIdx, (g*fPrime/f + logF*gPrime) * valuePow);
453template <
class ValueType,
int numVars,
unsigned staticSize>
454Evaluation<ValueType, numVars, staticSize> log(
const Evaluation<ValueType, numVars, staticSize>& x)
456 typedef MathToolbox<ValueType> ValueTypeToolbox;
458 Evaluation<ValueType, numVars, staticSize> result(x);
460 result.setValue(ValueTypeToolbox::log(x.value()));
463 const ValueType& df_dx = 1/x.value();
464 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
465 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
471template <
class ValueType,
int numVars,
unsigned staticSize>
472Evaluation<ValueType, numVars, staticSize> log10(
const Evaluation<ValueType, numVars, staticSize>& x)
474 typedef MathToolbox<ValueType> ValueTypeToolbox;
476 Evaluation<ValueType, numVars, staticSize> result(x);
478 result.setValue(ValueTypeToolbox::log10(x.value()));
481 const ValueType& df_dx = 1/x.value() * ValueTypeToolbox::log10(ValueTypeToolbox::exp(1.0));
482 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
483 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
492template <
class ValueT,
int numVars,
unsigned staticSize>
502 static ValueType value(
const Evaluation& eval)
503 {
return eval.value(); }
509 {
return Evaluation::createBlank(x); }
512 {
return Evaluation::createConstantZero(x); }
515 {
return Evaluation::createConstantOne(x); }
518 {
return Evaluation::createConstant(value); }
521 {
return Evaluation::createConstant(numDeriv, value); }
524 {
return Evaluation::createConstant(x, value); }
527 {
return Evaluation::createVariable(value, varIdx); }
529 template <
class LhsEval>
530 static typename std::enable_if<std::is_same<Evaluation, LhsEval>::value,
535 template <
class LhsEval>
536 static typename std::enable_if<std::is_same<Evaluation, LhsEval>::value,
541 template <
class LhsEval>
542 static typename std::enable_if<std::is_floating_point<LhsEval>::value,
545 {
return eval.value(); }
553 if (!ValueTypeToolbox::isSame(a.value(), b.value(), tolerance))
557 for (
int curVarIdx = 0; curVarIdx < numVars; ++curVarIdx)
558 if (!ValueTypeToolbox::isSame(a.derivative(curVarIdx), b.derivative(curVarIdx), tolerance))
565 template <
class Arg1Eval,
class Arg2Eval>
566 static Evaluation max(
const Arg1Eval& arg1,
const Arg2Eval& arg2)
567 {
return DenseAd::max(arg1, arg2); }
569 template <
class Arg1Eval,
class Arg2Eval>
570 static Evaluation min(
const Arg1Eval& arg1,
const Arg2Eval& arg2)
571 {
return DenseAd::min(arg1, arg2); }
574 {
return DenseAd::abs(arg); }
577 {
return DenseAd::tan(arg); }
580 {
return DenseAd::atan(arg); }
583 {
return DenseAd::atan2(arg1, arg2); }
585 template <
class Eval2>
587 {
return DenseAd::atan2(arg1, arg2); }
589 template <
class Eval1>
591 {
return DenseAd::atan2(arg1, arg2); }
594 {
return DenseAd::sin(arg); }
597 {
return DenseAd::asin(arg); }
600 {
return DenseAd::cos(arg); }
603 {
return DenseAd::acos(arg); }
606 {
return DenseAd::sqrt(arg); }
609 {
return DenseAd::exp(arg); }
612 {
return DenseAd::log(arg); }
615 {
return DenseAd::log10(arg); }
617 template <
class RhsValueType>
619 {
return DenseAd::pow(arg1, arg2); }
621 template <
class RhsValueType>
623 {
return DenseAd::pow(arg1, arg2); }
626 {
return DenseAd::pow(arg1, arg2); }
633 for (
int i = 0; i < numVars; ++i)
645 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:57
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30