Merge pull request #2 from andlaus/generated_eval_specializations
Generated eval specializations
This commit is contained in:
commit
99ad3843df
231
bin/genEvalSpecializations.py
Executable file
231
bin/genEvalSpecializations.py
Executable file
@ -0,0 +1,231 @@
|
||||
#! /usr/bin/python
|
||||
#
|
||||
# This script provides "hand loop-unrolled" specializations of the
|
||||
# Evaluation class of dense automatic differentiation so that the
|
||||
# compiler can more easily emit SIMD instructions. In an ideal world,
|
||||
# C++ compilers should be smart enough to do this themselfs, but
|
||||
# contemporary compilers don't seem to exhibit enough brains.
|
||||
#
|
||||
# Usage: In the opm-material top-level source directory, run
|
||||
# `./bin/genEvalSpecializations.py [MAX_DERIVATIVES]`. The script then
|
||||
# generates specializations for Evaluations with up to MAX_DERIVATIVES
|
||||
# derivatives. The default for MAX_DERIVATIVES is 12. To run this
|
||||
# script, you need a python 2 installation where the Jinja2 module is
|
||||
# available.
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
import jinja2
|
||||
|
||||
maxDerivs = 12
|
||||
if len(sys.argv) == 2:
|
||||
maxDerivs = int(sys.argv[1])
|
||||
|
||||
fileNames = []
|
||||
|
||||
specializationTemplate = \
|
||||
"""// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
// vi: set et ts=4 sw=4 sts=4:
|
||||
/*
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Consult the COPYING file in the top-level source directory of this
|
||||
module for the precise wording of the license and the list of
|
||||
copyright holders.
|
||||
*/
|
||||
/*!
|
||||
* \\file
|
||||
*
|
||||
* \\brief This file specializes the dense-AD Evaluation class for {{ numDerivs }} derivatives.
|
||||
*
|
||||
* \\attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "{{ scriptName }}"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
#ifndef OPM_DENSEAD_EVALUATION{{numDerivs}}_HPP
|
||||
#define OPM_DENSEAD_EVALUATION{{numDerivs}}_HPP
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
|
||||
template <class ValueT>
|
||||
struct EvaluationOps<ValueT, {{numDerivs}}>
|
||||
{
|
||||
private:
|
||||
typedef Evaluation<ValueT, {{numDerivs}} > Eval;
|
||||
|
||||
public:
|
||||
typedef std::array<ValueT, {{numDerivs + 1}} > DataVector;
|
||||
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
{% for i in range(0, numDerivs+1) %}
|
||||
a.data_[{{i}}] = b.data_[{{i}}];{% endfor %}
|
||||
}
|
||||
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
{% for i in range(0, numDerivs+1) %}
|
||||
a.data_[{{i}}] = - b.data_[{{i}}];{% endfor %}
|
||||
}
|
||||
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
{% for i in range(1, numDerivs+1) %}
|
||||
a.data_[{{i}}] = 0.0;{% endfor %}
|
||||
}
|
||||
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
{% for i in range(0, numDerivs+1) %}
|
||||
a.data_[{{i}}] += b.data_[{{i}}];{% endfor %}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
{% for i in range(0, numDerivs+1) %}
|
||||
a.data_[{{i}}] -= b.data_[{{i}}];{% endfor %}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
// value
|
||||
a.data_[0] *= v ;
|
||||
|
||||
// derivatives{% for i in range(1, numDerivs+1) %}
|
||||
a.data_[{{i}}] = a.data_[{{i}}]*v + b.data_[{{i}}] * u;{% endfor %}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
{% for i in range(0, numDerivs+1) %}
|
||||
a.data_[{{i}}] *= other;{% endfor %}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
// value
|
||||
a.data_[0] *= v_vv;
|
||||
|
||||
// derivatives{% for i in range(1, numDerivs+1) %}
|
||||
a.data_[{{i}}] = a.data_[{{i}}]*v_vv - b.data_[{{i}}]*u_vv;{% endfor %}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
{% for i in range(0, numDerivs+1) %}
|
||||
a.data_[{{i}}] /= other;{% endfor %}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b)
|
||||
{
|
||||
Eval result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
{% for i in range(1, numDerivs+1) %}
|
||||
result.data_[{{i}}] = df_dg*b.data_[{{i}}];{% endfor %}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} } // namespace DenseAd, Opm
|
||||
|
||||
#endif // OPM_DENSEAD_EVALUATION{{numDerivs}}_HPP
|
||||
"""
|
||||
|
||||
includeSpecializationsTemplate = \
|
||||
"""// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
// vi: set et ts=4 sw=4 sts=4:
|
||||
/*
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Consult the COPYING file in the top-level source directory of this
|
||||
module for the precise wording of the license and the list of
|
||||
copyright holders.
|
||||
*/
|
||||
/*!
|
||||
* \\file
|
||||
*
|
||||
* \\brief This file includes all specializations for the dense-AD Evaluation class.
|
||||
*
|
||||
* \\attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "{{ scriptName }}"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
#ifndef OPM_DENSEAD_EVALUATION_SPECIALIZATIONS_HPP
|
||||
#define OPM_DENSEAD_EVALUATION_SPECIALIZATIONS_HPP
|
||||
|
||||
{% for fileName in fileNames %}#include <{{ fileName }}>
|
||||
{% endfor %}
|
||||
|
||||
#endif // OPM_DENSEAD_EVALUATION_SPECIALIZATIONS_HPP
|
||||
"""
|
||||
|
||||
for numDerivs in range(1, maxDerivs + 1):
|
||||
print "Generating specialization for %d derivatives"%numDerivs
|
||||
|
||||
fileName = "opm/material/densead/Evaluation%d.hpp"%numDerivs
|
||||
fileNames.append(fileName)
|
||||
|
||||
template = jinja2.Template(specializationTemplate)
|
||||
fileContents = template.render(numDerivs=numDerivs, scriptName=os.path.basename(sys.argv[0]))
|
||||
|
||||
f = open(fileName, "w")
|
||||
f.write(fileContents)
|
||||
f.close()
|
||||
|
||||
template = jinja2.Template(includeSpecializationsTemplate)
|
||||
fileContents = template.render(fileNames=fileNames, scriptName=os.path.basename(sys.argv[0]))
|
||||
|
||||
f = open("opm/material/densead/EvaluationSpecializations.hpp", "w")
|
||||
f.write(fileContents)
|
||||
f.close()
|
@ -39,11 +39,132 @@
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
template <class ValueT, int numVars>
|
||||
class Evaluation;
|
||||
|
||||
/*!
|
||||
* \brief Provides operations on Evaluations, so that these can be specialized without
|
||||
* having to copy-and-paste the whole Evaluation class.
|
||||
*
|
||||
* \internal
|
||||
*/
|
||||
template <class ValueT, int numVars>
|
||||
struct EvaluationOps
|
||||
{
|
||||
private:
|
||||
typedef Evaluation<ValueT, numVars> Eval;
|
||||
|
||||
static constexpr int length_ = Eval::length_;
|
||||
static constexpr int valuepos_ = Eval::valuepos_;
|
||||
static constexpr int dstart_ = Eval::dstart_;
|
||||
static constexpr int dend_ = Eval::dend_ ;
|
||||
|
||||
public:
|
||||
typedef std::array<ValueT, length_> DataVector;
|
||||
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
for (int i = dstart_; i < dend_; ++i)
|
||||
a.data_[i] = 0.0;
|
||||
}
|
||||
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
a.data_ = b.data_;
|
||||
}
|
||||
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
for (int idx = 0; idx < length_; ++idx)
|
||||
a.data_[idx] = - b.data_[idx];
|
||||
}
|
||||
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
for (int i = 0; i < length_; ++i)
|
||||
a.data_[i] += b.data_[i];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
for (int i = 0; i < length_; ++i)
|
||||
a.data_[i] -= b.data_[i];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
a.data_[valuepos_] *= v ;
|
||||
for (int idx = dstart_; idx < dend_; ++idx)
|
||||
a.data_[idx] = a.data_[idx] * v + b.data_[idx] * u;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsValueType& other)
|
||||
{
|
||||
// values and derivatives are multiplied
|
||||
for (int idx = 0 ; idx < length_; ++ idx)
|
||||
a.data_[idx] *= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
a.data_[valuepos_] *= v_vv;
|
||||
for (int idx = dstart_; idx < dend_; ++idx)
|
||||
a.data_[idx] = a.data_[idx] * v_vv - b.data_[idx] * u_vv;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsValueType& other)
|
||||
{
|
||||
// values and derivatives are divided
|
||||
for (int idx = 0 ; idx <= length_; ++ idx)
|
||||
a.data_[idx] /= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// a/b with 'a' being a scalar and 'b' an Evaluation
|
||||
template <class RhsValueType>
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b )
|
||||
{
|
||||
Eval result;
|
||||
|
||||
result.setValue( a/b.value() );
|
||||
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
for (int idx = dstart_; idx < dend_; ++idx)
|
||||
result.data_[idx] = df_dg*b.data_[idx];
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Represents a function evaluation and its derivatives w.r.t. a fixed set of
|
||||
* variables.
|
||||
@ -51,6 +172,10 @@ namespace DenseAd {
|
||||
template <class ValueT, int numVars>
|
||||
class Evaluation
|
||||
{
|
||||
typedef EvaluationOps<ValueT, numVars> Ops;
|
||||
|
||||
friend Ops;
|
||||
|
||||
public:
|
||||
//! field type
|
||||
typedef ValueT ValueType;
|
||||
@ -75,8 +200,9 @@ public:
|
||||
{}
|
||||
|
||||
//! copy other function evaluation
|
||||
Evaluation(const Evaluation& other) : data_( other.data_ )
|
||||
Evaluation(const Evaluation& other)
|
||||
{
|
||||
Ops::assign(*this, other);
|
||||
}
|
||||
|
||||
// create an evaluation which represents a constant function
|
||||
@ -110,8 +236,7 @@ public:
|
||||
// set all derivatives to zero
|
||||
void clearDerivatives()
|
||||
{
|
||||
for (int i = dstart_; i < dend_; ++i)
|
||||
data_[ i ] = 0.0;
|
||||
Ops::clearDerivatives(*this);
|
||||
}
|
||||
|
||||
// create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
|
||||
@ -123,20 +248,6 @@ public:
|
||||
return Evaluation( value, varPos );
|
||||
}
|
||||
|
||||
|
||||
// create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
|
||||
template <class RhsValueType>
|
||||
static Evaluation devide(const RhsValueType& a, const Evaluation& b )
|
||||
{
|
||||
Evaluation<ValueType, numVars> result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueType df_dg = - result.value()/b.value();
|
||||
for (int idx = dstart_; idx < dend_; ++idx) {
|
||||
result.data_[idx] = df_dg*b.data_[idx];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "evaluate" a constant function (i.e. a function that does not depend on the set of
|
||||
// relevant variables, f(x) = c).
|
||||
template <class RhsValueType>
|
||||
@ -165,13 +276,7 @@ public:
|
||||
|
||||
// add value and derivatives from other to this values and derivatives
|
||||
Evaluation& operator+=(const Evaluation& other)
|
||||
{
|
||||
// value and derivatives are added
|
||||
for (int varIdx = 0; varIdx < length_; ++ varIdx)
|
||||
data_[ varIdx ] += other.data_[ varIdx ];
|
||||
|
||||
return *this;
|
||||
}
|
||||
{ return Ops::addEq(*this, other); }
|
||||
|
||||
// add value from other to this values
|
||||
template <class RhsValueType>
|
||||
@ -184,13 +289,7 @@ public:
|
||||
|
||||
// subtract other's value and derivatives from this values
|
||||
Evaluation& operator-=(const Evaluation& other)
|
||||
{
|
||||
// value and derivatives are subtracted
|
||||
for (int idx = 0 ; idx < length_ ; ++ idx)
|
||||
data_[idx] -= other.data_[idx];
|
||||
|
||||
return *this;
|
||||
}
|
||||
{ return Ops::subEq(*this, other); }
|
||||
|
||||
// subtract other's value from this values
|
||||
template <class RhsValueType>
|
||||
@ -204,54 +303,21 @@ public:
|
||||
|
||||
// multiply values and apply chain rule to derivatives: (u*v)' = (v'u + u'v)
|
||||
Evaluation& operator*=(const Evaluation& other)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueType u = value();
|
||||
const ValueType v = other.value();
|
||||
|
||||
data_[ valuepos_ ] *= v ;
|
||||
for (int idx = dstart_; idx < dend_; ++idx) {
|
||||
data_[idx] = data_[idx] * v + other.data_[idx] * u;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
{ return Ops::mulEq(*this, other); }
|
||||
|
||||
// m(u*v)' = (v'u + u'v)
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator*=(const RhsValueType& other)
|
||||
{
|
||||
// values and derivatives are multiplied
|
||||
for (int idx = 0 ; idx < length_ ; ++ idx)
|
||||
data_[idx] *= other;
|
||||
|
||||
return *this;
|
||||
}
|
||||
{ return Ops::scalarMulEq(*this, other); }
|
||||
|
||||
// m(u*v)' = (v'u + u'v)
|
||||
Evaluation& operator/=(const Evaluation& other)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueType v_vv = 1.0 / other.value();
|
||||
const ValueType u_vv = value() * v_vv * v_vv;
|
||||
|
||||
data_[ valuepos_ ] *= v_vv;
|
||||
for (int idx = dstart_; idx < dend_; ++idx) {
|
||||
data_[idx] = data_[idx] * v_vv - other.data_[idx] * u_vv;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
{ return Ops::divEq(*this, other); }
|
||||
|
||||
// multiply value and derivatives by value of other
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator/=(const RhsValueType& other)
|
||||
{
|
||||
// values and derivatives are divided
|
||||
const ValueType factor = (1.0/other);
|
||||
return this->operator *=( factor );
|
||||
}
|
||||
{ return Ops::scalarDivEq(*this, other); }
|
||||
|
||||
// add two evaluation objects
|
||||
Evaluation operator+(const Evaluation& other) const
|
||||
@ -274,8 +340,7 @@ public:
|
||||
Evaluation operator-(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result -= other;
|
||||
return result;
|
||||
return (result -= other);
|
||||
}
|
||||
|
||||
// subtract constant from evaluation object
|
||||
@ -283,8 +348,7 @@ public:
|
||||
Evaluation operator-(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result -= other;
|
||||
return result;
|
||||
return (result -= other);
|
||||
}
|
||||
|
||||
// negation (unary minus) operator
|
||||
@ -292,8 +356,7 @@ public:
|
||||
{
|
||||
Evaluation result;
|
||||
// set value and derivatives to negative
|
||||
for (int idx = 0; idx < length_; ++idx)
|
||||
result.data_[idx] = - data_[idx];
|
||||
Ops::assignNegative(result, *this);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -339,7 +402,7 @@ public:
|
||||
// copy assignment from evaluation
|
||||
Evaluation& operator=(const Evaluation& other)
|
||||
{
|
||||
data_ = other.data_;
|
||||
Ops::assign(*this, other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -392,7 +455,8 @@ public:
|
||||
{ return data_[valuepos_]; }
|
||||
|
||||
// set value of variable
|
||||
void setValue(const ValueType& val)
|
||||
template <class RhsValueType>
|
||||
void setValue(const RhsValueType& val)
|
||||
{ data_[valuepos_] = val; }
|
||||
|
||||
// return varIdx'th derivative
|
||||
@ -410,7 +474,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
std::array<ValueType, length_> data_;
|
||||
typename Ops::DataVector data_;
|
||||
};
|
||||
|
||||
template <class RhsValueType, class ValueType, int numVars>
|
||||
@ -437,16 +501,14 @@ template <class RhsValueType, class ValueType, int numVars>
|
||||
Evaluation<ValueType, numVars> operator+(const RhsValueType& a, const Evaluation<ValueType, numVars>& b)
|
||||
{
|
||||
Evaluation<ValueType, numVars> result(b);
|
||||
|
||||
result += a;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType, class ValueType, int numVars>
|
||||
Evaluation<ValueType, numVars> operator-(const RhsValueType& a, const Evaluation<ValueType, numVars>& b)
|
||||
{
|
||||
Evaluation<ValueType, numVars> result( a );
|
||||
Evaluation<ValueType, numVars> result(a);
|
||||
result -= b;
|
||||
return result;
|
||||
}
|
||||
@ -454,13 +516,15 @@ Evaluation<ValueType, numVars> operator-(const RhsValueType& a, const Evaluation
|
||||
template <class RhsValueType, class ValueType, int numVars>
|
||||
Evaluation<ValueType, numVars> operator/(const RhsValueType& a, const Evaluation<ValueType, numVars>& b)
|
||||
{
|
||||
return Evaluation<ValueType, numVars>::devide( a, b );
|
||||
typedef EvaluationOps<ValueType, numVars> Ops;
|
||||
|
||||
return Ops::divide(a, b);
|
||||
}
|
||||
|
||||
template <class RhsValueType, class ValueType, int numVars>
|
||||
Evaluation<ValueType, numVars> operator*(const RhsValueType& a, const Evaluation<ValueType, numVars>& b)
|
||||
{
|
||||
Evaluation<ValueType, numVars> result( b );
|
||||
Evaluation<ValueType, numVars> result(b);
|
||||
result *= a;
|
||||
return result;
|
||||
}
|
||||
@ -537,10 +601,6 @@ public:
|
||||
|
||||
} // namespace Dune
|
||||
|
||||
#include <opm/material/densead/Evaluation1.hpp>
|
||||
#include <opm/material/densead/Evaluation2.hpp>
|
||||
#include <opm/material/densead/Evaluation3.hpp>
|
||||
#include <opm/material/densead/Evaluation6.hpp>
|
||||
#include <opm/material/densead/Evaluation12.hpp>
|
||||
#include <opm/material/densead/EvaluationSpecializations.hpp>
|
||||
|
||||
#endif
|
||||
|
@ -23,394 +23,128 @@
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Representation of an evaluation of a function and its derivatives w.r.t. a set
|
||||
* of variables in the localized OPM automatic differentiation (AD) framework.
|
||||
* \brief This file specializes the dense-AD Evaluation class for 1 derivatives.
|
||||
*
|
||||
* \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
|
||||
#ifndef OPM_LOCAL_AD_EVALUATION_1_HPP
|
||||
#define OPM_LOCAL_AD_EVALUATION_1_HPP
|
||||
|
||||
#include "Math.hpp"
|
||||
|
||||
#include <opm/common/Valgrind.hpp>
|
||||
|
||||
#include <dune/common/version.hh>
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#ifndef OPM_DENSEAD_EVALUATION1_HPP
|
||||
#define OPM_DENSEAD_EVALUATION1_HPP
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
/*!
|
||||
* \brief Represents a function evaluation and its derivatives w.r.t. a fixed set of
|
||||
* variables.
|
||||
*/
|
||||
|
||||
template <class ValueT>
|
||||
class Evaluation< ValueT, 1 >
|
||||
struct EvaluationOps<ValueT, 1>
|
||||
{
|
||||
static constexpr int numVars = 1;
|
||||
private:
|
||||
typedef Evaluation<ValueT, 1 > Eval;
|
||||
|
||||
public:
|
||||
//! field type
|
||||
typedef ValueT ValueType;
|
||||
typedef std::array<ValueT, 2 > DataVector;
|
||||
|
||||
//! number of derivatives
|
||||
static constexpr int size = numVars;
|
||||
|
||||
protected:
|
||||
//! length of internal data vector
|
||||
static constexpr int length_ = numVars + 1 ;
|
||||
|
||||
//! position index for value
|
||||
static constexpr int valuepos_ = 0;
|
||||
//! start index for derivatives
|
||||
static constexpr int dstart_ = 1;
|
||||
//! end+1 index for derivatives
|
||||
static constexpr int dend_ = length_ ;
|
||||
public:
|
||||
|
||||
//! default constructor
|
||||
Evaluation() : data_()
|
||||
{}
|
||||
|
||||
//! copy other function evaluation
|
||||
Evaluation(const Evaluation& other) : data_( other.data_ )
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = b.data_[0];
|
||||
a.data_[1] = b.data_[1];
|
||||
}
|
||||
|
||||
// create an evaluation which represents a constant function
|
||||
//
|
||||
// i.e., f(x) = c. this implies an evaluation with the given value and all
|
||||
// derivatives being zero.
|
||||
template <class RhsValueType>
|
||||
Evaluation(const RhsValueType& c)
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
setValue( c );
|
||||
clearDerivatives();
|
||||
Valgrind::CheckDefined( data_ );
|
||||
|
||||
a.data_[0] = - b.data_[0];
|
||||
a.data_[1] = - b.data_[1];
|
||||
}
|
||||
|
||||
// create an evaluation which represents a constant function
|
||||
//
|
||||
// i.e., f(x) = c. this implies an evaluation with the given value and all
|
||||
// derivatives being zero.
|
||||
template <class RhsValueType>
|
||||
Evaluation(const RhsValueType& c, int varPos)
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
setValue( c );
|
||||
clearDerivatives();
|
||||
// The variable position must be in represented by the given variable descriptor
|
||||
assert(0 <= varPos && varPos < numVars);
|
||||
|
||||
data_[varPos + dstart_] = 1.0;
|
||||
Valgrind::CheckDefined(data_);
|
||||
a.data_[1] = 0.0;
|
||||
}
|
||||
|
||||
// set all derivatives to zero
|
||||
void clearDerivatives()
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
data_[ 1 ] = 0;
|
||||
|
||||
a.data_[0] += b.data_[0];
|
||||
a.data_[1] += b.data_[1];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
// create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
|
||||
template <class RhsValueType>
|
||||
static Evaluation devide(const RhsValueType& a, const Evaluation& b )
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
Evaluation<ValueType, numVars> result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueType df_dg = - result.value()/b.value();
|
||||
for (int idx = dstart_; idx < dend_; ++idx) {
|
||||
result.data_[idx] = df_dg*b.data_[idx];
|
||||
}
|
||||
return result;
|
||||
|
||||
a.data_[0] -= b.data_[0];
|
||||
a.data_[1] -= b.data_[1];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
|
||||
template <class RhsValueType>
|
||||
static Evaluation createVariable(const RhsValueType& value, int varPos)
|
||||
{
|
||||
// copy function value and set all derivatives to 0, except for the variable
|
||||
// which is represented by the value (which is set to 1.0)
|
||||
return Evaluation( value, varPos );
|
||||
}
|
||||
|
||||
// "evaluate" a constant function (i.e. a function that does not depend on the set of
|
||||
// relevant variables, f(x) = c).
|
||||
template <class RhsValueType>
|
||||
static Evaluation createConstant(const RhsValueType& value)
|
||||
{
|
||||
return Evaluation( value );
|
||||
}
|
||||
|
||||
// print the value and the derivatives of the function evaluation
|
||||
void print(std::ostream& os = std::cout) const
|
||||
{
|
||||
// print value
|
||||
os << "v: " << value() << " / d:";
|
||||
// print derivatives
|
||||
for (int varIdx = 0; varIdx < numVars; ++varIdx)
|
||||
os << " " << derivative(varIdx);
|
||||
}
|
||||
|
||||
// copy all derivatives from other
|
||||
void copyDerivatives(const Evaluation& other)
|
||||
{
|
||||
data_[ 1 ] = other.data_[ 1 ];
|
||||
}
|
||||
|
||||
|
||||
// add value and derivatives from other to this values and derivatives
|
||||
Evaluation& operator+=(const Evaluation& other)
|
||||
{
|
||||
data_[ 0 ] += other.data_[ 0 ];
|
||||
data_[ 1 ] += other.data_[ 1 ];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// add value from other to this values
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator+=(const RhsValueType& other)
|
||||
{
|
||||
// value is added, derivatives stay the same
|
||||
data_[valuepos_] += other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// subtract other's value and derivatives from this values
|
||||
Evaluation& operator-=(const Evaluation& other)
|
||||
{
|
||||
// value and derivatives are subtracted
|
||||
data_[ 0 ] -= other.data_[ 0 ];
|
||||
data_[ 1 ] -= other.data_[ 1 ];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// subtract other's value from this values
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator-=(const RhsValueType& other)
|
||||
{
|
||||
// for constants, values are subtracted, derivatives stay the same
|
||||
data_[ valuepos_ ] -= other;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// multiply values and apply chain rule to derivatives: (u*v)' = (v'u + u'v)
|
||||
Evaluation& operator*=(const Evaluation& other)
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueType u = value();
|
||||
const ValueType v = other.value();
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
data_[ 0 ] = u * v ;
|
||||
data_[ 1 ] = data_[ 1 ] * v + other.data_[ 1 ] * u;
|
||||
// value
|
||||
a.data_[0] *= v ;
|
||||
|
||||
return *this;
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v + b.data_[1] * u;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] *= other;
|
||||
a.data_[1] *= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
// value
|
||||
a.data_[0] *= v_vv;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v_vv - b.data_[1]*u_vv;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] /= other;
|
||||
a.data_[1] /= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// m(u*v)' = (v'u + u'v)
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator*=(RhsValueType other)
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b)
|
||||
{
|
||||
data_[ 0 ] *= other;
|
||||
data_[ 1 ] *= other;
|
||||
return *this;
|
||||
}
|
||||
Eval result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
|
||||
// m(u*v)' = (v'u + u'v)
|
||||
Evaluation& operator/=(const Evaluation& other)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u -
|
||||
// u'v)/v^2.
|
||||
const ValueType v_vv = 1.0 / other.value();
|
||||
const ValueType u_vv = value() * v_vv * v_vv;
|
||||
|
||||
data_[ 0 ] *= v_vv;
|
||||
data_[ 1 ] = data_[ 1 ] * v_vv - other.data_[ 1 ] * u_vv ;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// multiply value and derivatives by value of other
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator/=(const RhsValueType& other)
|
||||
{
|
||||
// values and derivatives are divided
|
||||
ValueType factor = (1.0/other);
|
||||
data_[ 0 ] *= factor;
|
||||
data_[ 1 ] *= factor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// add two evaluation objects
|
||||
Evaluation operator+(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result += other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// add constant to this object
|
||||
template <class RhsValueType>
|
||||
Evaluation operator+(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result += other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// subtract two evaluation objects
|
||||
Evaluation operator-(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result -= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// subtract constant from evaluation object
|
||||
template <class RhsValueType>
|
||||
Evaluation operator-(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result -= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// negation (unary minus) operator
|
||||
Evaluation operator-() const
|
||||
{
|
||||
Evaluation result;
|
||||
// set value and derivatives to negative
|
||||
for (int idx = 0; idx < length_; ++idx)
|
||||
result.data_[idx] = - data_[idx];
|
||||
result.data_[1] = df_dg*b.data_[1];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Evaluation operator*(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result *= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation operator*(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result *= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
Evaluation operator/(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result /= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation operator/(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result /= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator=(const RhsValueType& other)
|
||||
{
|
||||
setValue( other );
|
||||
clearDerivatives();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy assignment from evaluation
|
||||
Evaluation& operator=(const Evaluation& other)
|
||||
{
|
||||
data_ = other.data_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator==(const RhsValueType& other) const
|
||||
{ return value() == other; }
|
||||
|
||||
bool operator==(const Evaluation& other) const
|
||||
{
|
||||
for (int idx = 0; idx < length_; ++idx)
|
||||
if (data_[idx] != other.data_[idx])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const Evaluation& other) const
|
||||
{ return !operator==(other); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator>(RhsValueType other) const
|
||||
{ return value() > other; }
|
||||
|
||||
bool operator>(const Evaluation& other) const
|
||||
{ return value() > other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator<(RhsValueType other) const
|
||||
{ return value() < other; }
|
||||
|
||||
bool operator<(const Evaluation& other) const
|
||||
{ return value() < other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator>=(RhsValueType other) const
|
||||
{ return value() >= other; }
|
||||
|
||||
bool operator>=(const Evaluation& other) const
|
||||
{ return value() >= other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator<=(RhsValueType other) const
|
||||
{ return value() <= other; }
|
||||
|
||||
bool operator<=(const Evaluation& other) const
|
||||
{ return value() <= other.value(); }
|
||||
|
||||
// return value of variable
|
||||
const ValueType& value() const
|
||||
{ return data_[valuepos_]; }
|
||||
|
||||
// set value of variable
|
||||
void setValue(const ValueType& val)
|
||||
{ data_[valuepos_] = val; }
|
||||
|
||||
// return varIdx'th derivative
|
||||
const ValueType& derivative(int varIdx) const
|
||||
{
|
||||
assert(varIdx < numVars);
|
||||
return data_[varIdx + dstart_];
|
||||
}
|
||||
|
||||
// set derivative at position varIdx
|
||||
void setDerivative(int varIdx, const ValueType& derVal)
|
||||
{
|
||||
assert(varIdx < numVars);
|
||||
data_[varIdx + dstart_] = derVal;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::array<ValueType, length_> data_;
|
||||
};
|
||||
|
||||
} // namespace DenseAD
|
||||
} // namespace Dune
|
||||
} } // namespace DenseAd, Opm
|
||||
|
||||
#endif
|
||||
#endif // OPM_DENSEAD_EVALUATION1_HPP
|
240
opm/material/densead/Evaluation10.hpp
Normal file
240
opm/material/densead/Evaluation10.hpp
Normal file
@ -0,0 +1,240 @@
|
||||
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
// vi: set et ts=4 sw=4 sts=4:
|
||||
/*
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Consult the COPYING file in the top-level source directory of this
|
||||
module for the precise wording of the license and the list of
|
||||
copyright holders.
|
||||
*/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief This file specializes the dense-AD Evaluation class for 10 derivatives.
|
||||
*
|
||||
* \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
#ifndef OPM_DENSEAD_EVALUATION10_HPP
|
||||
#define OPM_DENSEAD_EVALUATION10_HPP
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
|
||||
template <class ValueT>
|
||||
struct EvaluationOps<ValueT, 10>
|
||||
{
|
||||
private:
|
||||
typedef Evaluation<ValueT, 10 > Eval;
|
||||
|
||||
public:
|
||||
typedef std::array<ValueT, 11 > DataVector;
|
||||
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = b.data_[0];
|
||||
a.data_[1] = b.data_[1];
|
||||
a.data_[2] = b.data_[2];
|
||||
a.data_[3] = b.data_[3];
|
||||
a.data_[4] = b.data_[4];
|
||||
a.data_[5] = b.data_[5];
|
||||
a.data_[6] = b.data_[6];
|
||||
a.data_[7] = b.data_[7];
|
||||
a.data_[8] = b.data_[8];
|
||||
a.data_[9] = b.data_[9];
|
||||
a.data_[10] = b.data_[10];
|
||||
}
|
||||
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = - b.data_[0];
|
||||
a.data_[1] = - b.data_[1];
|
||||
a.data_[2] = - b.data_[2];
|
||||
a.data_[3] = - b.data_[3];
|
||||
a.data_[4] = - b.data_[4];
|
||||
a.data_[5] = - b.data_[5];
|
||||
a.data_[6] = - b.data_[6];
|
||||
a.data_[7] = - b.data_[7];
|
||||
a.data_[8] = - b.data_[8];
|
||||
a.data_[9] = - b.data_[9];
|
||||
a.data_[10] = - b.data_[10];
|
||||
}
|
||||
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
|
||||
a.data_[1] = 0.0;
|
||||
a.data_[2] = 0.0;
|
||||
a.data_[3] = 0.0;
|
||||
a.data_[4] = 0.0;
|
||||
a.data_[5] = 0.0;
|
||||
a.data_[6] = 0.0;
|
||||
a.data_[7] = 0.0;
|
||||
a.data_[8] = 0.0;
|
||||
a.data_[9] = 0.0;
|
||||
a.data_[10] = 0.0;
|
||||
}
|
||||
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] += b.data_[0];
|
||||
a.data_[1] += b.data_[1];
|
||||
a.data_[2] += b.data_[2];
|
||||
a.data_[3] += b.data_[3];
|
||||
a.data_[4] += b.data_[4];
|
||||
a.data_[5] += b.data_[5];
|
||||
a.data_[6] += b.data_[6];
|
||||
a.data_[7] += b.data_[7];
|
||||
a.data_[8] += b.data_[8];
|
||||
a.data_[9] += b.data_[9];
|
||||
a.data_[10] += b.data_[10];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] -= b.data_[0];
|
||||
a.data_[1] -= b.data_[1];
|
||||
a.data_[2] -= b.data_[2];
|
||||
a.data_[3] -= b.data_[3];
|
||||
a.data_[4] -= b.data_[4];
|
||||
a.data_[5] -= b.data_[5];
|
||||
a.data_[6] -= b.data_[6];
|
||||
a.data_[7] -= b.data_[7];
|
||||
a.data_[8] -= b.data_[8];
|
||||
a.data_[9] -= b.data_[9];
|
||||
a.data_[10] -= b.data_[10];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
// value
|
||||
a.data_[0] *= v ;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v + b.data_[1] * u;
|
||||
a.data_[2] = a.data_[2]*v + b.data_[2] * u;
|
||||
a.data_[3] = a.data_[3]*v + b.data_[3] * u;
|
||||
a.data_[4] = a.data_[4]*v + b.data_[4] * u;
|
||||
a.data_[5] = a.data_[5]*v + b.data_[5] * u;
|
||||
a.data_[6] = a.data_[6]*v + b.data_[6] * u;
|
||||
a.data_[7] = a.data_[7]*v + b.data_[7] * u;
|
||||
a.data_[8] = a.data_[8]*v + b.data_[8] * u;
|
||||
a.data_[9] = a.data_[9]*v + b.data_[9] * u;
|
||||
a.data_[10] = a.data_[10]*v + b.data_[10] * u;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] *= other;
|
||||
a.data_[1] *= other;
|
||||
a.data_[2] *= other;
|
||||
a.data_[3] *= other;
|
||||
a.data_[4] *= other;
|
||||
a.data_[5] *= other;
|
||||
a.data_[6] *= other;
|
||||
a.data_[7] *= other;
|
||||
a.data_[8] *= other;
|
||||
a.data_[9] *= other;
|
||||
a.data_[10] *= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
// value
|
||||
a.data_[0] *= v_vv;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v_vv - b.data_[1]*u_vv;
|
||||
a.data_[2] = a.data_[2]*v_vv - b.data_[2]*u_vv;
|
||||
a.data_[3] = a.data_[3]*v_vv - b.data_[3]*u_vv;
|
||||
a.data_[4] = a.data_[4]*v_vv - b.data_[4]*u_vv;
|
||||
a.data_[5] = a.data_[5]*v_vv - b.data_[5]*u_vv;
|
||||
a.data_[6] = a.data_[6]*v_vv - b.data_[6]*u_vv;
|
||||
a.data_[7] = a.data_[7]*v_vv - b.data_[7]*u_vv;
|
||||
a.data_[8] = a.data_[8]*v_vv - b.data_[8]*u_vv;
|
||||
a.data_[9] = a.data_[9]*v_vv - b.data_[9]*u_vv;
|
||||
a.data_[10] = a.data_[10]*v_vv - b.data_[10]*u_vv;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] /= other;
|
||||
a.data_[1] /= other;
|
||||
a.data_[2] /= other;
|
||||
a.data_[3] /= other;
|
||||
a.data_[4] /= other;
|
||||
a.data_[5] /= other;
|
||||
a.data_[6] /= other;
|
||||
a.data_[7] /= other;
|
||||
a.data_[8] /= other;
|
||||
a.data_[9] /= other;
|
||||
a.data_[10] /= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b)
|
||||
{
|
||||
Eval result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
|
||||
result.data_[1] = df_dg*b.data_[1];
|
||||
result.data_[2] = df_dg*b.data_[2];
|
||||
result.data_[3] = df_dg*b.data_[3];
|
||||
result.data_[4] = df_dg*b.data_[4];
|
||||
result.data_[5] = df_dg*b.data_[5];
|
||||
result.data_[6] = df_dg*b.data_[6];
|
||||
result.data_[7] = df_dg*b.data_[7];
|
||||
result.data_[8] = df_dg*b.data_[8];
|
||||
result.data_[9] = df_dg*b.data_[9];
|
||||
result.data_[10] = df_dg*b.data_[10];
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} } // namespace DenseAd, Opm
|
||||
|
||||
#endif // OPM_DENSEAD_EVALUATION10_HPP
|
250
opm/material/densead/Evaluation11.hpp
Normal file
250
opm/material/densead/Evaluation11.hpp
Normal file
@ -0,0 +1,250 @@
|
||||
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
// vi: set et ts=4 sw=4 sts=4:
|
||||
/*
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Consult the COPYING file in the top-level source directory of this
|
||||
module for the precise wording of the license and the list of
|
||||
copyright holders.
|
||||
*/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief This file specializes the dense-AD Evaluation class for 11 derivatives.
|
||||
*
|
||||
* \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
#ifndef OPM_DENSEAD_EVALUATION11_HPP
|
||||
#define OPM_DENSEAD_EVALUATION11_HPP
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
|
||||
template <class ValueT>
|
||||
struct EvaluationOps<ValueT, 11>
|
||||
{
|
||||
private:
|
||||
typedef Evaluation<ValueT, 11 > Eval;
|
||||
|
||||
public:
|
||||
typedef std::array<ValueT, 12 > DataVector;
|
||||
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = b.data_[0];
|
||||
a.data_[1] = b.data_[1];
|
||||
a.data_[2] = b.data_[2];
|
||||
a.data_[3] = b.data_[3];
|
||||
a.data_[4] = b.data_[4];
|
||||
a.data_[5] = b.data_[5];
|
||||
a.data_[6] = b.data_[6];
|
||||
a.data_[7] = b.data_[7];
|
||||
a.data_[8] = b.data_[8];
|
||||
a.data_[9] = b.data_[9];
|
||||
a.data_[10] = b.data_[10];
|
||||
a.data_[11] = b.data_[11];
|
||||
}
|
||||
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = - b.data_[0];
|
||||
a.data_[1] = - b.data_[1];
|
||||
a.data_[2] = - b.data_[2];
|
||||
a.data_[3] = - b.data_[3];
|
||||
a.data_[4] = - b.data_[4];
|
||||
a.data_[5] = - b.data_[5];
|
||||
a.data_[6] = - b.data_[6];
|
||||
a.data_[7] = - b.data_[7];
|
||||
a.data_[8] = - b.data_[8];
|
||||
a.data_[9] = - b.data_[9];
|
||||
a.data_[10] = - b.data_[10];
|
||||
a.data_[11] = - b.data_[11];
|
||||
}
|
||||
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
|
||||
a.data_[1] = 0.0;
|
||||
a.data_[2] = 0.0;
|
||||
a.data_[3] = 0.0;
|
||||
a.data_[4] = 0.0;
|
||||
a.data_[5] = 0.0;
|
||||
a.data_[6] = 0.0;
|
||||
a.data_[7] = 0.0;
|
||||
a.data_[8] = 0.0;
|
||||
a.data_[9] = 0.0;
|
||||
a.data_[10] = 0.0;
|
||||
a.data_[11] = 0.0;
|
||||
}
|
||||
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] += b.data_[0];
|
||||
a.data_[1] += b.data_[1];
|
||||
a.data_[2] += b.data_[2];
|
||||
a.data_[3] += b.data_[3];
|
||||
a.data_[4] += b.data_[4];
|
||||
a.data_[5] += b.data_[5];
|
||||
a.data_[6] += b.data_[6];
|
||||
a.data_[7] += b.data_[7];
|
||||
a.data_[8] += b.data_[8];
|
||||
a.data_[9] += b.data_[9];
|
||||
a.data_[10] += b.data_[10];
|
||||
a.data_[11] += b.data_[11];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] -= b.data_[0];
|
||||
a.data_[1] -= b.data_[1];
|
||||
a.data_[2] -= b.data_[2];
|
||||
a.data_[3] -= b.data_[3];
|
||||
a.data_[4] -= b.data_[4];
|
||||
a.data_[5] -= b.data_[5];
|
||||
a.data_[6] -= b.data_[6];
|
||||
a.data_[7] -= b.data_[7];
|
||||
a.data_[8] -= b.data_[8];
|
||||
a.data_[9] -= b.data_[9];
|
||||
a.data_[10] -= b.data_[10];
|
||||
a.data_[11] -= b.data_[11];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
// value
|
||||
a.data_[0] *= v ;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v + b.data_[1] * u;
|
||||
a.data_[2] = a.data_[2]*v + b.data_[2] * u;
|
||||
a.data_[3] = a.data_[3]*v + b.data_[3] * u;
|
||||
a.data_[4] = a.data_[4]*v + b.data_[4] * u;
|
||||
a.data_[5] = a.data_[5]*v + b.data_[5] * u;
|
||||
a.data_[6] = a.data_[6]*v + b.data_[6] * u;
|
||||
a.data_[7] = a.data_[7]*v + b.data_[7] * u;
|
||||
a.data_[8] = a.data_[8]*v + b.data_[8] * u;
|
||||
a.data_[9] = a.data_[9]*v + b.data_[9] * u;
|
||||
a.data_[10] = a.data_[10]*v + b.data_[10] * u;
|
||||
a.data_[11] = a.data_[11]*v + b.data_[11] * u;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] *= other;
|
||||
a.data_[1] *= other;
|
||||
a.data_[2] *= other;
|
||||
a.data_[3] *= other;
|
||||
a.data_[4] *= other;
|
||||
a.data_[5] *= other;
|
||||
a.data_[6] *= other;
|
||||
a.data_[7] *= other;
|
||||
a.data_[8] *= other;
|
||||
a.data_[9] *= other;
|
||||
a.data_[10] *= other;
|
||||
a.data_[11] *= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
// value
|
||||
a.data_[0] *= v_vv;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v_vv - b.data_[1]*u_vv;
|
||||
a.data_[2] = a.data_[2]*v_vv - b.data_[2]*u_vv;
|
||||
a.data_[3] = a.data_[3]*v_vv - b.data_[3]*u_vv;
|
||||
a.data_[4] = a.data_[4]*v_vv - b.data_[4]*u_vv;
|
||||
a.data_[5] = a.data_[5]*v_vv - b.data_[5]*u_vv;
|
||||
a.data_[6] = a.data_[6]*v_vv - b.data_[6]*u_vv;
|
||||
a.data_[7] = a.data_[7]*v_vv - b.data_[7]*u_vv;
|
||||
a.data_[8] = a.data_[8]*v_vv - b.data_[8]*u_vv;
|
||||
a.data_[9] = a.data_[9]*v_vv - b.data_[9]*u_vv;
|
||||
a.data_[10] = a.data_[10]*v_vv - b.data_[10]*u_vv;
|
||||
a.data_[11] = a.data_[11]*v_vv - b.data_[11]*u_vv;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] /= other;
|
||||
a.data_[1] /= other;
|
||||
a.data_[2] /= other;
|
||||
a.data_[3] /= other;
|
||||
a.data_[4] /= other;
|
||||
a.data_[5] /= other;
|
||||
a.data_[6] /= other;
|
||||
a.data_[7] /= other;
|
||||
a.data_[8] /= other;
|
||||
a.data_[9] /= other;
|
||||
a.data_[10] /= other;
|
||||
a.data_[11] /= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b)
|
||||
{
|
||||
Eval result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
|
||||
result.data_[1] = df_dg*b.data_[1];
|
||||
result.data_[2] = df_dg*b.data_[2];
|
||||
result.data_[3] = df_dg*b.data_[3];
|
||||
result.data_[4] = df_dg*b.data_[4];
|
||||
result.data_[5] = df_dg*b.data_[5];
|
||||
result.data_[6] = df_dg*b.data_[6];
|
||||
result.data_[7] = df_dg*b.data_[7];
|
||||
result.data_[8] = df_dg*b.data_[8];
|
||||
result.data_[9] = df_dg*b.data_[9];
|
||||
result.data_[10] = df_dg*b.data_[10];
|
||||
result.data_[11] = df_dg*b.data_[11];
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} } // namespace DenseAd, Opm
|
||||
|
||||
#endif // OPM_DENSEAD_EVALUATION11_HPP
|
@ -23,485 +23,238 @@
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Representation of an evaluation of a function and its derivatives w.r.t. a set
|
||||
* of variables in the localized OPM automatic differentiation (AD) framework.
|
||||
* \brief This file specializes the dense-AD Evaluation class for 12 derivatives.
|
||||
*
|
||||
* \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
|
||||
#ifndef OPM_LOCAL_AD_EVALUATION_12_HPP
|
||||
#define OPM_LOCAL_AD_EVALUATION_12_HPP
|
||||
|
||||
#include "Math.hpp"
|
||||
|
||||
#include <opm/common/Valgrind.hpp>
|
||||
|
||||
#include <dune/common/version.hh>
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#ifndef OPM_DENSEAD_EVALUATION12_HPP
|
||||
#define OPM_DENSEAD_EVALUATION12_HPP
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
/*!
|
||||
* \brief Represents a function evaluation and its derivatives w.r.t. a fixed set of
|
||||
* variables.
|
||||
*/
|
||||
|
||||
template <class ValueT>
|
||||
class Evaluation< ValueT, 12 >
|
||||
struct EvaluationOps<ValueT, 12>
|
||||
{
|
||||
static constexpr int numVars = 12;
|
||||
private:
|
||||
typedef Evaluation<ValueT, 12 > Eval;
|
||||
|
||||
public:
|
||||
//! field type
|
||||
typedef ValueT ValueType;
|
||||
typedef std::array<ValueT, 13 > DataVector;
|
||||
|
||||
//! number of derivatives
|
||||
static constexpr int size = numVars;
|
||||
|
||||
protected:
|
||||
//! length of internal data vector
|
||||
static constexpr int length_ = numVars + 1 ;
|
||||
|
||||
//! position index for value
|
||||
static constexpr int valuepos_ = 0;
|
||||
//! start index for derivatives
|
||||
static constexpr int dstart_ = 1;
|
||||
//! end+1 index for derivatives
|
||||
static constexpr int dend_ = length_ ;
|
||||
public:
|
||||
|
||||
//! default constructor
|
||||
Evaluation() : data_()
|
||||
{}
|
||||
|
||||
//! copy other function evaluation
|
||||
Evaluation(const Evaluation& other) : data_( other.data_ )
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = b.data_[0];
|
||||
a.data_[1] = b.data_[1];
|
||||
a.data_[2] = b.data_[2];
|
||||
a.data_[3] = b.data_[3];
|
||||
a.data_[4] = b.data_[4];
|
||||
a.data_[5] = b.data_[5];
|
||||
a.data_[6] = b.data_[6];
|
||||
a.data_[7] = b.data_[7];
|
||||
a.data_[8] = b.data_[8];
|
||||
a.data_[9] = b.data_[9];
|
||||
a.data_[10] = b.data_[10];
|
||||
a.data_[11] = b.data_[11];
|
||||
a.data_[12] = b.data_[12];
|
||||
}
|
||||
|
||||
// create an evaluation which represents a constant function
|
||||
//
|
||||
// i.e., f(x) = c. this implies an evaluation with the given value and all
|
||||
// derivatives being zero.
|
||||
template <class RhsValueType>
|
||||
Evaluation(const RhsValueType& c)
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
setValue( c );
|
||||
clearDerivatives();
|
||||
Valgrind::CheckDefined( data_ );
|
||||
|
||||
a.data_[0] = - b.data_[0];
|
||||
a.data_[1] = - b.data_[1];
|
||||
a.data_[2] = - b.data_[2];
|
||||
a.data_[3] = - b.data_[3];
|
||||
a.data_[4] = - b.data_[4];
|
||||
a.data_[5] = - b.data_[5];
|
||||
a.data_[6] = - b.data_[6];
|
||||
a.data_[7] = - b.data_[7];
|
||||
a.data_[8] = - b.data_[8];
|
||||
a.data_[9] = - b.data_[9];
|
||||
a.data_[10] = - b.data_[10];
|
||||
a.data_[11] = - b.data_[11];
|
||||
a.data_[12] = - b.data_[12];
|
||||
}
|
||||
|
||||
// create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
|
||||
template <class RhsValueType>
|
||||
static Evaluation devide(const RhsValueType& a, const Evaluation& b )
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
Evaluation<ValueType, numVars> result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueType df_dg = - result.value()/b.value();
|
||||
for (int idx = dstart_; idx < dend_; ++idx) {
|
||||
result.data_[idx] = df_dg*b.data_[idx];
|
||||
}
|
||||
return result;
|
||||
|
||||
a.data_[1] = 0.0;
|
||||
a.data_[2] = 0.0;
|
||||
a.data_[3] = 0.0;
|
||||
a.data_[4] = 0.0;
|
||||
a.data_[5] = 0.0;
|
||||
a.data_[6] = 0.0;
|
||||
a.data_[7] = 0.0;
|
||||
a.data_[8] = 0.0;
|
||||
a.data_[9] = 0.0;
|
||||
a.data_[10] = 0.0;
|
||||
a.data_[11] = 0.0;
|
||||
a.data_[12] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// create an evaluation which represents a constant function
|
||||
//
|
||||
// i.e., f(x) = c. this implies an evaluation with the given value and all
|
||||
// derivatives being zero.
|
||||
template <class RhsValueType>
|
||||
Evaluation(const RhsValueType& c, int varPos)
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
setValue( c );
|
||||
clearDerivatives();
|
||||
// The variable position must be in represented by the given variable descriptor
|
||||
assert(0 <= varPos && varPos < numVars);
|
||||
|
||||
data_[varPos + dstart_] = 1.0;
|
||||
Valgrind::CheckDefined(data_);
|
||||
a.data_[0] += b.data_[0];
|
||||
a.data_[1] += b.data_[1];
|
||||
a.data_[2] += b.data_[2];
|
||||
a.data_[3] += b.data_[3];
|
||||
a.data_[4] += b.data_[4];
|
||||
a.data_[5] += b.data_[5];
|
||||
a.data_[6] += b.data_[6];
|
||||
a.data_[7] += b.data_[7];
|
||||
a.data_[8] += b.data_[8];
|
||||
a.data_[9] += b.data_[9];
|
||||
a.data_[10] += b.data_[10];
|
||||
a.data_[11] += b.data_[11];
|
||||
a.data_[12] += b.data_[12];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// set all derivatives to zero
|
||||
void clearDerivatives()
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
data_[ 1 ] = 0;
|
||||
data_[ 2 ] = 0;
|
||||
data_[ 3 ] = 0;
|
||||
data_[ 4 ] = 0;
|
||||
data_[ 5 ] = 0;
|
||||
data_[ 6 ] = 0;
|
||||
data_[ 7 ] = 0;
|
||||
data_[ 8 ] = 0;
|
||||
data_[ 9 ] = 0;
|
||||
data_[ 10 ] = 0;
|
||||
data_[ 11 ] = 0;
|
||||
data_[ 12 ] = 0;
|
||||
|
||||
a.data_[0] -= b.data_[0];
|
||||
a.data_[1] -= b.data_[1];
|
||||
a.data_[2] -= b.data_[2];
|
||||
a.data_[3] -= b.data_[3];
|
||||
a.data_[4] -= b.data_[4];
|
||||
a.data_[5] -= b.data_[5];
|
||||
a.data_[6] -= b.data_[6];
|
||||
a.data_[7] -= b.data_[7];
|
||||
a.data_[8] -= b.data_[8];
|
||||
a.data_[9] -= b.data_[9];
|
||||
a.data_[10] -= b.data_[10];
|
||||
a.data_[11] -= b.data_[11];
|
||||
a.data_[12] -= b.data_[12];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
|
||||
template <class RhsValueType>
|
||||
static Evaluation createVariable(const RhsValueType& value, int varPos)
|
||||
{
|
||||
// copy function value and set all derivatives to 0, except for the variable
|
||||
// which is represented by the value (which is set to 1.0)
|
||||
return Evaluation( value, varPos );
|
||||
}
|
||||
|
||||
// "evaluate" a constant function (i.e. a function that does not depend on the set of
|
||||
// relevant variables, f(x) = c).
|
||||
template <class RhsValueType>
|
||||
static Evaluation createConstant(const RhsValueType& value)
|
||||
{
|
||||
return Evaluation( value );
|
||||
}
|
||||
|
||||
// print the value and the derivatives of the function evaluation
|
||||
void print(std::ostream& os = std::cout) const
|
||||
{
|
||||
// print value
|
||||
os << "v: " << value() << " / d:";
|
||||
// print derivatives
|
||||
for (int varIdx = 0; varIdx < numVars; ++varIdx)
|
||||
os << " " << derivative(varIdx);
|
||||
}
|
||||
|
||||
// copy all derivatives from other
|
||||
void copyDerivatives(const Evaluation& other)
|
||||
{
|
||||
data_[ 1 ] = other.data_[ 1 ];
|
||||
data_[ 2 ] = other.data_[ 2 ];
|
||||
data_[ 3 ] = other.data_[ 3 ];
|
||||
data_[ 4 ] = other.data_[ 4 ];
|
||||
data_[ 5 ] = other.data_[ 5 ];
|
||||
data_[ 6 ] = other.data_[ 6 ];
|
||||
data_[ 7 ] = other.data_[ 7 ];
|
||||
data_[ 8 ] = other.data_[ 8 ];
|
||||
data_[ 9 ] = other.data_[ 9 ];
|
||||
data_[ 10 ] = other.data_[ 10 ];
|
||||
data_[ 11 ] = other.data_[ 11 ];
|
||||
data_[ 12 ] = other.data_[ 12 ];
|
||||
}
|
||||
|
||||
|
||||
// add value and derivatives from other to this values and derivatives
|
||||
Evaluation& operator+=(const Evaluation& other)
|
||||
{
|
||||
data_[ 0 ] += other.data_[ 0 ];
|
||||
data_[ 1 ] += other.data_[ 1 ];
|
||||
data_[ 2 ] += other.data_[ 2 ];
|
||||
data_[ 3 ] += other.data_[ 3 ];
|
||||
data_[ 4 ] += other.data_[ 4 ];
|
||||
data_[ 5 ] += other.data_[ 5 ];
|
||||
data_[ 6 ] += other.data_[ 6 ];
|
||||
data_[ 7 ] += other.data_[ 7 ];
|
||||
data_[ 8 ] += other.data_[ 8 ];
|
||||
data_[ 9 ] += other.data_[ 9 ];
|
||||
data_[ 10 ] += other.data_[ 10 ];
|
||||
data_[ 11 ] += other.data_[ 11 ];
|
||||
data_[ 12 ] += other.data_[ 12 ];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// add value from other to this values
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator+=(const RhsValueType& other)
|
||||
{
|
||||
// value is added, derivatives stay the same
|
||||
data_[valuepos_] += other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// subtract other's value and derivatives from this values
|
||||
Evaluation& operator-=(const Evaluation& other)
|
||||
{
|
||||
// value and derivatives are subtracted
|
||||
data_[ 0 ] -= other.data_[ 0 ];
|
||||
data_[ 1 ] -= other.data_[ 1 ];
|
||||
data_[ 2 ] -= other.data_[ 2 ];
|
||||
data_[ 3 ] -= other.data_[ 3 ];
|
||||
data_[ 4 ] -= other.data_[ 4 ];
|
||||
data_[ 5 ] -= other.data_[ 5 ];
|
||||
data_[ 6 ] -= other.data_[ 6 ];
|
||||
data_[ 7 ] -= other.data_[ 7 ];
|
||||
data_[ 8 ] -= other.data_[ 8 ];
|
||||
data_[ 9 ] -= other.data_[ 9 ];
|
||||
data_[ 10 ] -= other.data_[ 10 ];
|
||||
data_[ 11 ] -= other.data_[ 11 ];
|
||||
data_[ 12 ] -= other.data_[ 12 ];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// subtract other's value from this values
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator-=(const RhsValueType& other)
|
||||
{
|
||||
// for constants, values are subtracted, derivatives stay the same
|
||||
data_[ valuepos_ ] -= other;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// multiply values and apply chain rule to derivatives: (u*v)' = (v'u + u'v)
|
||||
Evaluation& operator*=(const Evaluation& other)
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueType u = value();
|
||||
const ValueType v = other.value();
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
data_[ 0 ] = u * v ;
|
||||
data_[ 1 ] = data_[ 1 ] * v + other.data_[ 1 ] * u;
|
||||
data_[ 2 ] = data_[ 2 ] * v + other.data_[ 2 ] * u;
|
||||
data_[ 3 ] = data_[ 3 ] * v + other.data_[ 3 ] * u;
|
||||
data_[ 4 ] = data_[ 4 ] * v + other.data_[ 4 ] * u;
|
||||
data_[ 5 ] = data_[ 5 ] * v + other.data_[ 5 ] * u;
|
||||
data_[ 6 ] = data_[ 6 ] * v + other.data_[ 6 ] * u;
|
||||
data_[ 7 ] = data_[ 7 ] * v + other.data_[ 7 ] * u;
|
||||
data_[ 8 ] = data_[ 8 ] * v + other.data_[ 8 ] * u;
|
||||
data_[ 9 ] = data_[ 9 ] * v + other.data_[ 9 ] * u;
|
||||
data_[ 10 ] = data_[ 10 ] * v + other.data_[ 10 ] * u;
|
||||
data_[ 11 ] = data_[ 11 ] * v + other.data_[ 11 ] * u;
|
||||
data_[ 12 ] = data_[ 12 ] * v + other.data_[ 12 ] * u;
|
||||
// value
|
||||
a.data_[0] *= v ;
|
||||
|
||||
return *this;
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v + b.data_[1] * u;
|
||||
a.data_[2] = a.data_[2]*v + b.data_[2] * u;
|
||||
a.data_[3] = a.data_[3]*v + b.data_[3] * u;
|
||||
a.data_[4] = a.data_[4]*v + b.data_[4] * u;
|
||||
a.data_[5] = a.data_[5]*v + b.data_[5] * u;
|
||||
a.data_[6] = a.data_[6]*v + b.data_[6] * u;
|
||||
a.data_[7] = a.data_[7]*v + b.data_[7] * u;
|
||||
a.data_[8] = a.data_[8]*v + b.data_[8] * u;
|
||||
a.data_[9] = a.data_[9]*v + b.data_[9] * u;
|
||||
a.data_[10] = a.data_[10]*v + b.data_[10] * u;
|
||||
a.data_[11] = a.data_[11]*v + b.data_[11] * u;
|
||||
a.data_[12] = a.data_[12]*v + b.data_[12] * u;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] *= other;
|
||||
a.data_[1] *= other;
|
||||
a.data_[2] *= other;
|
||||
a.data_[3] *= other;
|
||||
a.data_[4] *= other;
|
||||
a.data_[5] *= other;
|
||||
a.data_[6] *= other;
|
||||
a.data_[7] *= other;
|
||||
a.data_[8] *= other;
|
||||
a.data_[9] *= other;
|
||||
a.data_[10] *= other;
|
||||
a.data_[11] *= other;
|
||||
a.data_[12] *= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
// value
|
||||
a.data_[0] *= v_vv;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v_vv - b.data_[1]*u_vv;
|
||||
a.data_[2] = a.data_[2]*v_vv - b.data_[2]*u_vv;
|
||||
a.data_[3] = a.data_[3]*v_vv - b.data_[3]*u_vv;
|
||||
a.data_[4] = a.data_[4]*v_vv - b.data_[4]*u_vv;
|
||||
a.data_[5] = a.data_[5]*v_vv - b.data_[5]*u_vv;
|
||||
a.data_[6] = a.data_[6]*v_vv - b.data_[6]*u_vv;
|
||||
a.data_[7] = a.data_[7]*v_vv - b.data_[7]*u_vv;
|
||||
a.data_[8] = a.data_[8]*v_vv - b.data_[8]*u_vv;
|
||||
a.data_[9] = a.data_[9]*v_vv - b.data_[9]*u_vv;
|
||||
a.data_[10] = a.data_[10]*v_vv - b.data_[10]*u_vv;
|
||||
a.data_[11] = a.data_[11]*v_vv - b.data_[11]*u_vv;
|
||||
a.data_[12] = a.data_[12]*v_vv - b.data_[12]*u_vv;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] /= other;
|
||||
a.data_[1] /= other;
|
||||
a.data_[2] /= other;
|
||||
a.data_[3] /= other;
|
||||
a.data_[4] /= other;
|
||||
a.data_[5] /= other;
|
||||
a.data_[6] /= other;
|
||||
a.data_[7] /= other;
|
||||
a.data_[8] /= other;
|
||||
a.data_[9] /= other;
|
||||
a.data_[10] /= other;
|
||||
a.data_[11] /= other;
|
||||
a.data_[12] /= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// m(u*v)' = (v'u + u'v)
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator*=(RhsValueType other)
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b)
|
||||
{
|
||||
data_[ 0 ] *= other;
|
||||
data_[ 1 ] *= other;
|
||||
data_[ 2 ] *= other;
|
||||
data_[ 3 ] *= other;
|
||||
data_[ 4 ] *= other;
|
||||
data_[ 5 ] *= other;
|
||||
data_[ 6 ] *= other;
|
||||
data_[ 7 ] *= other;
|
||||
data_[ 8 ] *= other;
|
||||
data_[ 9 ] *= other;
|
||||
data_[ 10 ] *= other;
|
||||
data_[ 11 ] *= other;
|
||||
data_[ 12 ] *= other;
|
||||
Eval result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// m(u*v)' = (v'u + u'v)
|
||||
Evaluation& operator/=(const Evaluation& other)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u -
|
||||
// u'v)/v^2.
|
||||
const ValueType v_vv = 1.0 / other.value();
|
||||
const ValueType u_vv = value() * v_vv * v_vv;
|
||||
|
||||
data_[ 0 ] *= v_vv;
|
||||
data_[ 1 ] = data_[ 1 ] * v_vv - other.data_[ 1 ] * u_vv ;
|
||||
data_[ 2 ] = data_[ 2 ] * v_vv - other.data_[ 2 ] * u_vv ;
|
||||
data_[ 3 ] = data_[ 3 ] * v_vv - other.data_[ 3 ] * u_vv ;
|
||||
data_[ 4 ] = data_[ 4 ] * v_vv - other.data_[ 4 ] * u_vv ;
|
||||
data_[ 5 ] = data_[ 5 ] * v_vv - other.data_[ 5 ] * u_vv ;
|
||||
data_[ 6 ] = data_[ 6 ] * v_vv - other.data_[ 6 ] * u_vv ;
|
||||
data_[ 7 ] = data_[ 7 ] * v_vv - other.data_[ 7 ] * u_vv ;
|
||||
data_[ 8 ] = data_[ 8 ] * v_vv - other.data_[ 8 ] * u_vv ;
|
||||
data_[ 9 ] = data_[ 9 ] * v_vv - other.data_[ 9 ] * u_vv ;
|
||||
data_[ 10 ] = data_[ 10 ] * v_vv - other.data_[ 10 ] * u_vv ;
|
||||
data_[ 11 ] = data_[ 11 ] * v_vv - other.data_[ 11 ] * u_vv ;
|
||||
data_[ 12 ] = data_[ 12 ] * v_vv - other.data_[ 12 ] * u_vv ;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// multiply value and derivatives by value of other
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator/=(const RhsValueType& other)
|
||||
{
|
||||
// values and derivatives are divided
|
||||
ValueType factor = (1.0/other);
|
||||
data_[ 0 ] *= factor;
|
||||
data_[ 1 ] *= factor;
|
||||
data_[ 2 ] *= factor;
|
||||
data_[ 3 ] *= factor;
|
||||
data_[ 4 ] *= factor;
|
||||
data_[ 5 ] *= factor;
|
||||
data_[ 6 ] *= factor;
|
||||
data_[ 7 ] *= factor;
|
||||
data_[ 8 ] *= factor;
|
||||
data_[ 9 ] *= factor;
|
||||
data_[ 10 ] *= factor;
|
||||
data_[ 11 ] *= factor;
|
||||
data_[ 12 ] *= factor;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// add two evaluation objects
|
||||
Evaluation operator+(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result += other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// add constant to this object
|
||||
template <class RhsValueType>
|
||||
Evaluation operator+(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result += other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// subtract two evaluation objects
|
||||
Evaluation operator-(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result -= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// subtract constant from evaluation object
|
||||
template <class RhsValueType>
|
||||
Evaluation operator-(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result -= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// negation (unary minus) operator
|
||||
Evaluation operator-() const
|
||||
{
|
||||
Evaluation result;
|
||||
// set value and derivatives to negative
|
||||
for (int idx = 0; idx < length_; ++idx)
|
||||
result.data_[idx] = - data_[idx];
|
||||
result.data_[1] = df_dg*b.data_[1];
|
||||
result.data_[2] = df_dg*b.data_[2];
|
||||
result.data_[3] = df_dg*b.data_[3];
|
||||
result.data_[4] = df_dg*b.data_[4];
|
||||
result.data_[5] = df_dg*b.data_[5];
|
||||
result.data_[6] = df_dg*b.data_[6];
|
||||
result.data_[7] = df_dg*b.data_[7];
|
||||
result.data_[8] = df_dg*b.data_[8];
|
||||
result.data_[9] = df_dg*b.data_[9];
|
||||
result.data_[10] = df_dg*b.data_[10];
|
||||
result.data_[11] = df_dg*b.data_[11];
|
||||
result.data_[12] = df_dg*b.data_[12];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Evaluation operator*(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result *= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation operator*(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result *= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
Evaluation operator/(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result /= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation operator/(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result /= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator=(const RhsValueType& other)
|
||||
{
|
||||
setValue( other );
|
||||
clearDerivatives();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy assignment from evaluation
|
||||
Evaluation& operator=(const Evaluation& other)
|
||||
{
|
||||
data_ = other.data_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator==(const RhsValueType& other) const
|
||||
{ return value() == other; }
|
||||
|
||||
bool operator==(const Evaluation& other) const
|
||||
{
|
||||
for (int idx = 0; idx < length_; ++idx)
|
||||
if (data_[idx] != other.data_[idx])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const Evaluation& other) const
|
||||
{ return !operator==(other); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator>(RhsValueType other) const
|
||||
{ return value() > other; }
|
||||
|
||||
bool operator>(const Evaluation& other) const
|
||||
{ return value() > other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator<(RhsValueType other) const
|
||||
{ return value() < other; }
|
||||
|
||||
bool operator<(const Evaluation& other) const
|
||||
{ return value() < other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator>=(RhsValueType other) const
|
||||
{ return value() >= other; }
|
||||
|
||||
bool operator>=(const Evaluation& other) const
|
||||
{ return value() >= other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator<=(RhsValueType other) const
|
||||
{ return value() <= other; }
|
||||
|
||||
bool operator<=(const Evaluation& other) const
|
||||
{ return value() <= other.value(); }
|
||||
|
||||
// return value of variable
|
||||
const ValueType& value() const
|
||||
{ return data_[valuepos_]; }
|
||||
|
||||
// set value of variable
|
||||
void setValue(const ValueType& val)
|
||||
{ data_[valuepos_] = val; }
|
||||
|
||||
// return varIdx'th derivative
|
||||
const ValueType& derivative(int varIdx) const
|
||||
{
|
||||
assert(varIdx < numVars);
|
||||
return data_[varIdx + dstart_];
|
||||
}
|
||||
|
||||
// set derivative at position varIdx
|
||||
void setDerivative(int varIdx, const ValueType& derVal)
|
||||
{
|
||||
assert(varIdx < numVars);
|
||||
data_[varIdx + dstart_] = derVal;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::array<ValueType, length_> data_;
|
||||
};
|
||||
|
||||
} // namespace DenseAD
|
||||
} // namespace Dune
|
||||
} } // namespace DenseAd, Opm
|
||||
|
||||
// #include <opm/material/densead/EvaluationSIMD.hpp>
|
||||
|
||||
#endif
|
||||
#endif // OPM_DENSEAD_EVALUATION12_HPP
|
@ -23,403 +23,138 @@
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Representation of an evaluation of a function and its derivatives w.r.t. a set
|
||||
* of variables in the localized OPM automatic differentiation (AD) framework.
|
||||
* \brief This file specializes the dense-AD Evaluation class for 2 derivatives.
|
||||
*
|
||||
* \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
|
||||
#ifndef OPM_LOCAL_AD_EVALUATION_2_HPP
|
||||
#define OPM_LOCAL_AD_EVALUATION_2_HPP
|
||||
|
||||
#include "Math.hpp"
|
||||
|
||||
#include <opm/common/Valgrind.hpp>
|
||||
|
||||
#include <dune/common/version.hh>
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#ifndef OPM_DENSEAD_EVALUATION2_HPP
|
||||
#define OPM_DENSEAD_EVALUATION2_HPP
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
/*!
|
||||
* \brief Represents a function evaluation and its derivatives w.r.t. a fixed set of
|
||||
* variables.
|
||||
*/
|
||||
|
||||
template <class ValueT>
|
||||
class Evaluation< ValueT, 2 >
|
||||
struct EvaluationOps<ValueT, 2>
|
||||
{
|
||||
static constexpr int numVars = 2;
|
||||
private:
|
||||
typedef Evaluation<ValueT, 2 > Eval;
|
||||
|
||||
public:
|
||||
//! field type
|
||||
typedef ValueT ValueType;
|
||||
typedef std::array<ValueT, 3 > DataVector;
|
||||
|
||||
//! number of derivatives
|
||||
static constexpr int size = numVars;
|
||||
|
||||
protected:
|
||||
//! length of internal data vector
|
||||
static constexpr int length_ = numVars + 1 ;
|
||||
|
||||
//! position index for value
|
||||
static constexpr int valuepos_ = 0;
|
||||
//! start index for derivatives
|
||||
static constexpr int dstart_ = 1;
|
||||
//! end+1 index for derivatives
|
||||
static constexpr int dend_ = length_ ;
|
||||
public:
|
||||
|
||||
//! default constructor
|
||||
Evaluation() : data_()
|
||||
{}
|
||||
|
||||
//! copy other function evaluation
|
||||
Evaluation(const Evaluation& other) : data_( other.data_ )
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = b.data_[0];
|
||||
a.data_[1] = b.data_[1];
|
||||
a.data_[2] = b.data_[2];
|
||||
}
|
||||
|
||||
// create an evaluation which represents a constant function
|
||||
//
|
||||
// i.e., f(x) = c. this implies an evaluation with the given value and all
|
||||
// derivatives being zero.
|
||||
template <class RhsValueType>
|
||||
Evaluation(const RhsValueType& c)
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
setValue( c );
|
||||
clearDerivatives();
|
||||
Valgrind::CheckDefined( data_ );
|
||||
|
||||
a.data_[0] = - b.data_[0];
|
||||
a.data_[1] = - b.data_[1];
|
||||
a.data_[2] = - b.data_[2];
|
||||
}
|
||||
|
||||
// create an evaluation which represents a constant function
|
||||
//
|
||||
// i.e., f(x) = c. this implies an evaluation with the given value and all
|
||||
// derivatives being zero.
|
||||
template <class RhsValueType>
|
||||
Evaluation(const RhsValueType& c, int varPos)
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
setValue( c );
|
||||
clearDerivatives();
|
||||
// The variable position must be in represented by the given variable descriptor
|
||||
assert(0 <= varPos && varPos < numVars);
|
||||
|
||||
data_[varPos + dstart_] = 1.0;
|
||||
Valgrind::CheckDefined(data_);
|
||||
a.data_[1] = 0.0;
|
||||
a.data_[2] = 0.0;
|
||||
}
|
||||
|
||||
// set all derivatives to zero
|
||||
void clearDerivatives()
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
data_[ 1 ] = 0;
|
||||
data_[ 2 ] = 0;
|
||||
|
||||
a.data_[0] += b.data_[0];
|
||||
a.data_[1] += b.data_[1];
|
||||
a.data_[2] += b.data_[2];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
|
||||
template <class RhsValueType>
|
||||
static Evaluation devide(const RhsValueType& a, const Evaluation& b )
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
Evaluation<ValueType, numVars> result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueType df_dg = - result.value()/b.value();
|
||||
for (int idx = dstart_; idx < dend_; ++idx) {
|
||||
result.data_[idx] = df_dg*b.data_[idx];
|
||||
}
|
||||
return result;
|
||||
|
||||
a.data_[0] -= b.data_[0];
|
||||
a.data_[1] -= b.data_[1];
|
||||
a.data_[2] -= b.data_[2];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
|
||||
template <class RhsValueType>
|
||||
static Evaluation createVariable(const RhsValueType& value, int varPos)
|
||||
{
|
||||
// copy function value and set all derivatives to 0, except for the variable
|
||||
// which is represented by the value (which is set to 1.0)
|
||||
return Evaluation( value, varPos );
|
||||
}
|
||||
|
||||
// "evaluate" a constant function (i.e. a function that does not depend on the set of
|
||||
// relevant variables, f(x) = c).
|
||||
template <class RhsValueType>
|
||||
static Evaluation createConstant(const RhsValueType& value)
|
||||
{
|
||||
return Evaluation( value );
|
||||
}
|
||||
|
||||
// print the value and the derivatives of the function evaluation
|
||||
void print(std::ostream& os = std::cout) const
|
||||
{
|
||||
// print value
|
||||
os << "v: " << value() << " / d:";
|
||||
// print derivatives
|
||||
for (int varIdx = 0; varIdx < numVars; ++varIdx)
|
||||
os << " " << derivative(varIdx);
|
||||
}
|
||||
|
||||
// copy all derivatives from other
|
||||
void copyDerivatives(const Evaluation& other)
|
||||
{
|
||||
data_[ 1 ] = other.data_[ 1 ];
|
||||
data_[ 2 ] = other.data_[ 2 ];
|
||||
}
|
||||
|
||||
|
||||
// add value and derivatives from other to this values and derivatives
|
||||
Evaluation& operator+=(const Evaluation& other)
|
||||
{
|
||||
data_[ 0 ] += other.data_[ 0 ];
|
||||
data_[ 1 ] += other.data_[ 1 ];
|
||||
data_[ 2 ] += other.data_[ 2 ];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// add value from other to this values
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator+=(const RhsValueType& other)
|
||||
{
|
||||
// value is added, derivatives stay the same
|
||||
data_[valuepos_] += other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// subtract other's value and derivatives from this values
|
||||
Evaluation& operator-=(const Evaluation& other)
|
||||
{
|
||||
// value and derivatives are subtracted
|
||||
data_[ 0 ] -= other.data_[ 0 ];
|
||||
data_[ 1 ] -= other.data_[ 1 ];
|
||||
data_[ 2 ] -= other.data_[ 2 ];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// subtract other's value from this values
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator-=(const RhsValueType& other)
|
||||
{
|
||||
// for constants, values are subtracted, derivatives stay the same
|
||||
data_[ valuepos_ ] -= other;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// multiply values and apply chain rule to derivatives: (u*v)' = (v'u + u'v)
|
||||
Evaluation& operator*=(const Evaluation& other)
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueType u = value();
|
||||
const ValueType v = other.value();
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
data_[ 0 ] = u * v ;
|
||||
data_[ 1 ] = data_[ 1 ] * v + other.data_[ 1 ] * u;
|
||||
data_[ 2 ] = data_[ 2 ] * v + other.data_[ 2 ] * u;
|
||||
// value
|
||||
a.data_[0] *= v ;
|
||||
|
||||
return *this;
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v + b.data_[1] * u;
|
||||
a.data_[2] = a.data_[2]*v + b.data_[2] * u;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] *= other;
|
||||
a.data_[1] *= other;
|
||||
a.data_[2] *= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
// value
|
||||
a.data_[0] *= v_vv;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v_vv - b.data_[1]*u_vv;
|
||||
a.data_[2] = a.data_[2]*v_vv - b.data_[2]*u_vv;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] /= other;
|
||||
a.data_[1] /= other;
|
||||
a.data_[2] /= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// m(u*v)' = (v'u + u'v)
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator*=(RhsValueType other)
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b)
|
||||
{
|
||||
data_[ 0 ] *= other;
|
||||
data_[ 1 ] *= other;
|
||||
data_[ 2 ] *= other;
|
||||
return *this;
|
||||
}
|
||||
Eval result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
|
||||
// m(u*v)' = (v'u + u'v)
|
||||
Evaluation& operator/=(const Evaluation& other)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u -
|
||||
// u'v)/v^2.
|
||||
const ValueType v_vv = 1.0 / other.value();
|
||||
const ValueType u_vv = value() * v_vv * v_vv;
|
||||
|
||||
data_[ 0 ] *= v_vv;
|
||||
data_[ 1 ] = data_[ 1 ] * v_vv - other.data_[ 1 ] * u_vv ;
|
||||
data_[ 2 ] = data_[ 2 ] * v_vv - other.data_[ 2 ] * u_vv ;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// multiply value and derivatives by value of other
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator/=(const RhsValueType& other)
|
||||
{
|
||||
// values and derivatives are divided
|
||||
ValueType factor = (1.0/other);
|
||||
data_[ 0 ] *= factor;
|
||||
data_[ 1 ] *= factor;
|
||||
data_[ 2 ] *= factor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// add two evaluation objects
|
||||
Evaluation operator+(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result += other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// add constant to this object
|
||||
template <class RhsValueType>
|
||||
Evaluation operator+(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result += other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// subtract two evaluation objects
|
||||
Evaluation operator-(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result -= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// subtract constant from evaluation object
|
||||
template <class RhsValueType>
|
||||
Evaluation operator-(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result -= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// negation (unary minus) operator
|
||||
Evaluation operator-() const
|
||||
{
|
||||
Evaluation result;
|
||||
// set value and derivatives to negative
|
||||
for (int idx = 0; idx < length_; ++idx)
|
||||
result.data_[idx] = - data_[idx];
|
||||
result.data_[1] = df_dg*b.data_[1];
|
||||
result.data_[2] = df_dg*b.data_[2];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Evaluation operator*(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result *= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation operator*(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result *= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
Evaluation operator/(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result /= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation operator/(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result /= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator=(const RhsValueType& other)
|
||||
{
|
||||
setValue( other );
|
||||
clearDerivatives();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy assignment from evaluation
|
||||
Evaluation& operator=(const Evaluation& other)
|
||||
{
|
||||
data_ = other.data_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator==(const RhsValueType& other) const
|
||||
{ return value() == other; }
|
||||
|
||||
bool operator==(const Evaluation& other) const
|
||||
{
|
||||
for (int idx = 0; idx < length_; ++idx)
|
||||
if (data_[idx] != other.data_[idx])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const Evaluation& other) const
|
||||
{ return !operator==(other); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator>(RhsValueType other) const
|
||||
{ return value() > other; }
|
||||
|
||||
bool operator>(const Evaluation& other) const
|
||||
{ return value() > other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator<(RhsValueType other) const
|
||||
{ return value() < other; }
|
||||
|
||||
bool operator<(const Evaluation& other) const
|
||||
{ return value() < other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator>=(RhsValueType other) const
|
||||
{ return value() >= other; }
|
||||
|
||||
bool operator>=(const Evaluation& other) const
|
||||
{ return value() >= other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator<=(RhsValueType other) const
|
||||
{ return value() <= other; }
|
||||
|
||||
bool operator<=(const Evaluation& other) const
|
||||
{ return value() <= other.value(); }
|
||||
|
||||
// return value of variable
|
||||
const ValueType& value() const
|
||||
{ return data_[valuepos_]; }
|
||||
|
||||
// set value of variable
|
||||
void setValue(const ValueType& val)
|
||||
{ data_[valuepos_] = val; }
|
||||
|
||||
// return varIdx'th derivative
|
||||
const ValueType& derivative(int varIdx) const
|
||||
{
|
||||
assert(varIdx < numVars);
|
||||
return data_[varIdx + dstart_];
|
||||
}
|
||||
|
||||
// set derivative at position varIdx
|
||||
void setDerivative(int varIdx, const ValueType& derVal)
|
||||
{
|
||||
assert(varIdx < numVars);
|
||||
data_[varIdx + dstart_] = derVal;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::array<ValueType, length_> data_;
|
||||
};
|
||||
|
||||
} // namespace DenseAD
|
||||
} // namespace Dune
|
||||
} } // namespace DenseAd, Opm
|
||||
|
||||
// #include <opm/material/densead/EvaluationSIMD.hpp>
|
||||
|
||||
#endif
|
||||
#endif // OPM_DENSEAD_EVALUATION2_HPP
|
@ -23,413 +23,148 @@
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Representation of an evaluation of a function and its derivatives w.r.t. a set
|
||||
* of variables in the localized OPM automatic differentiation (AD) framework.
|
||||
* \brief This file specializes the dense-AD Evaluation class for 3 derivatives.
|
||||
*
|
||||
* \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
|
||||
#ifndef OPM_LOCAL_AD_EVALUATION_3_HPP
|
||||
#define OPM_LOCAL_AD_EVALUATION_3_HPP
|
||||
|
||||
#include "Math.hpp"
|
||||
|
||||
#include <opm/common/Valgrind.hpp>
|
||||
|
||||
#include <dune/common/version.hh>
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#ifndef OPM_DENSEAD_EVALUATION3_HPP
|
||||
#define OPM_DENSEAD_EVALUATION3_HPP
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
/*!
|
||||
* \brief Represents a function evaluation and its derivatives w.r.t. a fixed set of
|
||||
* variables.
|
||||
*/
|
||||
|
||||
template <class ValueT>
|
||||
class Evaluation< ValueT, 3 >
|
||||
struct EvaluationOps<ValueT, 3>
|
||||
{
|
||||
static constexpr int numVars = 3;
|
||||
private:
|
||||
typedef Evaluation<ValueT, 3 > Eval;
|
||||
|
||||
public:
|
||||
//! field type
|
||||
typedef ValueT ValueType;
|
||||
typedef std::array<ValueT, 4 > DataVector;
|
||||
|
||||
//! number of derivatives
|
||||
static constexpr int size = numVars;
|
||||
|
||||
protected:
|
||||
//! length of internal data vector
|
||||
static constexpr int length_ = numVars + 1 ;
|
||||
|
||||
//! position index for value
|
||||
static constexpr int valuepos_ = 0;
|
||||
//! start index for derivatives
|
||||
static constexpr int dstart_ = 1;
|
||||
//! end+1 index for derivatives
|
||||
static constexpr int dend_ = length_ ;
|
||||
public:
|
||||
|
||||
//! default constructor
|
||||
Evaluation() : data_()
|
||||
{}
|
||||
|
||||
//! copy other function evaluation
|
||||
Evaluation(const Evaluation& other) //: data_( other.data_ )
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
data_[ 0 ] = other.data_[ 0 ];
|
||||
data_[ 1 ] = other.data_[ 1 ];
|
||||
data_[ 2 ] = other.data_[ 2 ];
|
||||
data_[ 3 ] = other.data_[ 3 ];
|
||||
|
||||
a.data_[0] = b.data_[0];
|
||||
a.data_[1] = b.data_[1];
|
||||
a.data_[2] = b.data_[2];
|
||||
a.data_[3] = b.data_[3];
|
||||
}
|
||||
|
||||
// create an evaluation which represents a constant function
|
||||
//
|
||||
// i.e., f(x) = c. this implies an evaluation with the given value and all
|
||||
// derivatives being zero.
|
||||
template <class RhsValueType>
|
||||
Evaluation(const RhsValueType& c)
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
setValue( c );
|
||||
clearDerivatives();
|
||||
Valgrind::CheckDefined( data_ );
|
||||
|
||||
a.data_[0] = - b.data_[0];
|
||||
a.data_[1] = - b.data_[1];
|
||||
a.data_[2] = - b.data_[2];
|
||||
a.data_[3] = - b.data_[3];
|
||||
}
|
||||
|
||||
// create an evaluation which represents a constant function
|
||||
//
|
||||
// i.e., f(x) = c. this implies an evaluation with the given value and all
|
||||
// derivatives being zero.
|
||||
template <class RhsValueType>
|
||||
Evaluation(const RhsValueType& c, int varPos)
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
setValue( c );
|
||||
clearDerivatives();
|
||||
// The variable position must be in represented by the given variable descriptor
|
||||
assert(0 <= varPos && varPos < numVars);
|
||||
|
||||
data_[varPos + dstart_] = 1.0;
|
||||
Valgrind::CheckDefined(data_);
|
||||
a.data_[1] = 0.0;
|
||||
a.data_[2] = 0.0;
|
||||
a.data_[3] = 0.0;
|
||||
}
|
||||
|
||||
// set all derivatives to zero
|
||||
void clearDerivatives()
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
data_[ 1 ] = 0;
|
||||
data_[ 2 ] = 0;
|
||||
data_[ 3 ] = 0;
|
||||
|
||||
a.data_[0] += b.data_[0];
|
||||
a.data_[1] += b.data_[1];
|
||||
a.data_[2] += b.data_[2];
|
||||
a.data_[3] += b.data_[3];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
// create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
|
||||
template <class RhsValueType>
|
||||
static Evaluation devide(const RhsValueType& a, const Evaluation& b )
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
Evaluation<ValueType, numVars> result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueType df_dg = - result.value()/b.value();
|
||||
result.data_[ 1 ] = df_dg*b.data_[ 1 ];
|
||||
result.data_[ 2 ] = df_dg*b.data_[ 2 ];
|
||||
result.data_[ 3 ] = df_dg*b.data_[ 3 ];
|
||||
return result;
|
||||
|
||||
a.data_[0] -= b.data_[0];
|
||||
a.data_[1] -= b.data_[1];
|
||||
a.data_[2] -= b.data_[2];
|
||||
a.data_[3] -= b.data_[3];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
|
||||
template <class RhsValueType>
|
||||
static Evaluation createVariable(const RhsValueType& value, int varPos)
|
||||
{
|
||||
// copy function value and set all derivatives to 0, except for the variable
|
||||
// which is represented by the value (which is set to 1.0)
|
||||
return Evaluation( value, varPos );
|
||||
}
|
||||
|
||||
// "evaluate" a constant function (i.e. a function that does not depend on the set of
|
||||
// relevant variables, f(x) = c).
|
||||
template <class RhsValueType>
|
||||
static Evaluation createConstant(const RhsValueType& value)
|
||||
{
|
||||
return Evaluation( value );
|
||||
}
|
||||
|
||||
// print the value and the derivatives of the function evaluation
|
||||
void print(std::ostream& os = std::cout) const
|
||||
{
|
||||
// print value
|
||||
os << "v: " << value() << " / d:";
|
||||
// print derivatives
|
||||
for (int varIdx = 0; varIdx < numVars; ++varIdx)
|
||||
os << " " << derivative(varIdx);
|
||||
}
|
||||
|
||||
// copy all derivatives from other
|
||||
void copyDerivatives(const Evaluation& other)
|
||||
{
|
||||
data_[ 1 ] = other.data_[ 1 ];
|
||||
data_[ 2 ] = other.data_[ 2 ];
|
||||
data_[ 3 ] = other.data_[ 3 ];
|
||||
}
|
||||
|
||||
|
||||
// add value and derivatives from other to this values and derivatives
|
||||
Evaluation& operator+=(const Evaluation& other)
|
||||
{
|
||||
data_[ 0 ] += other.data_[ 0 ];
|
||||
data_[ 1 ] += other.data_[ 1 ];
|
||||
data_[ 2 ] += other.data_[ 2 ];
|
||||
data_[ 3 ] += other.data_[ 3 ];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// add value from other to this values
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator+=(const RhsValueType& other)
|
||||
{
|
||||
// value is added, derivatives stay the same
|
||||
data_[valuepos_] += other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// subtract other's value and derivatives from this values
|
||||
Evaluation& operator-=(const Evaluation& other)
|
||||
{
|
||||
// value and derivatives are subtracted
|
||||
data_[ 0 ] -= other.data_[ 0 ];
|
||||
data_[ 1 ] -= other.data_[ 1 ];
|
||||
data_[ 2 ] -= other.data_[ 2 ];
|
||||
data_[ 3 ] -= other.data_[ 3 ];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// subtract other's value from this values
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator-=(const RhsValueType& other)
|
||||
{
|
||||
// for constants, values are subtracted, derivatives stay the same
|
||||
data_[ valuepos_ ] -= other;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// multiply values and apply chain rule to derivatives: (u*v)' = (v'u + u'v)
|
||||
Evaluation& operator*=(const Evaluation& other)
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueType u = value();
|
||||
const ValueType v = other.value();
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
data_[ 0 ] *= v ;
|
||||
data_[ 1 ] = data_[ 1 ] * v + other.data_[ 1 ] * u;
|
||||
data_[ 2 ] = data_[ 2 ] * v + other.data_[ 2 ] * u;
|
||||
data_[ 3 ] = data_[ 3 ] * v + other.data_[ 3 ] * u;
|
||||
// value
|
||||
a.data_[0] *= v ;
|
||||
|
||||
return *this;
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v + b.data_[1] * u;
|
||||
a.data_[2] = a.data_[2]*v + b.data_[2] * u;
|
||||
a.data_[3] = a.data_[3]*v + b.data_[3] * u;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] *= other;
|
||||
a.data_[1] *= other;
|
||||
a.data_[2] *= other;
|
||||
a.data_[3] *= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
// value
|
||||
a.data_[0] *= v_vv;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v_vv - b.data_[1]*u_vv;
|
||||
a.data_[2] = a.data_[2]*v_vv - b.data_[2]*u_vv;
|
||||
a.data_[3] = a.data_[3]*v_vv - b.data_[3]*u_vv;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] /= other;
|
||||
a.data_[1] /= other;
|
||||
a.data_[2] /= other;
|
||||
a.data_[3] /= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// m(u*v)' = (v'u + u'v)
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator*=(RhsValueType other)
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b)
|
||||
{
|
||||
data_[ 0 ] *= other;
|
||||
data_[ 1 ] *= other;
|
||||
data_[ 2 ] *= other;
|
||||
data_[ 3 ] *= other;
|
||||
Eval result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// m(u*v)' = (v'u + u'v)
|
||||
Evaluation& operator/=(const Evaluation& other)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u -
|
||||
// u'v)/v^2.
|
||||
const ValueType v_vv = 1.0 / other.value();
|
||||
const ValueType u_vv = value() * v_vv * v_vv;
|
||||
|
||||
data_[ 0 ] *= v_vv;
|
||||
data_[ 1 ] = data_[ 1 ] * v_vv - other.data_[ 1 ] * u_vv ;
|
||||
data_[ 2 ] = data_[ 2 ] * v_vv - other.data_[ 2 ] * u_vv ;
|
||||
data_[ 3 ] = data_[ 3 ] * v_vv - other.data_[ 3 ] * u_vv ;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// multiply value and derivatives by value of other
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator/=(const RhsValueType& other)
|
||||
{
|
||||
// values and derivatives are divided
|
||||
const ValueType factor = (1.0/other);
|
||||
return this->operator*=( factor );
|
||||
}
|
||||
|
||||
// add two evaluation objects
|
||||
Evaluation operator+(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result += other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// add constant to this object
|
||||
template <class RhsValueType>
|
||||
Evaluation operator+(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result += other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// subtract two evaluation objects
|
||||
Evaluation operator-(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result -= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// subtract constant from evaluation object
|
||||
template <class RhsValueType>
|
||||
Evaluation operator-(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result -= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// negation (unary minus) operator
|
||||
Evaluation operator-() const
|
||||
{
|
||||
Evaluation result;
|
||||
// set value and derivatives to negative
|
||||
for (int idx = 0; idx < length_; ++idx)
|
||||
result.data_[idx] = - data_[idx];
|
||||
result.data_[1] = df_dg*b.data_[1];
|
||||
result.data_[2] = df_dg*b.data_[2];
|
||||
result.data_[3] = df_dg*b.data_[3];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Evaluation operator*(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result *= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation operator*(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result *= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
Evaluation operator/(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result /= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation operator/(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result /= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator=(const RhsValueType& other)
|
||||
{
|
||||
setValue( other );
|
||||
clearDerivatives();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy assignment from evaluation
|
||||
Evaluation& operator=(const Evaluation& other)
|
||||
{
|
||||
data_ = other.data_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator==(const RhsValueType& other) const
|
||||
{ return value() == other; }
|
||||
|
||||
bool operator==(const Evaluation& other) const
|
||||
{
|
||||
for (int idx = 0; idx < length_; ++idx)
|
||||
if (data_[idx] != other.data_[idx])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const Evaluation& other) const
|
||||
{ return !operator==(other); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator>(const RhsValueType& other) const
|
||||
{ return value() > other; }
|
||||
|
||||
bool operator>(const Evaluation& other) const
|
||||
{ return value() > other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator<(const RhsValueType& other) const
|
||||
{ return value() < other; }
|
||||
|
||||
bool operator<(const Evaluation& other) const
|
||||
{ return value() < other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator>=(const RhsValueType& other) const
|
||||
{ return value() >= other; }
|
||||
|
||||
bool operator>=(const Evaluation& other) const
|
||||
{ return value() >= other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator<=(const RhsValueType& other) const
|
||||
{ return value() <= other; }
|
||||
|
||||
bool operator<=(const Evaluation& other) const
|
||||
{ return value() <= other.value(); }
|
||||
|
||||
// return value of variable
|
||||
const ValueType& value() const
|
||||
{ return data_[valuepos_]; }
|
||||
|
||||
// set value of variable
|
||||
void setValue(const ValueType& val)
|
||||
{ data_[valuepos_] = val; }
|
||||
|
||||
// return varIdx'th derivative
|
||||
const ValueType& derivative(int varIdx) const
|
||||
{
|
||||
assert(varIdx < numVars);
|
||||
return data_[varIdx + dstart_];
|
||||
}
|
||||
|
||||
// set derivative at position varIdx
|
||||
void setDerivative(int varIdx, const ValueType& derVal)
|
||||
{
|
||||
assert(varIdx < numVars);
|
||||
data_[varIdx + dstart_] = derVal;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::array<ValueType, length_> data_;
|
||||
};
|
||||
|
||||
} // namespace DenseAD
|
||||
} // namespace Dune
|
||||
} } // namespace DenseAd, Opm
|
||||
|
||||
// #include <opm/material/densead/EvaluationSIMD.hpp>
|
||||
|
||||
#endif
|
||||
#endif // OPM_DENSEAD_EVALUATION3_HPP
|
180
opm/material/densead/Evaluation4.hpp
Normal file
180
opm/material/densead/Evaluation4.hpp
Normal file
@ -0,0 +1,180 @@
|
||||
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
// vi: set et ts=4 sw=4 sts=4:
|
||||
/*
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Consult the COPYING file in the top-level source directory of this
|
||||
module for the precise wording of the license and the list of
|
||||
copyright holders.
|
||||
*/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief This file specializes the dense-AD Evaluation class for 4 derivatives.
|
||||
*
|
||||
* \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
#ifndef OPM_DENSEAD_EVALUATION4_HPP
|
||||
#define OPM_DENSEAD_EVALUATION4_HPP
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
|
||||
template <class ValueT>
|
||||
struct EvaluationOps<ValueT, 4>
|
||||
{
|
||||
private:
|
||||
typedef Evaluation<ValueT, 4 > Eval;
|
||||
|
||||
public:
|
||||
typedef std::array<ValueT, 5 > DataVector;
|
||||
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = b.data_[0];
|
||||
a.data_[1] = b.data_[1];
|
||||
a.data_[2] = b.data_[2];
|
||||
a.data_[3] = b.data_[3];
|
||||
a.data_[4] = b.data_[4];
|
||||
}
|
||||
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = - b.data_[0];
|
||||
a.data_[1] = - b.data_[1];
|
||||
a.data_[2] = - b.data_[2];
|
||||
a.data_[3] = - b.data_[3];
|
||||
a.data_[4] = - b.data_[4];
|
||||
}
|
||||
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
|
||||
a.data_[1] = 0.0;
|
||||
a.data_[2] = 0.0;
|
||||
a.data_[3] = 0.0;
|
||||
a.data_[4] = 0.0;
|
||||
}
|
||||
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] += b.data_[0];
|
||||
a.data_[1] += b.data_[1];
|
||||
a.data_[2] += b.data_[2];
|
||||
a.data_[3] += b.data_[3];
|
||||
a.data_[4] += b.data_[4];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] -= b.data_[0];
|
||||
a.data_[1] -= b.data_[1];
|
||||
a.data_[2] -= b.data_[2];
|
||||
a.data_[3] -= b.data_[3];
|
||||
a.data_[4] -= b.data_[4];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
// value
|
||||
a.data_[0] *= v ;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v + b.data_[1] * u;
|
||||
a.data_[2] = a.data_[2]*v + b.data_[2] * u;
|
||||
a.data_[3] = a.data_[3]*v + b.data_[3] * u;
|
||||
a.data_[4] = a.data_[4]*v + b.data_[4] * u;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] *= other;
|
||||
a.data_[1] *= other;
|
||||
a.data_[2] *= other;
|
||||
a.data_[3] *= other;
|
||||
a.data_[4] *= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
// value
|
||||
a.data_[0] *= v_vv;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v_vv - b.data_[1]*u_vv;
|
||||
a.data_[2] = a.data_[2]*v_vv - b.data_[2]*u_vv;
|
||||
a.data_[3] = a.data_[3]*v_vv - b.data_[3]*u_vv;
|
||||
a.data_[4] = a.data_[4]*v_vv - b.data_[4]*u_vv;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] /= other;
|
||||
a.data_[1] /= other;
|
||||
a.data_[2] /= other;
|
||||
a.data_[3] /= other;
|
||||
a.data_[4] /= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b)
|
||||
{
|
||||
Eval result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
|
||||
result.data_[1] = df_dg*b.data_[1];
|
||||
result.data_[2] = df_dg*b.data_[2];
|
||||
result.data_[3] = df_dg*b.data_[3];
|
||||
result.data_[4] = df_dg*b.data_[4];
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} } // namespace DenseAd, Opm
|
||||
|
||||
#endif // OPM_DENSEAD_EVALUATION4_HPP
|
190
opm/material/densead/Evaluation5.hpp
Normal file
190
opm/material/densead/Evaluation5.hpp
Normal file
@ -0,0 +1,190 @@
|
||||
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
// vi: set et ts=4 sw=4 sts=4:
|
||||
/*
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Consult the COPYING file in the top-level source directory of this
|
||||
module for the precise wording of the license and the list of
|
||||
copyright holders.
|
||||
*/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief This file specializes the dense-AD Evaluation class for 5 derivatives.
|
||||
*
|
||||
* \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
#ifndef OPM_DENSEAD_EVALUATION5_HPP
|
||||
#define OPM_DENSEAD_EVALUATION5_HPP
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
|
||||
template <class ValueT>
|
||||
struct EvaluationOps<ValueT, 5>
|
||||
{
|
||||
private:
|
||||
typedef Evaluation<ValueT, 5 > Eval;
|
||||
|
||||
public:
|
||||
typedef std::array<ValueT, 6 > DataVector;
|
||||
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = b.data_[0];
|
||||
a.data_[1] = b.data_[1];
|
||||
a.data_[2] = b.data_[2];
|
||||
a.data_[3] = b.data_[3];
|
||||
a.data_[4] = b.data_[4];
|
||||
a.data_[5] = b.data_[5];
|
||||
}
|
||||
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = - b.data_[0];
|
||||
a.data_[1] = - b.data_[1];
|
||||
a.data_[2] = - b.data_[2];
|
||||
a.data_[3] = - b.data_[3];
|
||||
a.data_[4] = - b.data_[4];
|
||||
a.data_[5] = - b.data_[5];
|
||||
}
|
||||
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
|
||||
a.data_[1] = 0.0;
|
||||
a.data_[2] = 0.0;
|
||||
a.data_[3] = 0.0;
|
||||
a.data_[4] = 0.0;
|
||||
a.data_[5] = 0.0;
|
||||
}
|
||||
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] += b.data_[0];
|
||||
a.data_[1] += b.data_[1];
|
||||
a.data_[2] += b.data_[2];
|
||||
a.data_[3] += b.data_[3];
|
||||
a.data_[4] += b.data_[4];
|
||||
a.data_[5] += b.data_[5];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] -= b.data_[0];
|
||||
a.data_[1] -= b.data_[1];
|
||||
a.data_[2] -= b.data_[2];
|
||||
a.data_[3] -= b.data_[3];
|
||||
a.data_[4] -= b.data_[4];
|
||||
a.data_[5] -= b.data_[5];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
// value
|
||||
a.data_[0] *= v ;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v + b.data_[1] * u;
|
||||
a.data_[2] = a.data_[2]*v + b.data_[2] * u;
|
||||
a.data_[3] = a.data_[3]*v + b.data_[3] * u;
|
||||
a.data_[4] = a.data_[4]*v + b.data_[4] * u;
|
||||
a.data_[5] = a.data_[5]*v + b.data_[5] * u;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] *= other;
|
||||
a.data_[1] *= other;
|
||||
a.data_[2] *= other;
|
||||
a.data_[3] *= other;
|
||||
a.data_[4] *= other;
|
||||
a.data_[5] *= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
// value
|
||||
a.data_[0] *= v_vv;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v_vv - b.data_[1]*u_vv;
|
||||
a.data_[2] = a.data_[2]*v_vv - b.data_[2]*u_vv;
|
||||
a.data_[3] = a.data_[3]*v_vv - b.data_[3]*u_vv;
|
||||
a.data_[4] = a.data_[4]*v_vv - b.data_[4]*u_vv;
|
||||
a.data_[5] = a.data_[5]*v_vv - b.data_[5]*u_vv;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] /= other;
|
||||
a.data_[1] /= other;
|
||||
a.data_[2] /= other;
|
||||
a.data_[3] /= other;
|
||||
a.data_[4] /= other;
|
||||
a.data_[5] /= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b)
|
||||
{
|
||||
Eval result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
|
||||
result.data_[1] = df_dg*b.data_[1];
|
||||
result.data_[2] = df_dg*b.data_[2];
|
||||
result.data_[3] = df_dg*b.data_[3];
|
||||
result.data_[4] = df_dg*b.data_[4];
|
||||
result.data_[5] = df_dg*b.data_[5];
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} } // namespace DenseAd, Opm
|
||||
|
||||
#endif // OPM_DENSEAD_EVALUATION5_HPP
|
@ -23,436 +23,178 @@
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Representation of an evaluation of a function and its derivatives w.r.t. a set
|
||||
* of variables in the localized OPM automatic differentiation (AD) framework.
|
||||
* \brief This file specializes the dense-AD Evaluation class for 6 derivatives.
|
||||
*
|
||||
* \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
|
||||
#ifndef OPM_LOCAL_AD_EVALUATION_6_HPP
|
||||
#define OPM_LOCAL_AD_EVALUATION_6_HPP
|
||||
|
||||
#include "Math.hpp"
|
||||
|
||||
#include <opm/common/Valgrind.hpp>
|
||||
|
||||
#include <dune/common/version.hh>
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#ifndef OPM_DENSEAD_EVALUATION6_HPP
|
||||
#define OPM_DENSEAD_EVALUATION6_HPP
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
/*!
|
||||
* \brief Represents a function evaluation and its derivatives w.r.t. a fixed set of
|
||||
* variables.
|
||||
*/
|
||||
|
||||
template <class ValueT>
|
||||
class Evaluation< ValueT, 6 >
|
||||
struct EvaluationOps<ValueT, 6>
|
||||
{
|
||||
static constexpr int numVars = 6;
|
||||
private:
|
||||
typedef Evaluation<ValueT, 6 > Eval;
|
||||
|
||||
public:
|
||||
//! field type
|
||||
typedef ValueT ValueType;
|
||||
typedef std::array<ValueT, 7 > DataVector;
|
||||
|
||||
//! number of derivatives
|
||||
static constexpr int size = numVars;
|
||||
|
||||
protected:
|
||||
//! length of internal data vector
|
||||
static constexpr int length_ = numVars + 1 ;
|
||||
|
||||
//! position index for value
|
||||
static constexpr int valuepos_ = 0;
|
||||
//! start index for derivatives
|
||||
static constexpr int dstart_ = 1;
|
||||
//! end+1 index for derivatives
|
||||
static constexpr int dend_ = length_ ;
|
||||
public:
|
||||
|
||||
//! default constructor
|
||||
Evaluation() : data_()
|
||||
{}
|
||||
|
||||
//! copy other function evaluation
|
||||
Evaluation(const Evaluation& other) : data_( other.data_ )
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = b.data_[0];
|
||||
a.data_[1] = b.data_[1];
|
||||
a.data_[2] = b.data_[2];
|
||||
a.data_[3] = b.data_[3];
|
||||
a.data_[4] = b.data_[4];
|
||||
a.data_[5] = b.data_[5];
|
||||
a.data_[6] = b.data_[6];
|
||||
}
|
||||
|
||||
// create an evaluation which represents a constant function
|
||||
//
|
||||
// i.e., f(x) = c. this implies an evaluation with the given value and all
|
||||
// derivatives being zero.
|
||||
template <class RhsValueType>
|
||||
Evaluation(const RhsValueType& c)
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
setValue( c );
|
||||
clearDerivatives();
|
||||
Valgrind::CheckDefined( data_ );
|
||||
|
||||
a.data_[0] = - b.data_[0];
|
||||
a.data_[1] = - b.data_[1];
|
||||
a.data_[2] = - b.data_[2];
|
||||
a.data_[3] = - b.data_[3];
|
||||
a.data_[4] = - b.data_[4];
|
||||
a.data_[5] = - b.data_[5];
|
||||
a.data_[6] = - b.data_[6];
|
||||
}
|
||||
|
||||
// create an evaluation which represents a constant function
|
||||
//
|
||||
// i.e., f(x) = c. this implies an evaluation with the given value and all
|
||||
// derivatives being zero.
|
||||
template <class RhsValueType>
|
||||
Evaluation(const RhsValueType& c, int varPos)
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
setValue( c );
|
||||
clearDerivatives();
|
||||
// The variable position must be in represented by the given variable descriptor
|
||||
assert(0 <= varPos && varPos < numVars);
|
||||
|
||||
data_[varPos + dstart_] = 1.0;
|
||||
Valgrind::CheckDefined(data_);
|
||||
}
|
||||
// create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
|
||||
template <class RhsValueType>
|
||||
static Evaluation devide(const RhsValueType& a, const Evaluation& b )
|
||||
{
|
||||
Evaluation<ValueType, numVars> result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueType df_dg = - result.value()/b.value();
|
||||
for (int idx = dstart_; idx < dend_; ++idx) {
|
||||
result.data_[idx] = df_dg*b.data_[idx];
|
||||
}
|
||||
return result;
|
||||
a.data_[1] = 0.0;
|
||||
a.data_[2] = 0.0;
|
||||
a.data_[3] = 0.0;
|
||||
a.data_[4] = 0.0;
|
||||
a.data_[5] = 0.0;
|
||||
a.data_[6] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// set all derivatives to zero
|
||||
void clearDerivatives()
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
data_[ 1 ] = 0;
|
||||
data_[ 2 ] = 0;
|
||||
data_[ 3 ] = 0;
|
||||
data_[ 4 ] = 0;
|
||||
data_[ 5 ] = 0;
|
||||
data_[ 6 ] = 0;
|
||||
|
||||
a.data_[0] += b.data_[0];
|
||||
a.data_[1] += b.data_[1];
|
||||
a.data_[2] += b.data_[2];
|
||||
a.data_[3] += b.data_[3];
|
||||
a.data_[4] += b.data_[4];
|
||||
a.data_[5] += b.data_[5];
|
||||
a.data_[6] += b.data_[6];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
|
||||
template <class RhsValueType>
|
||||
static Evaluation createVariable(const RhsValueType& value, int varPos)
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// copy function value and set all derivatives to 0, except for the variable
|
||||
// which is represented by the value (which is set to 1.0)
|
||||
return Evaluation( value, varPos );
|
||||
|
||||
a.data_[0] -= b.data_[0];
|
||||
a.data_[1] -= b.data_[1];
|
||||
a.data_[2] -= b.data_[2];
|
||||
a.data_[3] -= b.data_[3];
|
||||
a.data_[4] -= b.data_[4];
|
||||
a.data_[5] -= b.data_[5];
|
||||
a.data_[6] -= b.data_[6];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// "evaluate" a constant function (i.e. a function that does not depend on the set of
|
||||
// relevant variables, f(x) = c).
|
||||
template <class RhsValueType>
|
||||
static Evaluation createConstant(const RhsValueType& value)
|
||||
{
|
||||
return Evaluation( value );
|
||||
}
|
||||
|
||||
// print the value and the derivatives of the function evaluation
|
||||
void print(std::ostream& os = std::cout) const
|
||||
{
|
||||
// print value
|
||||
os << "v: " << value() << " / d:";
|
||||
// print derivatives
|
||||
for (int varIdx = 0; varIdx < numVars; ++varIdx)
|
||||
os << " " << derivative(varIdx);
|
||||
}
|
||||
|
||||
// copy all derivatives from other
|
||||
void copyDerivatives(const Evaluation& other)
|
||||
{
|
||||
data_[ 1 ] = other.data_[ 1 ];
|
||||
data_[ 2 ] = other.data_[ 2 ];
|
||||
data_[ 3 ] = other.data_[ 3 ];
|
||||
data_[ 4 ] = other.data_[ 4 ];
|
||||
data_[ 5 ] = other.data_[ 5 ];
|
||||
data_[ 6 ] = other.data_[ 6 ];
|
||||
}
|
||||
|
||||
|
||||
// add value and derivatives from other to this values and derivatives
|
||||
Evaluation& operator+=(const Evaluation& other)
|
||||
{
|
||||
data_[ 0 ] += other.data_[ 0 ];
|
||||
data_[ 1 ] += other.data_[ 1 ];
|
||||
data_[ 2 ] += other.data_[ 2 ];
|
||||
data_[ 3 ] += other.data_[ 3 ];
|
||||
data_[ 4 ] += other.data_[ 4 ];
|
||||
data_[ 5 ] += other.data_[ 5 ];
|
||||
data_[ 6 ] += other.data_[ 6 ];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// add value from other to this values
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator+=(const RhsValueType& other)
|
||||
{
|
||||
// value is added, derivatives stay the same
|
||||
data_[valuepos_] += other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// subtract other's value and derivatives from this values
|
||||
Evaluation& operator-=(const Evaluation& other)
|
||||
{
|
||||
// value and derivatives are subtracted
|
||||
data_[ 0 ] -= other.data_[ 0 ];
|
||||
data_[ 1 ] -= other.data_[ 1 ];
|
||||
data_[ 2 ] -= other.data_[ 2 ];
|
||||
data_[ 3 ] -= other.data_[ 3 ];
|
||||
data_[ 4 ] -= other.data_[ 4 ];
|
||||
data_[ 5 ] -= other.data_[ 5 ];
|
||||
data_[ 6 ] -= other.data_[ 6 ];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// subtract other's value from this values
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator-=(const RhsValueType& other)
|
||||
{
|
||||
// for constants, values are subtracted, derivatives stay the same
|
||||
data_[ valuepos_ ] -= other;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// multiply values and apply chain rule to derivatives: (u*v)' = (v'u + u'v)
|
||||
Evaluation& operator*=(const Evaluation& other)
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueType u = value();
|
||||
const ValueType v = other.value();
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
data_[ 0 ] = u * v ;
|
||||
data_[ 1 ] = data_[ 1 ] * v + other.data_[ 1 ] * u;
|
||||
data_[ 2 ] = data_[ 2 ] * v + other.data_[ 2 ] * u;
|
||||
data_[ 3 ] = data_[ 3 ] * v + other.data_[ 3 ] * u;
|
||||
data_[ 4 ] = data_[ 4 ] * v + other.data_[ 4 ] * u;
|
||||
data_[ 5 ] = data_[ 5 ] * v + other.data_[ 5 ] * u;
|
||||
data_[ 6 ] = data_[ 6 ] * v + other.data_[ 6 ] * u;
|
||||
// value
|
||||
a.data_[0] *= v ;
|
||||
|
||||
return *this;
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v + b.data_[1] * u;
|
||||
a.data_[2] = a.data_[2]*v + b.data_[2] * u;
|
||||
a.data_[3] = a.data_[3]*v + b.data_[3] * u;
|
||||
a.data_[4] = a.data_[4]*v + b.data_[4] * u;
|
||||
a.data_[5] = a.data_[5]*v + b.data_[5] * u;
|
||||
a.data_[6] = a.data_[6]*v + b.data_[6] * u;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] *= other;
|
||||
a.data_[1] *= other;
|
||||
a.data_[2] *= other;
|
||||
a.data_[3] *= other;
|
||||
a.data_[4] *= other;
|
||||
a.data_[5] *= other;
|
||||
a.data_[6] *= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
// value
|
||||
a.data_[0] *= v_vv;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v_vv - b.data_[1]*u_vv;
|
||||
a.data_[2] = a.data_[2]*v_vv - b.data_[2]*u_vv;
|
||||
a.data_[3] = a.data_[3]*v_vv - b.data_[3]*u_vv;
|
||||
a.data_[4] = a.data_[4]*v_vv - b.data_[4]*u_vv;
|
||||
a.data_[5] = a.data_[5]*v_vv - b.data_[5]*u_vv;
|
||||
a.data_[6] = a.data_[6]*v_vv - b.data_[6]*u_vv;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] /= other;
|
||||
a.data_[1] /= other;
|
||||
a.data_[2] /= other;
|
||||
a.data_[3] /= other;
|
||||
a.data_[4] /= other;
|
||||
a.data_[5] /= other;
|
||||
a.data_[6] /= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// m(u*v)' = (v'u + u'v)
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator*=(RhsValueType other)
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b)
|
||||
{
|
||||
data_[ 0 ] *= other;
|
||||
data_[ 1 ] *= other;
|
||||
data_[ 2 ] *= other;
|
||||
data_[ 3 ] *= other;
|
||||
data_[ 4 ] *= other;
|
||||
data_[ 5 ] *= other;
|
||||
data_[ 6 ] *= other;
|
||||
Eval result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// m(u*v)' = (v'u + u'v)
|
||||
Evaluation& operator/=(const Evaluation& other)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u -
|
||||
// u'v)/v^2.
|
||||
const ValueType v_vv = 1.0 / other.value();
|
||||
const ValueType u_vv = value() * v_vv * v_vv;
|
||||
|
||||
data_[ 0 ] *= v_vv;
|
||||
data_[ 1 ] = data_[ 1 ] * v_vv - other.data_[ 1 ] * u_vv ;
|
||||
data_[ 2 ] = data_[ 2 ] * v_vv - other.data_[ 2 ] * u_vv ;
|
||||
data_[ 3 ] = data_[ 3 ] * v_vv - other.data_[ 3 ] * u_vv ;
|
||||
data_[ 4 ] = data_[ 4 ] * v_vv - other.data_[ 4 ] * u_vv ;
|
||||
data_[ 5 ] = data_[ 5 ] * v_vv - other.data_[ 5 ] * u_vv ;
|
||||
data_[ 6 ] = data_[ 6 ] * v_vv - other.data_[ 6 ] * u_vv ;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// multiply value and derivatives by value of other
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator/=(const RhsValueType& other)
|
||||
{
|
||||
// values and derivatives are divided
|
||||
ValueType factor = (1.0/other);
|
||||
data_[ 0 ] *= factor;
|
||||
data_[ 1 ] *= factor;
|
||||
data_[ 2 ] *= factor;
|
||||
data_[ 3 ] *= factor;
|
||||
data_[ 4 ] *= factor;
|
||||
data_[ 5 ] *= factor;
|
||||
data_[ 6 ] *= factor;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// add two evaluation objects
|
||||
Evaluation operator+(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result += other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// add constant to this object
|
||||
template <class RhsValueType>
|
||||
Evaluation operator+(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result += other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// subtract two evaluation objects
|
||||
Evaluation operator-(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result -= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// subtract constant from evaluation object
|
||||
template <class RhsValueType>
|
||||
Evaluation operator-(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result -= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
// negation (unary minus) operator
|
||||
Evaluation operator-() const
|
||||
{
|
||||
Evaluation result;
|
||||
// set value and derivatives to negative
|
||||
for (int idx = 0; idx < length_; ++idx)
|
||||
result.data_[idx] = - data_[idx];
|
||||
result.data_[1] = df_dg*b.data_[1];
|
||||
result.data_[2] = df_dg*b.data_[2];
|
||||
result.data_[3] = df_dg*b.data_[3];
|
||||
result.data_[4] = df_dg*b.data_[4];
|
||||
result.data_[5] = df_dg*b.data_[5];
|
||||
result.data_[6] = df_dg*b.data_[6];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Evaluation operator*(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result *= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation operator*(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result *= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
Evaluation operator/(const Evaluation& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result /= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation operator/(const RhsValueType& other) const
|
||||
{
|
||||
Evaluation result(*this);
|
||||
result /= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
Evaluation& operator=(const RhsValueType& other)
|
||||
{
|
||||
setValue( other );
|
||||
clearDerivatives();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy assignment from evaluation
|
||||
Evaluation& operator=(const Evaluation& other)
|
||||
{
|
||||
data_ = other.data_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator==(const RhsValueType& other) const
|
||||
{ return value() == other; }
|
||||
|
||||
bool operator==(const Evaluation& other) const
|
||||
{
|
||||
for (int idx = 0; idx < length_; ++idx)
|
||||
if (data_[idx] != other.data_[idx])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const Evaluation& other) const
|
||||
{ return !operator==(other); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator>(RhsValueType other) const
|
||||
{ return value() > other; }
|
||||
|
||||
bool operator>(const Evaluation& other) const
|
||||
{ return value() > other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator<(RhsValueType other) const
|
||||
{ return value() < other; }
|
||||
|
||||
bool operator<(const Evaluation& other) const
|
||||
{ return value() < other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator>=(RhsValueType other) const
|
||||
{ return value() >= other; }
|
||||
|
||||
bool operator>=(const Evaluation& other) const
|
||||
{ return value() >= other.value(); }
|
||||
|
||||
template <class RhsValueType>
|
||||
bool operator<=(RhsValueType other) const
|
||||
{ return value() <= other; }
|
||||
|
||||
bool operator<=(const Evaluation& other) const
|
||||
{ return value() <= other.value(); }
|
||||
|
||||
// return value of variable
|
||||
const ValueType& value() const
|
||||
{ return data_[valuepos_]; }
|
||||
|
||||
// set value of variable
|
||||
void setValue(const ValueType& val)
|
||||
{ data_[valuepos_] = val; }
|
||||
|
||||
// return varIdx'th derivative
|
||||
const ValueType& derivative(int varIdx) const
|
||||
{
|
||||
assert(varIdx < numVars);
|
||||
return data_[varIdx + dstart_];
|
||||
}
|
||||
|
||||
// set derivative at position varIdx
|
||||
void setDerivative(int varIdx, const ValueType& derVal)
|
||||
{
|
||||
assert(varIdx < numVars);
|
||||
data_[varIdx + dstart_] = derVal;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::array<ValueType, length_> data_;
|
||||
};
|
||||
|
||||
} // namespace DenseAD
|
||||
} // namespace Dune
|
||||
} } // namespace DenseAd, Opm
|
||||
|
||||
// #include <opm/material/densead/EvaluationSIMD.hpp>
|
||||
|
||||
#endif
|
||||
#endif // OPM_DENSEAD_EVALUATION6_HPP
|
210
opm/material/densead/Evaluation7.hpp
Normal file
210
opm/material/densead/Evaluation7.hpp
Normal file
@ -0,0 +1,210 @@
|
||||
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
// vi: set et ts=4 sw=4 sts=4:
|
||||
/*
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Consult the COPYING file in the top-level source directory of this
|
||||
module for the precise wording of the license and the list of
|
||||
copyright holders.
|
||||
*/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief This file specializes the dense-AD Evaluation class for 7 derivatives.
|
||||
*
|
||||
* \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
#ifndef OPM_DENSEAD_EVALUATION7_HPP
|
||||
#define OPM_DENSEAD_EVALUATION7_HPP
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
|
||||
template <class ValueT>
|
||||
struct EvaluationOps<ValueT, 7>
|
||||
{
|
||||
private:
|
||||
typedef Evaluation<ValueT, 7 > Eval;
|
||||
|
||||
public:
|
||||
typedef std::array<ValueT, 8 > DataVector;
|
||||
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = b.data_[0];
|
||||
a.data_[1] = b.data_[1];
|
||||
a.data_[2] = b.data_[2];
|
||||
a.data_[3] = b.data_[3];
|
||||
a.data_[4] = b.data_[4];
|
||||
a.data_[5] = b.data_[5];
|
||||
a.data_[6] = b.data_[6];
|
||||
a.data_[7] = b.data_[7];
|
||||
}
|
||||
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = - b.data_[0];
|
||||
a.data_[1] = - b.data_[1];
|
||||
a.data_[2] = - b.data_[2];
|
||||
a.data_[3] = - b.data_[3];
|
||||
a.data_[4] = - b.data_[4];
|
||||
a.data_[5] = - b.data_[5];
|
||||
a.data_[6] = - b.data_[6];
|
||||
a.data_[7] = - b.data_[7];
|
||||
}
|
||||
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
|
||||
a.data_[1] = 0.0;
|
||||
a.data_[2] = 0.0;
|
||||
a.data_[3] = 0.0;
|
||||
a.data_[4] = 0.0;
|
||||
a.data_[5] = 0.0;
|
||||
a.data_[6] = 0.0;
|
||||
a.data_[7] = 0.0;
|
||||
}
|
||||
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] += b.data_[0];
|
||||
a.data_[1] += b.data_[1];
|
||||
a.data_[2] += b.data_[2];
|
||||
a.data_[3] += b.data_[3];
|
||||
a.data_[4] += b.data_[4];
|
||||
a.data_[5] += b.data_[5];
|
||||
a.data_[6] += b.data_[6];
|
||||
a.data_[7] += b.data_[7];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] -= b.data_[0];
|
||||
a.data_[1] -= b.data_[1];
|
||||
a.data_[2] -= b.data_[2];
|
||||
a.data_[3] -= b.data_[3];
|
||||
a.data_[4] -= b.data_[4];
|
||||
a.data_[5] -= b.data_[5];
|
||||
a.data_[6] -= b.data_[6];
|
||||
a.data_[7] -= b.data_[7];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
// value
|
||||
a.data_[0] *= v ;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v + b.data_[1] * u;
|
||||
a.data_[2] = a.data_[2]*v + b.data_[2] * u;
|
||||
a.data_[3] = a.data_[3]*v + b.data_[3] * u;
|
||||
a.data_[4] = a.data_[4]*v + b.data_[4] * u;
|
||||
a.data_[5] = a.data_[5]*v + b.data_[5] * u;
|
||||
a.data_[6] = a.data_[6]*v + b.data_[6] * u;
|
||||
a.data_[7] = a.data_[7]*v + b.data_[7] * u;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] *= other;
|
||||
a.data_[1] *= other;
|
||||
a.data_[2] *= other;
|
||||
a.data_[3] *= other;
|
||||
a.data_[4] *= other;
|
||||
a.data_[5] *= other;
|
||||
a.data_[6] *= other;
|
||||
a.data_[7] *= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
// value
|
||||
a.data_[0] *= v_vv;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v_vv - b.data_[1]*u_vv;
|
||||
a.data_[2] = a.data_[2]*v_vv - b.data_[2]*u_vv;
|
||||
a.data_[3] = a.data_[3]*v_vv - b.data_[3]*u_vv;
|
||||
a.data_[4] = a.data_[4]*v_vv - b.data_[4]*u_vv;
|
||||
a.data_[5] = a.data_[5]*v_vv - b.data_[5]*u_vv;
|
||||
a.data_[6] = a.data_[6]*v_vv - b.data_[6]*u_vv;
|
||||
a.data_[7] = a.data_[7]*v_vv - b.data_[7]*u_vv;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] /= other;
|
||||
a.data_[1] /= other;
|
||||
a.data_[2] /= other;
|
||||
a.data_[3] /= other;
|
||||
a.data_[4] /= other;
|
||||
a.data_[5] /= other;
|
||||
a.data_[6] /= other;
|
||||
a.data_[7] /= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b)
|
||||
{
|
||||
Eval result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
|
||||
result.data_[1] = df_dg*b.data_[1];
|
||||
result.data_[2] = df_dg*b.data_[2];
|
||||
result.data_[3] = df_dg*b.data_[3];
|
||||
result.data_[4] = df_dg*b.data_[4];
|
||||
result.data_[5] = df_dg*b.data_[5];
|
||||
result.data_[6] = df_dg*b.data_[6];
|
||||
result.data_[7] = df_dg*b.data_[7];
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} } // namespace DenseAd, Opm
|
||||
|
||||
#endif // OPM_DENSEAD_EVALUATION7_HPP
|
220
opm/material/densead/Evaluation8.hpp
Normal file
220
opm/material/densead/Evaluation8.hpp
Normal file
@ -0,0 +1,220 @@
|
||||
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
// vi: set et ts=4 sw=4 sts=4:
|
||||
/*
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Consult the COPYING file in the top-level source directory of this
|
||||
module for the precise wording of the license and the list of
|
||||
copyright holders.
|
||||
*/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief This file specializes the dense-AD Evaluation class for 8 derivatives.
|
||||
*
|
||||
* \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
#ifndef OPM_DENSEAD_EVALUATION8_HPP
|
||||
#define OPM_DENSEAD_EVALUATION8_HPP
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
|
||||
template <class ValueT>
|
||||
struct EvaluationOps<ValueT, 8>
|
||||
{
|
||||
private:
|
||||
typedef Evaluation<ValueT, 8 > Eval;
|
||||
|
||||
public:
|
||||
typedef std::array<ValueT, 9 > DataVector;
|
||||
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = b.data_[0];
|
||||
a.data_[1] = b.data_[1];
|
||||
a.data_[2] = b.data_[2];
|
||||
a.data_[3] = b.data_[3];
|
||||
a.data_[4] = b.data_[4];
|
||||
a.data_[5] = b.data_[5];
|
||||
a.data_[6] = b.data_[6];
|
||||
a.data_[7] = b.data_[7];
|
||||
a.data_[8] = b.data_[8];
|
||||
}
|
||||
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = - b.data_[0];
|
||||
a.data_[1] = - b.data_[1];
|
||||
a.data_[2] = - b.data_[2];
|
||||
a.data_[3] = - b.data_[3];
|
||||
a.data_[4] = - b.data_[4];
|
||||
a.data_[5] = - b.data_[5];
|
||||
a.data_[6] = - b.data_[6];
|
||||
a.data_[7] = - b.data_[7];
|
||||
a.data_[8] = - b.data_[8];
|
||||
}
|
||||
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
|
||||
a.data_[1] = 0.0;
|
||||
a.data_[2] = 0.0;
|
||||
a.data_[3] = 0.0;
|
||||
a.data_[4] = 0.0;
|
||||
a.data_[5] = 0.0;
|
||||
a.data_[6] = 0.0;
|
||||
a.data_[7] = 0.0;
|
||||
a.data_[8] = 0.0;
|
||||
}
|
||||
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] += b.data_[0];
|
||||
a.data_[1] += b.data_[1];
|
||||
a.data_[2] += b.data_[2];
|
||||
a.data_[3] += b.data_[3];
|
||||
a.data_[4] += b.data_[4];
|
||||
a.data_[5] += b.data_[5];
|
||||
a.data_[6] += b.data_[6];
|
||||
a.data_[7] += b.data_[7];
|
||||
a.data_[8] += b.data_[8];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] -= b.data_[0];
|
||||
a.data_[1] -= b.data_[1];
|
||||
a.data_[2] -= b.data_[2];
|
||||
a.data_[3] -= b.data_[3];
|
||||
a.data_[4] -= b.data_[4];
|
||||
a.data_[5] -= b.data_[5];
|
||||
a.data_[6] -= b.data_[6];
|
||||
a.data_[7] -= b.data_[7];
|
||||
a.data_[8] -= b.data_[8];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
// value
|
||||
a.data_[0] *= v ;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v + b.data_[1] * u;
|
||||
a.data_[2] = a.data_[2]*v + b.data_[2] * u;
|
||||
a.data_[3] = a.data_[3]*v + b.data_[3] * u;
|
||||
a.data_[4] = a.data_[4]*v + b.data_[4] * u;
|
||||
a.data_[5] = a.data_[5]*v + b.data_[5] * u;
|
||||
a.data_[6] = a.data_[6]*v + b.data_[6] * u;
|
||||
a.data_[7] = a.data_[7]*v + b.data_[7] * u;
|
||||
a.data_[8] = a.data_[8]*v + b.data_[8] * u;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] *= other;
|
||||
a.data_[1] *= other;
|
||||
a.data_[2] *= other;
|
||||
a.data_[3] *= other;
|
||||
a.data_[4] *= other;
|
||||
a.data_[5] *= other;
|
||||
a.data_[6] *= other;
|
||||
a.data_[7] *= other;
|
||||
a.data_[8] *= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
// value
|
||||
a.data_[0] *= v_vv;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v_vv - b.data_[1]*u_vv;
|
||||
a.data_[2] = a.data_[2]*v_vv - b.data_[2]*u_vv;
|
||||
a.data_[3] = a.data_[3]*v_vv - b.data_[3]*u_vv;
|
||||
a.data_[4] = a.data_[4]*v_vv - b.data_[4]*u_vv;
|
||||
a.data_[5] = a.data_[5]*v_vv - b.data_[5]*u_vv;
|
||||
a.data_[6] = a.data_[6]*v_vv - b.data_[6]*u_vv;
|
||||
a.data_[7] = a.data_[7]*v_vv - b.data_[7]*u_vv;
|
||||
a.data_[8] = a.data_[8]*v_vv - b.data_[8]*u_vv;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] /= other;
|
||||
a.data_[1] /= other;
|
||||
a.data_[2] /= other;
|
||||
a.data_[3] /= other;
|
||||
a.data_[4] /= other;
|
||||
a.data_[5] /= other;
|
||||
a.data_[6] /= other;
|
||||
a.data_[7] /= other;
|
||||
a.data_[8] /= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b)
|
||||
{
|
||||
Eval result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
|
||||
result.data_[1] = df_dg*b.data_[1];
|
||||
result.data_[2] = df_dg*b.data_[2];
|
||||
result.data_[3] = df_dg*b.data_[3];
|
||||
result.data_[4] = df_dg*b.data_[4];
|
||||
result.data_[5] = df_dg*b.data_[5];
|
||||
result.data_[6] = df_dg*b.data_[6];
|
||||
result.data_[7] = df_dg*b.data_[7];
|
||||
result.data_[8] = df_dg*b.data_[8];
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} } // namespace DenseAd, Opm
|
||||
|
||||
#endif // OPM_DENSEAD_EVALUATION8_HPP
|
230
opm/material/densead/Evaluation9.hpp
Normal file
230
opm/material/densead/Evaluation9.hpp
Normal file
@ -0,0 +1,230 @@
|
||||
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
// vi: set et ts=4 sw=4 sts=4:
|
||||
/*
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Consult the COPYING file in the top-level source directory of this
|
||||
module for the precise wording of the license and the list of
|
||||
copyright holders.
|
||||
*/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief This file specializes the dense-AD Evaluation class for 9 derivatives.
|
||||
*
|
||||
* \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
#ifndef OPM_DENSEAD_EVALUATION9_HPP
|
||||
#define OPM_DENSEAD_EVALUATION9_HPP
|
||||
|
||||
namespace Opm {
|
||||
namespace DenseAd {
|
||||
|
||||
template <class ValueT>
|
||||
struct EvaluationOps<ValueT, 9>
|
||||
{
|
||||
private:
|
||||
typedef Evaluation<ValueT, 9 > Eval;
|
||||
|
||||
public:
|
||||
typedef std::array<ValueT, 10 > DataVector;
|
||||
|
||||
static inline void assign(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = b.data_[0];
|
||||
a.data_[1] = b.data_[1];
|
||||
a.data_[2] = b.data_[2];
|
||||
a.data_[3] = b.data_[3];
|
||||
a.data_[4] = b.data_[4];
|
||||
a.data_[5] = b.data_[5];
|
||||
a.data_[6] = b.data_[6];
|
||||
a.data_[7] = b.data_[7];
|
||||
a.data_[8] = b.data_[8];
|
||||
a.data_[9] = b.data_[9];
|
||||
}
|
||||
|
||||
static inline void assignNegative(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] = - b.data_[0];
|
||||
a.data_[1] = - b.data_[1];
|
||||
a.data_[2] = - b.data_[2];
|
||||
a.data_[3] = - b.data_[3];
|
||||
a.data_[4] = - b.data_[4];
|
||||
a.data_[5] = - b.data_[5];
|
||||
a.data_[6] = - b.data_[6];
|
||||
a.data_[7] = - b.data_[7];
|
||||
a.data_[8] = - b.data_[8];
|
||||
a.data_[9] = - b.data_[9];
|
||||
}
|
||||
|
||||
static inline void clearDerivatives(Eval& a)
|
||||
{
|
||||
|
||||
a.data_[1] = 0.0;
|
||||
a.data_[2] = 0.0;
|
||||
a.data_[3] = 0.0;
|
||||
a.data_[4] = 0.0;
|
||||
a.data_[5] = 0.0;
|
||||
a.data_[6] = 0.0;
|
||||
a.data_[7] = 0.0;
|
||||
a.data_[8] = 0.0;
|
||||
a.data_[9] = 0.0;
|
||||
}
|
||||
|
||||
static inline Eval& addEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] += b.data_[0];
|
||||
a.data_[1] += b.data_[1];
|
||||
a.data_[2] += b.data_[2];
|
||||
a.data_[3] += b.data_[3];
|
||||
a.data_[4] += b.data_[4];
|
||||
a.data_[5] += b.data_[5];
|
||||
a.data_[6] += b.data_[6];
|
||||
a.data_[7] += b.data_[7];
|
||||
a.data_[8] += b.data_[8];
|
||||
a.data_[9] += b.data_[9];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& subEq(Eval& a, const Eval& b)
|
||||
{
|
||||
|
||||
a.data_[0] -= b.data_[0];
|
||||
a.data_[1] -= b.data_[1];
|
||||
a.data_[2] -= b.data_[2];
|
||||
a.data_[3] -= b.data_[3];
|
||||
a.data_[4] -= b.data_[4];
|
||||
a.data_[5] -= b.data_[5];
|
||||
a.data_[6] -= b.data_[6];
|
||||
a.data_[7] -= b.data_[7];
|
||||
a.data_[8] -= b.data_[8];
|
||||
a.data_[9] -= b.data_[9];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& mulEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// while the values are multiplied, the derivatives follow the product rule,
|
||||
// i.e., (u*v)' = (v'u + u'v).
|
||||
const ValueT u = a.value();
|
||||
const ValueT v = b.value();
|
||||
|
||||
// value
|
||||
a.data_[0] *= v ;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v + b.data_[1] * u;
|
||||
a.data_[2] = a.data_[2]*v + b.data_[2] * u;
|
||||
a.data_[3] = a.data_[3]*v + b.data_[3] * u;
|
||||
a.data_[4] = a.data_[4]*v + b.data_[4] * u;
|
||||
a.data_[5] = a.data_[5]*v + b.data_[5] * u;
|
||||
a.data_[6] = a.data_[6]*v + b.data_[6] * u;
|
||||
a.data_[7] = a.data_[7]*v + b.data_[7] * u;
|
||||
a.data_[8] = a.data_[8]*v + b.data_[8] * u;
|
||||
a.data_[9] = a.data_[9]*v + b.data_[9] * u;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarMulEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] *= other;
|
||||
a.data_[1] *= other;
|
||||
a.data_[2] *= other;
|
||||
a.data_[3] *= other;
|
||||
a.data_[4] *= other;
|
||||
a.data_[5] *= other;
|
||||
a.data_[6] *= other;
|
||||
a.data_[7] *= other;
|
||||
a.data_[8] *= other;
|
||||
a.data_[9] *= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline Eval& divEq(Eval& a, const Eval& b)
|
||||
{
|
||||
// values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2.
|
||||
const ValueT v_vv = 1.0 / b.value();
|
||||
const ValueT u_vv = a.value() * v_vv * v_vv;
|
||||
|
||||
// value
|
||||
a.data_[0] *= v_vv;
|
||||
|
||||
// derivatives
|
||||
a.data_[1] = a.data_[1]*v_vv - b.data_[1]*u_vv;
|
||||
a.data_[2] = a.data_[2]*v_vv - b.data_[2]*u_vv;
|
||||
a.data_[3] = a.data_[3]*v_vv - b.data_[3]*u_vv;
|
||||
a.data_[4] = a.data_[4]*v_vv - b.data_[4]*u_vv;
|
||||
a.data_[5] = a.data_[5]*v_vv - b.data_[5]*u_vv;
|
||||
a.data_[6] = a.data_[6]*v_vv - b.data_[6]*u_vv;
|
||||
a.data_[7] = a.data_[7]*v_vv - b.data_[7]*u_vv;
|
||||
a.data_[8] = a.data_[8]*v_vv - b.data_[8]*u_vv;
|
||||
a.data_[9] = a.data_[9]*v_vv - b.data_[9]*u_vv;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsType>
|
||||
static inline Eval& scalarDivEq(Eval& a, const RhsType& other)
|
||||
{
|
||||
|
||||
a.data_[0] /= other;
|
||||
a.data_[1] /= other;
|
||||
a.data_[2] /= other;
|
||||
a.data_[3] /= other;
|
||||
a.data_[4] /= other;
|
||||
a.data_[5] /= other;
|
||||
a.data_[6] /= other;
|
||||
a.data_[7] /= other;
|
||||
a.data_[8] /= other;
|
||||
a.data_[9] /= other;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class RhsValueType>
|
||||
static inline Eval divide(const RhsValueType& a, const Eval& b)
|
||||
{
|
||||
Eval result;
|
||||
result.setValue( a/b.value() );
|
||||
const ValueT df_dg = - result.value()/b.value();
|
||||
|
||||
result.data_[1] = df_dg*b.data_[1];
|
||||
result.data_[2] = df_dg*b.data_[2];
|
||||
result.data_[3] = df_dg*b.data_[3];
|
||||
result.data_[4] = df_dg*b.data_[4];
|
||||
result.data_[5] = df_dg*b.data_[5];
|
||||
result.data_[6] = df_dg*b.data_[6];
|
||||
result.data_[7] = df_dg*b.data_[7];
|
||||
result.data_[8] = df_dg*b.data_[8];
|
||||
result.data_[9] = df_dg*b.data_[9];
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} } // namespace DenseAd, Opm
|
||||
|
||||
#endif // OPM_DENSEAD_EVALUATION9_HPP
|
48
opm/material/densead/EvaluationSpecializations.hpp
Normal file
48
opm/material/densead/EvaluationSpecializations.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
// vi: set et ts=4 sw=4 sts=4:
|
||||
/*
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Consult the COPYING file in the top-level source directory of this
|
||||
module for the precise wording of the license and the list of
|
||||
copyright holders.
|
||||
*/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief This file includes all specializations for the dense-AD Evaluation class.
|
||||
*
|
||||
* \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py"
|
||||
* SCRIPT. DO NOT EDIT IT MANUALLY!
|
||||
*/
|
||||
#ifndef OPM_DENSEAD_EVALUATION_SPECIALIZATIONS_HPP
|
||||
#define OPM_DENSEAD_EVALUATION_SPECIALIZATIONS_HPP
|
||||
|
||||
#include <opm/material/densead/Evaluation1.hpp>
|
||||
#include <opm/material/densead/Evaluation2.hpp>
|
||||
#include <opm/material/densead/Evaluation3.hpp>
|
||||
#include <opm/material/densead/Evaluation4.hpp>
|
||||
#include <opm/material/densead/Evaluation5.hpp>
|
||||
#include <opm/material/densead/Evaluation6.hpp>
|
||||
#include <opm/material/densead/Evaluation7.hpp>
|
||||
#include <opm/material/densead/Evaluation8.hpp>
|
||||
#include <opm/material/densead/Evaluation9.hpp>
|
||||
#include <opm/material/densead/Evaluation10.hpp>
|
||||
#include <opm/material/densead/Evaluation11.hpp>
|
||||
#include <opm/material/densead/Evaluation12.hpp>
|
||||
|
||||
|
||||
#endif // OPM_DENSEAD_EVALUATION_SPECIALIZATIONS_HPP
|
Loading…
Reference in New Issue
Block a user