From 2a69da14f0da2bb17da4da3115c850b873e13103 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Mon, 5 Jun 2017 21:37:37 +0200 Subject: [PATCH 1/6] Simplify usage of Evaluations in some places The convenience functions allow to get rid of many direct calls to the toolbox and constants can be directly returned as doubles. --- .../RegularizedVanGenuchten.hpp | 12 ++++-------- opm/material/fluidsystems/BrineCO2FluidSystem.hpp | 4 ++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/opm/material/fluidmatrixinteractions/RegularizedVanGenuchten.hpp b/opm/material/fluidmatrixinteractions/RegularizedVanGenuchten.hpp index f20974192..afacaca0e 100644 --- a/opm/material/fluidmatrixinteractions/RegularizedVanGenuchten.hpp +++ b/opm/material/fluidmatrixinteractions/RegularizedVanGenuchten.hpp @@ -306,13 +306,11 @@ public: template static Evaluation twoPhaseSatKrw(const Params& params, const Evaluation& Sw) { - typedef MathToolbox Toolbox; - // regularize if (Sw <= 0) - return Toolbox::createConstant(0); + return 0.0; else if (Sw >= 1) - return Toolbox::createConstant(1); + return 1.0; return VanGenuchten::twoPhaseSatKrw(params, Sw); } @@ -344,13 +342,11 @@ public: template static Evaluation twoPhaseSatKrn(const Params& params, const Evaluation& Sw) { - typedef MathToolbox Toolbox; - // regularize if (Sw <= 0) - return Toolbox::createConstant(1); + return 1.0; else if (Sw >= 1) - return Toolbox::createConstant(0); + return 0.0; return VanGenuchten::twoPhaseSatKrn(params, Sw); } diff --git a/opm/material/fluidsystems/BrineCO2FluidSystem.hpp b/opm/material/fluidsystems/BrineCO2FluidSystem.hpp index 6a620de7a..86329aaa5 100644 --- a/opm/material/fluidsystems/BrineCO2FluidSystem.hpp +++ b/opm/material/fluidsystems/BrineCO2FluidSystem.hpp @@ -266,8 +266,8 @@ public: // use normalized composition for to calculate the density // (the relations don't seem to take non-normalized // compositions too well...) - LhsEval xgBrine = LhsToolbox::min(1.0, LhsToolbox::max(0.0, FsToolbox::template decay(fluidState.moleFraction(gasPhaseIdx, BrineIdx)))); - LhsEval xgCO2 = LhsToolbox::min(1.0, LhsToolbox::max(0.0, FsToolbox::template decay(fluidState.moleFraction(gasPhaseIdx, CO2Idx)))); + LhsEval xgBrine = Opm::min(1.0, Opm::max(0.0, Opm::decay(fluidState.moleFraction(gasPhaseIdx, BrineIdx)))); + LhsEval xgCO2 = Opm::min(1.0, Opm::max(0.0, Opm::decay(fluidState.moleFraction(gasPhaseIdx, CO2Idx)))); LhsEval sumx = xgBrine + xgCO2; xgBrine /= sumx; xgCO2 /= sumx; From 2f86c78dd82da00c40a64612e2bcf4ba53c7b652 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Mon, 3 Apr 2017 16:45:58 +0200 Subject: [PATCH 2/6] Revert "Revert "[WIP] Evaluation: specialize evaluations for used numbers in Blackoil setting"" This reverts commit cfc79fd6d5152a3d72e42c76e8109f4316680f97. --- bin/genEvalSpecializations.py | 734 ++++++++++++++++++ opm/material/densead/Evaluation.hpp | 274 ++++--- opm/material/densead/Evaluation1.hpp | 430 ++++++++++ opm/material/densead/Evaluation10.hpp | 538 +++++++++++++ opm/material/densead/Evaluation11.hpp | 550 +++++++++++++ opm/material/densead/Evaluation12.hpp | 562 ++++++++++++++ opm/material/densead/Evaluation2.hpp | 442 +++++++++++ opm/material/densead/Evaluation3.hpp | 454 +++++++++++ opm/material/densead/Evaluation4.hpp | 466 +++++++++++ opm/material/densead/Evaluation5.hpp | 478 ++++++++++++ opm/material/densead/Evaluation6.hpp | 490 ++++++++++++ opm/material/densead/Evaluation7.hpp | 502 ++++++++++++ opm/material/densead/Evaluation8.hpp | 514 ++++++++++++ opm/material/densead/Evaluation9.hpp | 526 +++++++++++++ .../densead/EvaluationSpecializations.hpp | 48 ++ opm/material/densead/Math.hpp | 78 +- tests/test_densead.cpp | 71 +- 17 files changed, 6955 insertions(+), 202 deletions(-) create mode 100755 bin/genEvalSpecializations.py create mode 100644 opm/material/densead/Evaluation1.hpp create mode 100644 opm/material/densead/Evaluation10.hpp create mode 100644 opm/material/densead/Evaluation11.hpp create mode 100644 opm/material/densead/Evaluation12.hpp create mode 100644 opm/material/densead/Evaluation2.hpp create mode 100644 opm/material/densead/Evaluation3.hpp create mode 100644 opm/material/densead/Evaluation4.hpp create mode 100644 opm/material/densead/Evaluation5.hpp create mode 100644 opm/material/densead/Evaluation6.hpp create mode 100644 opm/material/densead/Evaluation7.hpp create mode 100644 opm/material/densead/Evaluation8.hpp create mode 100644 opm/material/densead/Evaluation9.hpp create mode 100644 opm/material/densead/EvaluationSpecializations.hpp diff --git a/bin/genEvalSpecializations.py b/bin/genEvalSpecializations.py new file mode 100755 index 000000000..6c94ed452 --- /dev/null +++ b/bin/genEvalSpecializations.py @@ -0,0 +1,734 @@ +#! /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 . + + 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 + * +{% if numDerivs < 0 %} + * \\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. +{% else %} + * \\brief This file specializes the dense-AD Evaluation class for {{ numDerivs }} derivatives. +{% endif %} + * + * \\attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "{{ scriptName }}" + * SCRIPT. DO NOT EDIT IT MANUALLY! + */ +{% if numDerivs < 0 %} +#ifndef OPM_DENSEAD_EVALUATION_HPP +#define OPM_DENSEAD_EVALUATION_HPP +{% else %} +#ifndef OPM_DENSEAD_EVALUATION{{numDerivs}}_HPP +#define OPM_DENSEAD_EVALUATION{{numDerivs}}_HPP +{% endif %} + +#include "Math.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace DenseAd { + +{% if numDerivs < 0 %} +/*! + * \\brief Represents a function evaluation and its derivatives w.r.t. a fixed set of + * variables. + */ +template +class Evaluation\ +{% else %} +template +class Evaluation\ +{% endif %} +{ +public: + //! field type + typedef ValueT ValueType; + + //! number of derivatives\ + {% if numDerivs < 0 %} + static constexpr int size = numDerivs; + {% else %} + static constexpr int size = {{ numDerivs }}; + {% endif %} +protected: + //! length of internal data vector + static constexpr int length_ = size + 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) +{% if numDerivs < 0 %}\ + : data_(other.data_) + { } +{% else %}\ + {\ + {% for i in range(0, numDerivs+1) %} + data_[{{i}}] = other.data_[{{i}}];{% endfor %} + } +{% endif %}\ + + // 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 + Evaluation(const RhsValueType& c) + { + setValue( c ); + clearDerivatives(); + Valgrind::CheckDefined( data_ ); + } + + // 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 + Evaluation(const RhsValueType& c, int varPos) + { + setValue( c ); + clearDerivatives(); + // The variable position must be in represented by the given variable descriptor + assert(0 <= varPos && varPos < size); + + data_[varPos + dstart_] = 1.0; + Valgrind::CheckDefined(data_); + } + + // set all derivatives to zero + void clearDerivatives() + {\ + {% if numDerivs < 0 %} + for (int i = dstart_; i < dend_; ++i) { + data_[i] = 0.0; + } +{% else %}\ + {% for i in range(1, numDerivs+1) %} + data_[{{i}}] = 0.0;{% endfor %} +{% endif %}\ + } + + // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) + template + 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 + 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 < size; ++varIdx) { + os << " " << derivative(varIdx); + } + } + + // copy all derivatives from other + void copyDerivatives(const Evaluation& other) + {\ + {% if numDerivs < 0 %} + for (int i = dstart_; i < dend_; ++i) { + data_[i] = other.data_[i]; + } + {% else %}\ + {% for i in range(1, numDerivs+1) %} + data_[{{i}}] = other.data_[{{i}}];{% endfor %} + {% endif %}\ + } + + + // add value and derivatives from other to this values and derivatives + Evaluation& operator+=(const Evaluation& other) + {\ + {% if numDerivs < 0 %} + for (int i = 0; i < length_; ++i) { + data_[i] += other.data_[i]; + } + {% else %}\ + {% for i in range(0, numDerivs+1) %} + data_[{{i}}] += other.data_[{{i}}];{% endfor %} + {% endif %}\ + + return *this; + } + + // add value from other to this values + template + 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) + {\ + {% if numDerivs < 0 %} + for (int i = 0; i < length_; ++i) { + data_[i] -= other.data_[i]; + } + {% else %}\ + {% for i in range(0, numDerivs+1) %} + data_[{{i}}] -= other.data_[{{i}}];{% endfor %} + {% endif %} + return *this; + } + + // subtract other's value from this values + template + 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) + { + // while the values are multiplied, the derivatives follow the product rule, + // i.e., (u*v)' = (v'u + u'v). + const ValueType u = this->value(); + const ValueType v = other.value(); + + // value + data_[valuepos_] *= v ; + + // derivatives\ +{% if numDerivs < 0 %} + for (int i = dstart_; i < dend_; ++i) { + data_[i] = data_[i] * v + other.data_[i] * u; + } +{% else %}\ + {% for i in range(1, numDerivs+1) %} + data_[{{i}}] = data_[{{i}}] * v + other.data_[{{i}}] * u;{% endfor %} +{% endif %}\ + + return *this; + } + + // m(c*u)' = c*u' + template + Evaluation& operator*=(const RhsValueType& other) + {\ + {% if numDerivs < 0 %} + for (int i = 0; i < length_; ++i) { + data_[i] *= other; + } + {% else %}\ + {% for i in range(0, numDerivs+1) %} + data_[{{i}}] *= other;{% endfor %} + {% endif %} + 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; + + // value + data_[valuepos_] *= v_vv; + + // derivatives\ + {% if numDerivs < 0 %} + for (int i = dstart_; i < dend_; ++i) { + data_[i] = data_[i] * v_vv - other.data_[i] * u_vv; + } + {% else %}\ + {% for i in range(1, numDerivs+1) %} + data_[{{i}}] = data_[{{i}}] * v_vv - other.data_[{{i}}] * u_vv;{% endfor %} + {% endif %} + return *this; + } + + // divide value and derivatives by value of other + template + Evaluation& operator/=(const RhsValueType& other) + { + const ValueType tmp = 1.0/other; + {% if numDerivs < 0 %} + for (int i = 0; i < length_; ++i) { + data_[i] *= tmp; + } + {% else %}\ + {% for i in range(0, numDerivs+1) %} + data_[{{i}}] *= tmp;{% endfor %} + {% endif %} + return *this; + } + + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + {% if numDerivs < 0 %} + for (int i = dstart_; i < dend_; ++i) { + result.data_[i] = df_dg * b.data_[i]; + } + {% else %}\ + {% for i in range(1, numDerivs+1) %} + result.data_[{{i}}] = df_dg * b.data_[{{i}}];{% endfor %} + {% endif %} + return result; + } + + // add two evaluation objects + Evaluation operator+(const Evaluation& other) const + { + Evaluation result(*this); + result += other; + return result; + } + + // add constant to this object + template + 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); + return (result -= other); + } + + // subtract constant from evaluation object + template + Evaluation operator-(const RhsValueType& other) const + { + Evaluation result(*this); + return (result -= other); + } + + // negation (unary minus) operator + Evaluation operator-() const + { + Evaluation result; + // set value and derivatives to negative\ + {% if numDerivs < 0 %} + for (int i = 0; i < length_; ++i) { + result.data_[i] = - data_[i]; + } + {% else %}\ + {% for i in range(0, numDerivs+1) %} + result.data_[{{i}}] = - data_[{{i}}];{% endfor %} + {% endif %} + return result; + } + + Evaluation operator*(const Evaluation& other) const + { + Evaluation result(*this); + result *= other; + return result; + } + + template + 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 + Evaluation operator/(const RhsValueType& other) const + { + Evaluation result(*this); + result /= other; + return result; + } + + template + Evaluation& operator=(const RhsValueType& other) + { + setValue( other ); + clearDerivatives(); + return *this; + } + + // copy assignment from evaluation + Evaluation& operator=(const Evaluation& other) + {\ + {% if numDerivs < 0 %} + for (int i = 0; i < length_; ++i) { + data_[i] = other.data_[i]; + } + {% else %}\ + {% for i in range(0, numDerivs+1) %} + data_[{{i}}] = other.data_[{{i}}];{% endfor %} + {% endif %} + return *this; + } + + template + 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 + bool operator>(RhsValueType other) const + { return value() > other; } + + bool operator>(const Evaluation& other) const + { return value() > other.value(); } + + template + bool operator<(RhsValueType other) const + { return value() < other; } + + bool operator<(const Evaluation& other) const + { return value() < other.value(); } + + template + bool operator>=(RhsValueType other) const + { return value() >= other; } + + bool operator>=(const Evaluation& other) const + { return value() >= other.value(); } + + template + 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 + template + void setValue(const RhsValueType& val) + { data_[valuepos_] = val; } + + // return varIdx'th derivative + const ValueType& derivative(int varIdx) const + { + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; + } + + // set derivative at position varIdx + void setDerivative(int varIdx, const ValueType& derVal) + { + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; + } + +private: + std::array data_; +}; + +{# the generic operators are only required for the unspecialized case #} +{% if numDerivs < 0 %} +template +bool operator<(const RhsValueType& a, const Evaluation& b) +{ return b > a; } + +template +bool operator>(const RhsValueType& a, const Evaluation& b) +{ return b < a; } + +template +bool operator<=(const RhsValueType& a, const Evaluation& b) +{ return b >= a; } + +template +bool operator>=(const RhsValueType& a, const Evaluation& b) +{ return b <= a; } + +template +bool operator!=(const RhsValueType& a, const Evaluation& b) +{ return a != b.value(); } + +template +Evaluation operator+(const RhsValueType& a, const Evaluation& b) +{ + Evaluation result(b); + result += a; + return result; +} + +template +Evaluation operator-(const RhsValueType& a, const Evaluation& b) +{ + Evaluation result(a); + result -= b; + return result; +} + +template +Evaluation operator/(const RhsValueType& a, const Evaluation& b) +{ + return Evaluation::divide(a, b); +} + +template +Evaluation operator*(const RhsValueType& a, const Evaluation& b) +{ + Evaluation result(b); + result *= a; + return result; +} + +template +std::ostream& operator<<(std::ostream& os, const Evaluation& eval) +{ + os << eval.value(); + return os; +} +{% endif %} +} } // namespace DenseAd, Opm + +{% if numDerivs < 0 %} +// In Dune 2.3, the Evaluation.hpp header must be included before the fmatrix.hh +// header. Dune 2.4+ does not suffer from this because of some c++-foo. +// +// for those who are wondering: in C++ function templates cannot be partially +// specialized, and function argument overloads must be known _before_ they are used. The +// latter is what we do for the 'Dune::fvmeta::absreal()' function. +// +// consider the following test program: +// +// double foo(double i) +// { return i; } +// +// void bar() +// { std::cout << foo(0) << "\\n"; } +// +// int foo(int i) +// { return i + 1; } +// +// void foobar() +// { std::cout << foo(0) << "\\n"; } +// +// this will print '0' for bar() and '1' for foobar()... +#if !(DUNE_VERSION_NEWER(DUNE_COMMON, 2,4)) + +namespace Opm { +namespace DenseAd { +template +Evaluation abs(const Evaluation&); +}} + +namespace std { +template +const Opm::DenseAd::Evaluation abs(const Opm::DenseAd::Evaluation& x) +{ return Opm::DenseAd::abs(x); } + +} // namespace std + +#if defined DUNE_DENSEMATRIX_HH +#warning \\ + "Due to some C++ peculiarity regarding function overloads, the 'Evaluation.hpp'" \\ + "header file must be included before Dune's 'densematrix.hh' for Dune < 2.4. " \\ + "(If Evaluations are to be used in conjunction with a dense matrix.)" +#endif + +#endif + +// this makes the Dune matrix/vector classes happy... +#include + +namespace Dune { +template +struct FieldTraits > +{ +public: + typedef Opm::DenseAd::Evaluation field_type; + // setting real_type to field_type here potentially leads to slightly worse + // performance, but at least it makes things compile. + typedef field_type real_type; +}; + +} // namespace Dune + +#include "EvaluationSpecializations.hpp" + +#endif // OPM_DENSEAD_EVALUATION_HPP +{% else %} +#endif // OPM_DENSEAD_EVALUATION{{numDerivs}}_HPP +{% endif %} +""" + +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 . + + 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 +""" + +print ("Generating generic template class") +fileName = "opm/material/densead/Evaluation.hpp" +template = jinja2.Template(specializationTemplate) +fileContents = template.render(numDerivs=-1, scriptName=os.path.basename(sys.argv[0])) + +f = open(fileName, "w") +f.write(fileContents) +f.close() + +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() diff --git a/opm/material/densead/Evaluation.hpp b/opm/material/densead/Evaluation.hpp index fe574de40..18f977dad 100644 --- a/opm/material/densead/Evaluation.hpp +++ b/opm/material/densead/Evaluation.hpp @@ -23,11 +23,18 @@ /*! * \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. + + * + * \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py" + * SCRIPT. DO NOT EDIT IT MANUALLY! */ -#ifndef OPM_LOCAL_AD_EVALUATION_HPP -#define OPM_LOCAL_AD_EVALUATION_HPP + +#ifndef OPM_DENSEAD_EVALUATION_HPP +#define OPM_DENSEAD_EVALUATION_HPP + #include "Math.hpp" @@ -38,45 +45,48 @@ #include #include #include +#include #include #include namespace Opm { namespace DenseAd { + + /*! * \brief Represents a function evaluation and its derivatives w.r.t. a fixed set of * variables. */ -template +template class Evaluation { public: //! field type typedef ValueT ValueType; - //! number of derivatives - static constexpr unsigned size = numVars; - + //! number of derivatives + static constexpr int size = numDerivs; + protected: //! length of internal data vector - static constexpr unsigned length_ = numVars + 1 ; + static constexpr int length_ = size + 1; //! position index for value - static constexpr unsigned valuepos_ = 0; + static constexpr int valuepos_ = 0; //! start index for derivatives - static constexpr unsigned dstart_ = 1; + static constexpr int dstart_ = 1; //! end+1 index for derivatives - static constexpr unsigned dend_ = length_ ; -public: + static constexpr int dend_ = length_; +public: //! default constructor Evaluation() : data_() {} //! copy other function evaluation - Evaluation(const Evaluation& other) : data_( other.data_ ) - { - } + Evaluation(const Evaluation& other) + : data_(other.data_) + { } // create an evaluation which represents a constant function // @@ -95,12 +105,12 @@ public: // i.e., f(x) = c. this implies an evaluation with the given value and all // derivatives being zero. template - Evaluation(const RhsValueType& c, unsigned varPos) + Evaluation(const RhsValueType& c, int varPos) { setValue( c ); clearDerivatives(); // The variable position must be in represented by the given variable descriptor - assert(0 <= varPos && varPos < numVars); + assert(0 <= varPos && varPos < size); data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); @@ -108,14 +118,15 @@ public: // set all derivatives to zero void clearDerivatives() - { - for (unsigned i = dstart_; i < dend_; ++i) - data_[ i ] = 0.0; + { + for (int i = dstart_; i < dend_; ++i) { + data_[i] = 0.0; + } } // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) template - static Evaluation createVariable(const RhsValueType& value, unsigned varPos) + 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) @@ -136,25 +147,27 @@ public: // print value os << "v: " << value() << " / d:"; // print derivatives - for (unsigned varIdx = 0; varIdx < numVars; ++varIdx) + for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); + } } // copy all derivatives from other void copyDerivatives(const Evaluation& other) - { - for (unsigned varIdx = dstart_; varIdx < dend_; ++varIdx) - data_[ varIdx ] = other.data_[ varIdx ]; - } + { + for (int i = dstart_; i < dend_; ++i) { + data_[i] = other.data_[i]; + } + } // add value and derivatives from other to this values and derivatives Evaluation& operator+=(const Evaluation& other) - { - // value and derivatives are added - for (unsigned varIdx = 0; varIdx < length_; ++ varIdx) - data_[ varIdx ] += other.data_[ varIdx ]; - + { + for (int i = 0; i < length_; ++i) { + data_[i] += other.data_[i]; + } + return *this; } @@ -169,11 +182,11 @@ public: // subtract other's value and derivatives from this values Evaluation& operator-=(const Evaluation& other) - { - // value and derivatives are subtracted - for (unsigned idx = 0 ; idx < length_ ; ++ idx) - data_[idx] -= other.data_[idx]; - + { + for (int i = 0; i < length_; ++i) { + data_[i] -= other.data_[i]; + } + return *this; } @@ -192,60 +205,78 @@ public: { // while the values are multiplied, the derivatives follow the product rule, // i.e., (u*v)' = (v'u + u'v). - ValueType& u = data_[ valuepos_ ]; - const ValueType& v = other.value(); - for (unsigned idx = dstart_; idx < dend_; ++idx) { - const ValueType& uPrime = data_[idx]; - const ValueType& vPrime = other.data_[idx]; + const ValueType u = this->value(); + const ValueType v = other.value(); - data_[idx] = (v*uPrime + u*vPrime); + // value + data_[valuepos_] *= v ; + + // derivatives + for (int i = dstart_; i < dend_; ++i) { + data_[i] = data_[i] * v + other.data_[i] * u; } - u *= v; return *this; } - // m(u*v)' = (v'u + u'v) + // m(c*u)' = c*u' template - Evaluation& operator*=(RhsValueType other) - { - // values and derivatives are multiplied - for (unsigned idx = 0 ; idx < length_ ; ++ idx) - data_[idx] *= other; - + Evaluation& operator*=(const RhsValueType& other) + { + for (int i = 0; i < length_; ++i) { + data_[i] *= other; + } + 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. - ValueType& u = data_[ valuepos_ ]; - const ValueType& v = other.value(); - for (unsigned idx = dstart_; idx < dend_; ++idx) { - const ValueType& uPrime = data_[idx]; - const ValueType& vPrime = other.data_[idx]; + // 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_[idx] = (v*uPrime - u*vPrime)/(v*v); + // value + data_[valuepos_] *= v_vv; + + // derivatives + for (int i = dstart_; i < dend_; ++i) { + data_[i] = data_[i] * v_vv - other.data_[i] * u_vv; } - u /= v; - + return *this; } - // multiply value and derivatives by value of other + // divide value and derivatives by value of other template Evaluation& operator/=(const RhsValueType& other) { - // values and derivatives are divided - ValueType factor = (1.0/other); - for (unsigned idx = 0; idx < length_; ++idx) - data_[idx] *= factor; - + const ValueType tmp = 1.0/other; + + for (int i = 0; i < length_; ++i) { + data_[i] *= tmp; + } + return *this; } + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + + for (int i = dstart_; i < dend_; ++i) { + result.data_[i] = df_dg * b.data_[i]; + } + + return result; + } + // add two evaluation objects Evaluation operator+(const Evaluation& other) const { @@ -267,8 +298,7 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - result -= other; - return result; + return (result -= other); } // subtract constant from evaluation object @@ -276,18 +306,18 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - result -= other; - return result; + return (result -= other); } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative - for (unsigned idx = 0; idx < length_; ++idx) - result.data_[idx] = - data_[idx]; - + // set value and derivatives to negative + for (int i = 0; i < length_; ++i) { + result.data_[i] = - data_[i]; + } + return result; } @@ -331,8 +361,11 @@ public: // copy assignment from evaluation Evaluation& operator=(const Evaluation& other) - { - data_ = other.data_; + { + for (int i = 0; i < length_; ++i) { + data_[i] = other.data_[i]; + } + return *this; } @@ -342,10 +375,11 @@ public: bool operator==(const Evaluation& other) const { - for (unsigned idx = 0; idx < length_; ++idx) - if (data_[idx] != other.data_[idx]) + for (int idx = 0; idx < length_; ++idx) { + if (data_[idx] != other.data_[idx]) { return false; - + } + } return true; } @@ -385,105 +419,89 @@ public: { return data_[valuepos_]; } // set value of variable - void setValue(const ValueType& val) + template + void setValue(const RhsValueType& val) { data_[valuepos_] = val; } // return varIdx'th derivative - const ValueType& derivative(unsigned varIdx) const + const ValueType& derivative(int varIdx) const { - assert(varIdx < numVars); - return data_[varIdx + dstart_]; + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } // set derivative at position varIdx - void setDerivative(unsigned varIdx, const ValueType& derVal) + void setDerivative(int varIdx, const ValueType& derVal) { - assert(varIdx < numVars); - data_[varIdx + dstart_] = derVal; + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } -protected: - std::array data_; +private: + std::array data_; }; -template + + +template bool operator<(const RhsValueType& a, const Evaluation& b) { return b > a; } -template +template bool operator>(const RhsValueType& a, const Evaluation& b) { return b < a; } -template +template bool operator<=(const RhsValueType& a, const Evaluation& b) { return b >= a; } -template +template bool operator>=(const RhsValueType& a, const Evaluation& b) { return b <= a; } -template +template bool operator!=(const RhsValueType& a, const Evaluation& b) { return a != b.value(); } -template +template Evaluation operator+(const RhsValueType& a, const Evaluation& b) { Evaluation result(b); - result += a; - return result; } -template +template Evaluation operator-(const RhsValueType& a, const Evaluation& b) { - Evaluation result; - - result.setValue(a - b.value()); - for (unsigned varIdx = 0; varIdx < numVars; ++varIdx) - result.setDerivative(varIdx, - b.derivative(varIdx)); - + Evaluation result(a); + result -= b; return result; } -template +template Evaluation operator/(const RhsValueType& a, const Evaluation& b) { - Evaluation result; - - result.setValue(a/b.value()); - - // outer derivative - const ValueType& df_dg = - a/(b.value()*b.value()); - for (unsigned varIdx = 0; varIdx < numVars; ++varIdx) - result.setDerivative(varIdx, df_dg*b.derivative(varIdx)); - - return result; + return Evaluation::divide(a, b); } -template +template Evaluation operator*(const RhsValueType& a, const Evaluation& b) { - Evaluation result; - - result.setValue(a*b.value()); - for (unsigned varIdx = 0; varIdx < numVars; ++varIdx) - result.setDerivative(varIdx, a*b.derivative(varIdx)); - + Evaluation result(b); + result *= a; return result; } -template +template std::ostream& operator<<(std::ostream& os, const Evaluation& eval) { os << eval.value(); return os; } -} // namespace DenseAd -} // namespace Opm +} } // namespace DenseAd, Opm + // In Dune 2.3, the Evaluation.hpp header must be included before the fmatrix.hh // header. Dune 2.4+ does not suffer from this because of some c++-foo. @@ -511,12 +529,12 @@ std::ostream& operator<<(std::ostream& os, const Evaluation& namespace Opm { namespace DenseAd { -template +template Evaluation abs(const Evaluation&); }} namespace std { -template +template const Opm::DenseAd::Evaluation abs(const Opm::DenseAd::Evaluation& x) { return Opm::DenseAd::abs(x); } @@ -535,7 +553,7 @@ const Opm::DenseAd::Evaluation abs(const Opm::DenseAd::Evalu #include namespace Dune { -template +template struct FieldTraits > { public: @@ -547,4 +565,6 @@ public: } // namespace Dune -#endif +#include "EvaluationSpecializations.hpp" + +#endif // OPM_DENSEAD_EVALUATION_HPP diff --git a/opm/material/densead/Evaluation1.hpp b/opm/material/densead/Evaluation1.hpp new file mode 100644 index 000000000..dd6981ea0 --- /dev/null +++ b/opm/material/densead/Evaluation1.hpp @@ -0,0 +1,430 @@ +// -*- 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 . + + 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 1 derivatives. + + * + * \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py" + * SCRIPT. DO NOT EDIT IT MANUALLY! + */ + +#ifndef OPM_DENSEAD_EVALUATION1_HPP +#define OPM_DENSEAD_EVALUATION1_HPP + + +#include "Math.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace DenseAd { + + +template +class Evaluation +{ +public: + //! field type + typedef ValueT ValueType; + + //! number of derivatives + static constexpr int size = 1; + +protected: + //! length of internal data vector + static constexpr int length_ = size + 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_[0] = other.data_[0]; + data_[1] = other.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 + Evaluation(const RhsValueType& c) + { + setValue( c ); + clearDerivatives(); + Valgrind::CheckDefined( data_ ); + } + + // 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 + Evaluation(const RhsValueType& c, int varPos) + { + setValue( c ); + clearDerivatives(); + // The variable position must be in represented by the given variable descriptor + assert(0 <= varPos && varPos < size); + + data_[varPos + dstart_] = 1.0; + Valgrind::CheckDefined(data_); + } + + // set all derivatives to zero + void clearDerivatives() + { + data_[1] = 0.0; + } + + // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) + template + 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 + 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 < size; ++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 + 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) + { + data_[0] -= other.data_[0]; + data_[1] -= other.data_[1]; + + return *this; + } + + // subtract other's value from this values + template + 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) + { + // while the values are multiplied, the derivatives follow the product rule, + // i.e., (u*v)' = (v'u + u'v). + const ValueType u = this->value(); + const ValueType v = other.value(); + + // value + data_[valuepos_] *= v ; + + // derivatives + data_[1] = data_[1] * v + other.data_[1] * u; + + return *this; + } + + // m(c*u)' = c*u' + template + Evaluation& operator*=(const RhsValueType& other) + { + data_[0] *= other; + data_[1] *= other; + + 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; + + // value + data_[valuepos_] *= v_vv; + + // derivatives + data_[1] = data_[1] * v_vv - other.data_[1] * u_vv; + + return *this; + } + + // divide value and derivatives by value of other + template + Evaluation& operator/=(const RhsValueType& other) + { + const ValueType tmp = 1.0/other; + + data_[0] *= tmp; + data_[1] *= tmp; + + return *this; + } + + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + + result.data_[1] = df_dg * b.data_[1]; + + return result; + } + + // add two evaluation objects + Evaluation operator+(const Evaluation& other) const + { + Evaluation result(*this); + result += other; + return result; + } + + // add constant to this object + template + 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); + return (result -= other); + } + + // subtract constant from evaluation object + template + Evaluation operator-(const RhsValueType& other) const + { + Evaluation result(*this); + return (result -= other); + } + + // negation (unary minus) operator + Evaluation operator-() const + { + Evaluation result; + // set value and derivatives to negative + result.data_[0] = - data_[0]; + result.data_[1] = - data_[1]; + + return result; + } + + Evaluation operator*(const Evaluation& other) const + { + Evaluation result(*this); + result *= other; + return result; + } + + template + 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 + Evaluation operator/(const RhsValueType& other) const + { + Evaluation result(*this); + result /= other; + return result; + } + + template + Evaluation& operator=(const RhsValueType& other) + { + setValue( other ); + clearDerivatives(); + return *this; + } + + // copy assignment from evaluation + Evaluation& operator=(const Evaluation& other) + { + data_[0] = other.data_[0]; + data_[1] = other.data_[1]; + + return *this; + } + + template + 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 + bool operator>(RhsValueType other) const + { return value() > other; } + + bool operator>(const Evaluation& other) const + { return value() > other.value(); } + + template + bool operator<(RhsValueType other) const + { return value() < other; } + + bool operator<(const Evaluation& other) const + { return value() < other.value(); } + + template + bool operator>=(RhsValueType other) const + { return value() >= other; } + + bool operator>=(const Evaluation& other) const + { return value() >= other.value(); } + + template + 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 + template + void setValue(const RhsValueType& val) + { data_[valuepos_] = val; } + + // return varIdx'th derivative + const ValueType& derivative(int varIdx) const + { + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; + } + + // set derivative at position varIdx + void setDerivative(int varIdx, const ValueType& derVal) + { + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; + } + +private: + std::array data_; +}; + + + +} } // namespace DenseAd, Opm + + +#endif // OPM_DENSEAD_EVALUATION1_HPP diff --git a/opm/material/densead/Evaluation10.hpp b/opm/material/densead/Evaluation10.hpp new file mode 100644 index 000000000..984c89968 --- /dev/null +++ b/opm/material/densead/Evaluation10.hpp @@ -0,0 +1,538 @@ +// -*- 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 . + + 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 + + +#include "Math.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace DenseAd { + + +template +class Evaluation +{ +public: + //! field type + typedef ValueT ValueType; + + //! number of derivatives + static constexpr int size = 10; + +protected: + //! length of internal data vector + static constexpr int length_ = size + 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_[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]; + } + + // 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 + Evaluation(const RhsValueType& c) + { + setValue( c ); + clearDerivatives(); + Valgrind::CheckDefined( data_ ); + } + + // 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 + Evaluation(const RhsValueType& c, int varPos) + { + setValue( c ); + clearDerivatives(); + // The variable position must be in represented by the given variable descriptor + assert(0 <= varPos && varPos < size); + + data_[varPos + dstart_] = 1.0; + Valgrind::CheckDefined(data_); + } + + // set all derivatives to zero + void clearDerivatives() + { + data_[1] = 0.0; + data_[2] = 0.0; + data_[3] = 0.0; + data_[4] = 0.0; + data_[5] = 0.0; + data_[6] = 0.0; + data_[7] = 0.0; + data_[8] = 0.0; + data_[9] = 0.0; + data_[10] = 0.0; + } + + // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) + template + 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 + 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 < size; ++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]; + } + + + // 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]; + + return *this; + } + + // add value from other to this values + template + 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) + { + 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]; + + return *this; + } + + // subtract other's value from this values + template + 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) + { + // while the values are multiplied, the derivatives follow the product rule, + // i.e., (u*v)' = (v'u + u'v). + const ValueType u = this->value(); + const ValueType v = other.value(); + + // value + data_[valuepos_] *= v ; + + // derivatives + 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; + + return *this; + } + + // m(c*u)' = c*u' + template + Evaluation& operator*=(const RhsValueType& other) + { + 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; + + 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; + + // value + data_[valuepos_] *= v_vv; + + // derivatives + 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; + + return *this; + } + + // divide value and derivatives by value of other + template + Evaluation& operator/=(const RhsValueType& other) + { + const ValueType tmp = 1.0/other; + + data_[0] *= tmp; + data_[1] *= tmp; + data_[2] *= tmp; + data_[3] *= tmp; + data_[4] *= tmp; + data_[5] *= tmp; + data_[6] *= tmp; + data_[7] *= tmp; + data_[8] *= tmp; + data_[9] *= tmp; + data_[10] *= tmp; + + return *this; + } + + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + + 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; + } + + // add two evaluation objects + Evaluation operator+(const Evaluation& other) const + { + Evaluation result(*this); + result += other; + return result; + } + + // add constant to this object + template + 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); + return (result -= other); + } + + // subtract constant from evaluation object + template + Evaluation operator-(const RhsValueType& other) const + { + Evaluation result(*this); + return (result -= other); + } + + // negation (unary minus) operator + Evaluation operator-() const + { + Evaluation result; + // set value and derivatives to negative + result.data_[0] = - data_[0]; + result.data_[1] = - data_[1]; + result.data_[2] = - data_[2]; + result.data_[3] = - data_[3]; + result.data_[4] = - data_[4]; + result.data_[5] = - data_[5]; + result.data_[6] = - data_[6]; + result.data_[7] = - data_[7]; + result.data_[8] = - data_[8]; + result.data_[9] = - data_[9]; + result.data_[10] = - data_[10]; + + return result; + } + + Evaluation operator*(const Evaluation& other) const + { + Evaluation result(*this); + result *= other; + return result; + } + + template + 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 + Evaluation operator/(const RhsValueType& other) const + { + Evaluation result(*this); + result /= other; + return result; + } + + template + Evaluation& operator=(const RhsValueType& other) + { + setValue( other ); + clearDerivatives(); + return *this; + } + + // copy assignment from evaluation + 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]; + + return *this; + } + + template + 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 + bool operator>(RhsValueType other) const + { return value() > other; } + + bool operator>(const Evaluation& other) const + { return value() > other.value(); } + + template + bool operator<(RhsValueType other) const + { return value() < other; } + + bool operator<(const Evaluation& other) const + { return value() < other.value(); } + + template + bool operator>=(RhsValueType other) const + { return value() >= other; } + + bool operator>=(const Evaluation& other) const + { return value() >= other.value(); } + + template + 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 + template + void setValue(const RhsValueType& val) + { data_[valuepos_] = val; } + + // return varIdx'th derivative + const ValueType& derivative(int varIdx) const + { + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; + } + + // set derivative at position varIdx + void setDerivative(int varIdx, const ValueType& derVal) + { + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; + } + +private: + std::array data_; +}; + + + +} } // namespace DenseAd, Opm + + +#endif // OPM_DENSEAD_EVALUATION10_HPP diff --git a/opm/material/densead/Evaluation11.hpp b/opm/material/densead/Evaluation11.hpp new file mode 100644 index 000000000..b595356ce --- /dev/null +++ b/opm/material/densead/Evaluation11.hpp @@ -0,0 +1,550 @@ +// -*- 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 . + + 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 + + +#include "Math.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace DenseAd { + + +template +class Evaluation +{ +public: + //! field type + typedef ValueT ValueType; + + //! number of derivatives + static constexpr int size = 11; + +protected: + //! length of internal data vector + static constexpr int length_ = size + 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_[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]; + } + + // 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 + Evaluation(const RhsValueType& c) + { + setValue( c ); + clearDerivatives(); + Valgrind::CheckDefined( data_ ); + } + + // 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 + Evaluation(const RhsValueType& c, int varPos) + { + setValue( c ); + clearDerivatives(); + // The variable position must be in represented by the given variable descriptor + assert(0 <= varPos && varPos < size); + + data_[varPos + dstart_] = 1.0; + Valgrind::CheckDefined(data_); + } + + // set all derivatives to zero + void clearDerivatives() + { + data_[1] = 0.0; + data_[2] = 0.0; + data_[3] = 0.0; + data_[4] = 0.0; + data_[5] = 0.0; + data_[6] = 0.0; + data_[7] = 0.0; + data_[8] = 0.0; + data_[9] = 0.0; + data_[10] = 0.0; + data_[11] = 0.0; + } + + // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) + template + 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 + 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 < size; ++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]; + } + + + // 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]; + + return *this; + } + + // add value from other to this values + template + 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) + { + 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]; + + return *this; + } + + // subtract other's value from this values + template + 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) + { + // while the values are multiplied, the derivatives follow the product rule, + // i.e., (u*v)' = (v'u + u'v). + const ValueType u = this->value(); + const ValueType v = other.value(); + + // value + data_[valuepos_] *= v ; + + // derivatives + 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; + + return *this; + } + + // m(c*u)' = c*u' + template + Evaluation& operator*=(const RhsValueType& other) + { + 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; + + 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; + + // value + data_[valuepos_] *= v_vv; + + // derivatives + 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; + + return *this; + } + + // divide value and derivatives by value of other + template + Evaluation& operator/=(const RhsValueType& other) + { + const ValueType tmp = 1.0/other; + + data_[0] *= tmp; + data_[1] *= tmp; + data_[2] *= tmp; + data_[3] *= tmp; + data_[4] *= tmp; + data_[5] *= tmp; + data_[6] *= tmp; + data_[7] *= tmp; + data_[8] *= tmp; + data_[9] *= tmp; + data_[10] *= tmp; + data_[11] *= tmp; + + return *this; + } + + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + + 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; + } + + // add two evaluation objects + Evaluation operator+(const Evaluation& other) const + { + Evaluation result(*this); + result += other; + return result; + } + + // add constant to this object + template + 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); + return (result -= other); + } + + // subtract constant from evaluation object + template + Evaluation operator-(const RhsValueType& other) const + { + Evaluation result(*this); + return (result -= other); + } + + // negation (unary minus) operator + Evaluation operator-() const + { + Evaluation result; + // set value and derivatives to negative + result.data_[0] = - data_[0]; + result.data_[1] = - data_[1]; + result.data_[2] = - data_[2]; + result.data_[3] = - data_[3]; + result.data_[4] = - data_[4]; + result.data_[5] = - data_[5]; + result.data_[6] = - data_[6]; + result.data_[7] = - data_[7]; + result.data_[8] = - data_[8]; + result.data_[9] = - data_[9]; + result.data_[10] = - data_[10]; + result.data_[11] = - data_[11]; + + return result; + } + + Evaluation operator*(const Evaluation& other) const + { + Evaluation result(*this); + result *= other; + return result; + } + + template + 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 + Evaluation operator/(const RhsValueType& other) const + { + Evaluation result(*this); + result /= other; + return result; + } + + template + Evaluation& operator=(const RhsValueType& other) + { + setValue( other ); + clearDerivatives(); + return *this; + } + + // copy assignment from evaluation + 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]; + + return *this; + } + + template + 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 + bool operator>(RhsValueType other) const + { return value() > other; } + + bool operator>(const Evaluation& other) const + { return value() > other.value(); } + + template + bool operator<(RhsValueType other) const + { return value() < other; } + + bool operator<(const Evaluation& other) const + { return value() < other.value(); } + + template + bool operator>=(RhsValueType other) const + { return value() >= other; } + + bool operator>=(const Evaluation& other) const + { return value() >= other.value(); } + + template + 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 + template + void setValue(const RhsValueType& val) + { data_[valuepos_] = val; } + + // return varIdx'th derivative + const ValueType& derivative(int varIdx) const + { + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; + } + + // set derivative at position varIdx + void setDerivative(int varIdx, const ValueType& derVal) + { + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; + } + +private: + std::array data_; +}; + + + +} } // namespace DenseAd, Opm + + +#endif // OPM_DENSEAD_EVALUATION11_HPP diff --git a/opm/material/densead/Evaluation12.hpp b/opm/material/densead/Evaluation12.hpp new file mode 100644 index 000000000..caeff8dd7 --- /dev/null +++ b/opm/material/densead/Evaluation12.hpp @@ -0,0 +1,562 @@ +// -*- 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 . + + 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 12 derivatives. + + * + * \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py" + * SCRIPT. DO NOT EDIT IT MANUALLY! + */ + +#ifndef OPM_DENSEAD_EVALUATION12_HPP +#define OPM_DENSEAD_EVALUATION12_HPP + + +#include "Math.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace DenseAd { + + +template +class Evaluation +{ +public: + //! field type + typedef ValueT ValueType; + + //! number of derivatives + static constexpr int size = 12; + +protected: + //! length of internal data vector + static constexpr int length_ = size + 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_[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]; + } + + // 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 + Evaluation(const RhsValueType& c) + { + setValue( c ); + clearDerivatives(); + Valgrind::CheckDefined( data_ ); + } + + // 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 + Evaluation(const RhsValueType& c, int varPos) + { + setValue( c ); + clearDerivatives(); + // The variable position must be in represented by the given variable descriptor + assert(0 <= varPos && varPos < size); + + data_[varPos + dstart_] = 1.0; + Valgrind::CheckDefined(data_); + } + + // set all derivatives to zero + void clearDerivatives() + { + data_[1] = 0.0; + data_[2] = 0.0; + data_[3] = 0.0; + data_[4] = 0.0; + data_[5] = 0.0; + data_[6] = 0.0; + data_[7] = 0.0; + data_[8] = 0.0; + data_[9] = 0.0; + data_[10] = 0.0; + data_[11] = 0.0; + data_[12] = 0.0; + } + + // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) + template + 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 + 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 < size; ++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 + 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) + { + 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 + 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) + { + // while the values are multiplied, the derivatives follow the product rule, + // i.e., (u*v)' = (v'u + u'v). + const ValueType u = this->value(); + const ValueType v = other.value(); + + // value + data_[valuepos_] *= v ; + + // derivatives + 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; + + return *this; + } + + // m(c*u)' = c*u' + template + Evaluation& operator*=(const RhsValueType& other) + { + 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; + + 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; + + // value + data_[valuepos_] *= v_vv; + + // derivatives + 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; + } + + // divide value and derivatives by value of other + template + Evaluation& operator/=(const RhsValueType& other) + { + const ValueType tmp = 1.0/other; + + data_[0] *= tmp; + data_[1] *= tmp; + data_[2] *= tmp; + data_[3] *= tmp; + data_[4] *= tmp; + data_[5] *= tmp; + data_[6] *= tmp; + data_[7] *= tmp; + data_[8] *= tmp; + data_[9] *= tmp; + data_[10] *= tmp; + data_[11] *= tmp; + data_[12] *= tmp; + + return *this; + } + + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + + 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; + } + + // add two evaluation objects + Evaluation operator+(const Evaluation& other) const + { + Evaluation result(*this); + result += other; + return result; + } + + // add constant to this object + template + 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); + return (result -= other); + } + + // subtract constant from evaluation object + template + Evaluation operator-(const RhsValueType& other) const + { + Evaluation result(*this); + return (result -= other); + } + + // negation (unary minus) operator + Evaluation operator-() const + { + Evaluation result; + // set value and derivatives to negative + result.data_[0] = - data_[0]; + result.data_[1] = - data_[1]; + result.data_[2] = - data_[2]; + result.data_[3] = - data_[3]; + result.data_[4] = - data_[4]; + result.data_[5] = - data_[5]; + result.data_[6] = - data_[6]; + result.data_[7] = - data_[7]; + result.data_[8] = - data_[8]; + result.data_[9] = - data_[9]; + result.data_[10] = - data_[10]; + result.data_[11] = - data_[11]; + result.data_[12] = - data_[12]; + + return result; + } + + Evaluation operator*(const Evaluation& other) const + { + Evaluation result(*this); + result *= other; + return result; + } + + template + 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 + Evaluation operator/(const RhsValueType& other) const + { + Evaluation result(*this); + result /= other; + return result; + } + + template + Evaluation& operator=(const RhsValueType& other) + { + setValue( other ); + clearDerivatives(); + return *this; + } + + // copy assignment from evaluation + 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; + } + + template + 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 + bool operator>(RhsValueType other) const + { return value() > other; } + + bool operator>(const Evaluation& other) const + { return value() > other.value(); } + + template + bool operator<(RhsValueType other) const + { return value() < other; } + + bool operator<(const Evaluation& other) const + { return value() < other.value(); } + + template + bool operator>=(RhsValueType other) const + { return value() >= other; } + + bool operator>=(const Evaluation& other) const + { return value() >= other.value(); } + + template + 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 + template + void setValue(const RhsValueType& val) + { data_[valuepos_] = val; } + + // return varIdx'th derivative + const ValueType& derivative(int varIdx) const + { + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; + } + + // set derivative at position varIdx + void setDerivative(int varIdx, const ValueType& derVal) + { + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; + } + +private: + std::array data_; +}; + + + +} } // namespace DenseAd, Opm + + +#endif // OPM_DENSEAD_EVALUATION12_HPP diff --git a/opm/material/densead/Evaluation2.hpp b/opm/material/densead/Evaluation2.hpp new file mode 100644 index 000000000..fdfcb7ee7 --- /dev/null +++ b/opm/material/densead/Evaluation2.hpp @@ -0,0 +1,442 @@ +// -*- 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 . + + 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 2 derivatives. + + * + * \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py" + * SCRIPT. DO NOT EDIT IT MANUALLY! + */ + +#ifndef OPM_DENSEAD_EVALUATION2_HPP +#define OPM_DENSEAD_EVALUATION2_HPP + + +#include "Math.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace DenseAd { + + +template +class Evaluation +{ +public: + //! field type + typedef ValueT ValueType; + + //! number of derivatives + static constexpr int size = 2; + +protected: + //! length of internal data vector + static constexpr int length_ = size + 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_[0] = other.data_[0]; + data_[1] = other.data_[1]; + data_[2] = other.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 + Evaluation(const RhsValueType& c) + { + setValue( c ); + clearDerivatives(); + Valgrind::CheckDefined( data_ ); + } + + // 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 + Evaluation(const RhsValueType& c, int varPos) + { + setValue( c ); + clearDerivatives(); + // The variable position must be in represented by the given variable descriptor + assert(0 <= varPos && varPos < size); + + data_[varPos + dstart_] = 1.0; + Valgrind::CheckDefined(data_); + } + + // set all derivatives to zero + void clearDerivatives() + { + data_[1] = 0.0; + data_[2] = 0.0; + } + + // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) + template + 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 + 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 < size; ++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 + 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) + { + 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 + 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) + { + // while the values are multiplied, the derivatives follow the product rule, + // i.e., (u*v)' = (v'u + u'v). + const ValueType u = this->value(); + const ValueType v = other.value(); + + // value + data_[valuepos_] *= v ; + + // derivatives + data_[1] = data_[1] * v + other.data_[1] * u; + data_[2] = data_[2] * v + other.data_[2] * u; + + return *this; + } + + // m(c*u)' = c*u' + template + Evaluation& operator*=(const RhsValueType& other) + { + data_[0] *= other; + data_[1] *= other; + data_[2] *= other; + + 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; + + // value + data_[valuepos_] *= v_vv; + + // derivatives + data_[1] = data_[1] * v_vv - other.data_[1] * u_vv; + data_[2] = data_[2] * v_vv - other.data_[2] * u_vv; + + return *this; + } + + // divide value and derivatives by value of other + template + Evaluation& operator/=(const RhsValueType& other) + { + const ValueType tmp = 1.0/other; + + data_[0] *= tmp; + data_[1] *= tmp; + data_[2] *= tmp; + + return *this; + } + + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + + result.data_[1] = df_dg * b.data_[1]; + result.data_[2] = df_dg * b.data_[2]; + + return result; + } + + // add two evaluation objects + Evaluation operator+(const Evaluation& other) const + { + Evaluation result(*this); + result += other; + return result; + } + + // add constant to this object + template + 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); + return (result -= other); + } + + // subtract constant from evaluation object + template + Evaluation operator-(const RhsValueType& other) const + { + Evaluation result(*this); + return (result -= other); + } + + // negation (unary minus) operator + Evaluation operator-() const + { + Evaluation result; + // set value and derivatives to negative + result.data_[0] = - data_[0]; + result.data_[1] = - data_[1]; + result.data_[2] = - data_[2]; + + return result; + } + + Evaluation operator*(const Evaluation& other) const + { + Evaluation result(*this); + result *= other; + return result; + } + + template + 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 + Evaluation operator/(const RhsValueType& other) const + { + Evaluation result(*this); + result /= other; + return result; + } + + template + Evaluation& operator=(const RhsValueType& other) + { + setValue( other ); + clearDerivatives(); + return *this; + } + + // copy assignment from evaluation + Evaluation& operator=(const Evaluation& other) + { + data_[0] = other.data_[0]; + data_[1] = other.data_[1]; + data_[2] = other.data_[2]; + + return *this; + } + + template + 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 + bool operator>(RhsValueType other) const + { return value() > other; } + + bool operator>(const Evaluation& other) const + { return value() > other.value(); } + + template + bool operator<(RhsValueType other) const + { return value() < other; } + + bool operator<(const Evaluation& other) const + { return value() < other.value(); } + + template + bool operator>=(RhsValueType other) const + { return value() >= other; } + + bool operator>=(const Evaluation& other) const + { return value() >= other.value(); } + + template + 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 + template + void setValue(const RhsValueType& val) + { data_[valuepos_] = val; } + + // return varIdx'th derivative + const ValueType& derivative(int varIdx) const + { + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; + } + + // set derivative at position varIdx + void setDerivative(int varIdx, const ValueType& derVal) + { + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; + } + +private: + std::array data_; +}; + + + +} } // namespace DenseAd, Opm + + +#endif // OPM_DENSEAD_EVALUATION2_HPP diff --git a/opm/material/densead/Evaluation3.hpp b/opm/material/densead/Evaluation3.hpp new file mode 100644 index 000000000..f31ca52e5 --- /dev/null +++ b/opm/material/densead/Evaluation3.hpp @@ -0,0 +1,454 @@ +// -*- 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 . + + 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 3 derivatives. + + * + * \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py" + * SCRIPT. DO NOT EDIT IT MANUALLY! + */ + +#ifndef OPM_DENSEAD_EVALUATION3_HPP +#define OPM_DENSEAD_EVALUATION3_HPP + + +#include "Math.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace DenseAd { + + +template +class Evaluation +{ +public: + //! field type + typedef ValueT ValueType; + + //! number of derivatives + static constexpr int size = 3; + +protected: + //! length of internal data vector + static constexpr int length_ = size + 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_[0] = other.data_[0]; + data_[1] = other.data_[1]; + data_[2] = other.data_[2]; + data_[3] = other.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 + Evaluation(const RhsValueType& c) + { + setValue( c ); + clearDerivatives(); + Valgrind::CheckDefined( data_ ); + } + + // 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 + Evaluation(const RhsValueType& c, int varPos) + { + setValue( c ); + clearDerivatives(); + // The variable position must be in represented by the given variable descriptor + assert(0 <= varPos && varPos < size); + + data_[varPos + dstart_] = 1.0; + Valgrind::CheckDefined(data_); + } + + // set all derivatives to zero + void clearDerivatives() + { + data_[1] = 0.0; + data_[2] = 0.0; + data_[3] = 0.0; + } + + // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) + template + 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 + 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 < size; ++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 + 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) + { + 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 + 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) + { + // while the values are multiplied, the derivatives follow the product rule, + // i.e., (u*v)' = (v'u + u'v). + const ValueType u = this->value(); + const ValueType v = other.value(); + + // value + data_[valuepos_] *= v ; + + // derivatives + 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; + + return *this; + } + + // m(c*u)' = c*u' + template + Evaluation& operator*=(const RhsValueType& other) + { + data_[0] *= other; + data_[1] *= other; + data_[2] *= other; + data_[3] *= other; + + 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; + + // value + data_[valuepos_] *= v_vv; + + // derivatives + 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; + } + + // divide value and derivatives by value of other + template + Evaluation& operator/=(const RhsValueType& other) + { + const ValueType tmp = 1.0/other; + + data_[0] *= tmp; + data_[1] *= tmp; + data_[2] *= tmp; + data_[3] *= tmp; + + return *this; + } + + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + + 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; + } + + // add two evaluation objects + Evaluation operator+(const Evaluation& other) const + { + Evaluation result(*this); + result += other; + return result; + } + + // add constant to this object + template + 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); + return (result -= other); + } + + // subtract constant from evaluation object + template + Evaluation operator-(const RhsValueType& other) const + { + Evaluation result(*this); + return (result -= other); + } + + // negation (unary minus) operator + Evaluation operator-() const + { + Evaluation result; + // set value and derivatives to negative + result.data_[0] = - data_[0]; + result.data_[1] = - data_[1]; + result.data_[2] = - data_[2]; + result.data_[3] = - data_[3]; + + return result; + } + + Evaluation operator*(const Evaluation& other) const + { + Evaluation result(*this); + result *= other; + return result; + } + + template + 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 + Evaluation operator/(const RhsValueType& other) const + { + Evaluation result(*this); + result /= other; + return result; + } + + template + Evaluation& operator=(const RhsValueType& other) + { + setValue( other ); + clearDerivatives(); + return *this; + } + + // copy assignment from evaluation + 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; + } + + template + 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 + bool operator>(RhsValueType other) const + { return value() > other; } + + bool operator>(const Evaluation& other) const + { return value() > other.value(); } + + template + bool operator<(RhsValueType other) const + { return value() < other; } + + bool operator<(const Evaluation& other) const + { return value() < other.value(); } + + template + bool operator>=(RhsValueType other) const + { return value() >= other; } + + bool operator>=(const Evaluation& other) const + { return value() >= other.value(); } + + template + 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 + template + void setValue(const RhsValueType& val) + { data_[valuepos_] = val; } + + // return varIdx'th derivative + const ValueType& derivative(int varIdx) const + { + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; + } + + // set derivative at position varIdx + void setDerivative(int varIdx, const ValueType& derVal) + { + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; + } + +private: + std::array data_; +}; + + + +} } // namespace DenseAd, Opm + + +#endif // OPM_DENSEAD_EVALUATION3_HPP diff --git a/opm/material/densead/Evaluation4.hpp b/opm/material/densead/Evaluation4.hpp new file mode 100644 index 000000000..b703d8ab2 --- /dev/null +++ b/opm/material/densead/Evaluation4.hpp @@ -0,0 +1,466 @@ +// -*- 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 . + + 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 + + +#include "Math.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace DenseAd { + + +template +class Evaluation +{ +public: + //! field type + typedef ValueT ValueType; + + //! number of derivatives + static constexpr int size = 4; + +protected: + //! length of internal data vector + static constexpr int length_ = size + 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_[0] = other.data_[0]; + data_[1] = other.data_[1]; + data_[2] = other.data_[2]; + data_[3] = other.data_[3]; + data_[4] = other.data_[4]; + } + + // 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 + Evaluation(const RhsValueType& c) + { + setValue( c ); + clearDerivatives(); + Valgrind::CheckDefined( data_ ); + } + + // 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 + Evaluation(const RhsValueType& c, int varPos) + { + setValue( c ); + clearDerivatives(); + // The variable position must be in represented by the given variable descriptor + assert(0 <= varPos && varPos < size); + + data_[varPos + dstart_] = 1.0; + Valgrind::CheckDefined(data_); + } + + // set all derivatives to zero + void clearDerivatives() + { + data_[1] = 0.0; + data_[2] = 0.0; + data_[3] = 0.0; + data_[4] = 0.0; + } + + // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) + template + 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 + 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 < size; ++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]; + } + + + // 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]; + + return *this; + } + + // add value from other to this values + template + 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) + { + 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]; + + return *this; + } + + // subtract other's value from this values + template + 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) + { + // while the values are multiplied, the derivatives follow the product rule, + // i.e., (u*v)' = (v'u + u'v). + const ValueType u = this->value(); + const ValueType v = other.value(); + + // value + data_[valuepos_] *= v ; + + // derivatives + 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; + + return *this; + } + + // m(c*u)' = c*u' + template + Evaluation& operator*=(const RhsValueType& other) + { + data_[0] *= other; + data_[1] *= other; + data_[2] *= other; + data_[3] *= other; + data_[4] *= other; + + 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; + + // value + data_[valuepos_] *= v_vv; + + // derivatives + 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; + + return *this; + } + + // divide value and derivatives by value of other + template + Evaluation& operator/=(const RhsValueType& other) + { + const ValueType tmp = 1.0/other; + + data_[0] *= tmp; + data_[1] *= tmp; + data_[2] *= tmp; + data_[3] *= tmp; + data_[4] *= tmp; + + return *this; + } + + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + + 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; + } + + // add two evaluation objects + Evaluation operator+(const Evaluation& other) const + { + Evaluation result(*this); + result += other; + return result; + } + + // add constant to this object + template + 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); + return (result -= other); + } + + // subtract constant from evaluation object + template + Evaluation operator-(const RhsValueType& other) const + { + Evaluation result(*this); + return (result -= other); + } + + // negation (unary minus) operator + Evaluation operator-() const + { + Evaluation result; + // set value and derivatives to negative + result.data_[0] = - data_[0]; + result.data_[1] = - data_[1]; + result.data_[2] = - data_[2]; + result.data_[3] = - data_[3]; + result.data_[4] = - data_[4]; + + return result; + } + + Evaluation operator*(const Evaluation& other) const + { + Evaluation result(*this); + result *= other; + return result; + } + + template + 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 + Evaluation operator/(const RhsValueType& other) const + { + Evaluation result(*this); + result /= other; + return result; + } + + template + Evaluation& operator=(const RhsValueType& other) + { + setValue( other ); + clearDerivatives(); + return *this; + } + + // copy assignment from evaluation + 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]; + + return *this; + } + + template + 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 + bool operator>(RhsValueType other) const + { return value() > other; } + + bool operator>(const Evaluation& other) const + { return value() > other.value(); } + + template + bool operator<(RhsValueType other) const + { return value() < other; } + + bool operator<(const Evaluation& other) const + { return value() < other.value(); } + + template + bool operator>=(RhsValueType other) const + { return value() >= other; } + + bool operator>=(const Evaluation& other) const + { return value() >= other.value(); } + + template + 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 + template + void setValue(const RhsValueType& val) + { data_[valuepos_] = val; } + + // return varIdx'th derivative + const ValueType& derivative(int varIdx) const + { + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; + } + + // set derivative at position varIdx + void setDerivative(int varIdx, const ValueType& derVal) + { + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; + } + +private: + std::array data_; +}; + + + +} } // namespace DenseAd, Opm + + +#endif // OPM_DENSEAD_EVALUATION4_HPP diff --git a/opm/material/densead/Evaluation5.hpp b/opm/material/densead/Evaluation5.hpp new file mode 100644 index 000000000..230e1dc7f --- /dev/null +++ b/opm/material/densead/Evaluation5.hpp @@ -0,0 +1,478 @@ +// -*- 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 . + + 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 + + +#include "Math.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace DenseAd { + + +template +class Evaluation +{ +public: + //! field type + typedef ValueT ValueType; + + //! number of derivatives + static constexpr int size = 5; + +protected: + //! length of internal data vector + static constexpr int length_ = size + 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_[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]; + } + + // 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 + Evaluation(const RhsValueType& c) + { + setValue( c ); + clearDerivatives(); + Valgrind::CheckDefined( data_ ); + } + + // 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 + Evaluation(const RhsValueType& c, int varPos) + { + setValue( c ); + clearDerivatives(); + // The variable position must be in represented by the given variable descriptor + assert(0 <= varPos && varPos < size); + + data_[varPos + dstart_] = 1.0; + Valgrind::CheckDefined(data_); + } + + // set all derivatives to zero + void clearDerivatives() + { + data_[1] = 0.0; + data_[2] = 0.0; + data_[3] = 0.0; + data_[4] = 0.0; + data_[5] = 0.0; + } + + // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) + template + 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 + 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 < size; ++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]; + } + + + // 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]; + + return *this; + } + + // add value from other to this values + template + 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) + { + 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]; + + return *this; + } + + // subtract other's value from this values + template + 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) + { + // while the values are multiplied, the derivatives follow the product rule, + // i.e., (u*v)' = (v'u + u'v). + const ValueType u = this->value(); + const ValueType v = other.value(); + + // value + data_[valuepos_] *= v ; + + // derivatives + 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; + + return *this; + } + + // m(c*u)' = c*u' + template + Evaluation& operator*=(const RhsValueType& other) + { + data_[0] *= other; + data_[1] *= other; + data_[2] *= other; + data_[3] *= other; + data_[4] *= other; + data_[5] *= other; + + 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; + + // value + data_[valuepos_] *= v_vv; + + // derivatives + 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; + + return *this; + } + + // divide value and derivatives by value of other + template + Evaluation& operator/=(const RhsValueType& other) + { + const ValueType tmp = 1.0/other; + + data_[0] *= tmp; + data_[1] *= tmp; + data_[2] *= tmp; + data_[3] *= tmp; + data_[4] *= tmp; + data_[5] *= tmp; + + return *this; + } + + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + + 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; + } + + // add two evaluation objects + Evaluation operator+(const Evaluation& other) const + { + Evaluation result(*this); + result += other; + return result; + } + + // add constant to this object + template + 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); + return (result -= other); + } + + // subtract constant from evaluation object + template + Evaluation operator-(const RhsValueType& other) const + { + Evaluation result(*this); + return (result -= other); + } + + // negation (unary minus) operator + Evaluation operator-() const + { + Evaluation result; + // set value and derivatives to negative + result.data_[0] = - data_[0]; + result.data_[1] = - data_[1]; + result.data_[2] = - data_[2]; + result.data_[3] = - data_[3]; + result.data_[4] = - data_[4]; + result.data_[5] = - data_[5]; + + return result; + } + + Evaluation operator*(const Evaluation& other) const + { + Evaluation result(*this); + result *= other; + return result; + } + + template + 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 + Evaluation operator/(const RhsValueType& other) const + { + Evaluation result(*this); + result /= other; + return result; + } + + template + Evaluation& operator=(const RhsValueType& other) + { + setValue( other ); + clearDerivatives(); + return *this; + } + + // copy assignment from evaluation + 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]; + + return *this; + } + + template + 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 + bool operator>(RhsValueType other) const + { return value() > other; } + + bool operator>(const Evaluation& other) const + { return value() > other.value(); } + + template + bool operator<(RhsValueType other) const + { return value() < other; } + + bool operator<(const Evaluation& other) const + { return value() < other.value(); } + + template + bool operator>=(RhsValueType other) const + { return value() >= other; } + + bool operator>=(const Evaluation& other) const + { return value() >= other.value(); } + + template + 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 + template + void setValue(const RhsValueType& val) + { data_[valuepos_] = val; } + + // return varIdx'th derivative + const ValueType& derivative(int varIdx) const + { + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; + } + + // set derivative at position varIdx + void setDerivative(int varIdx, const ValueType& derVal) + { + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; + } + +private: + std::array data_; +}; + + + +} } // namespace DenseAd, Opm + + +#endif // OPM_DENSEAD_EVALUATION5_HPP diff --git a/opm/material/densead/Evaluation6.hpp b/opm/material/densead/Evaluation6.hpp new file mode 100644 index 000000000..25a13984c --- /dev/null +++ b/opm/material/densead/Evaluation6.hpp @@ -0,0 +1,490 @@ +// -*- 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 . + + 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 6 derivatives. + + * + * \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py" + * SCRIPT. DO NOT EDIT IT MANUALLY! + */ + +#ifndef OPM_DENSEAD_EVALUATION6_HPP +#define OPM_DENSEAD_EVALUATION6_HPP + + +#include "Math.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace DenseAd { + + +template +class Evaluation +{ +public: + //! field type + typedef ValueT ValueType; + + //! number of derivatives + static constexpr int size = 6; + +protected: + //! length of internal data vector + static constexpr int length_ = size + 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_[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]; + } + + // 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 + Evaluation(const RhsValueType& c) + { + setValue( c ); + clearDerivatives(); + Valgrind::CheckDefined( data_ ); + } + + // 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 + Evaluation(const RhsValueType& c, int varPos) + { + setValue( c ); + clearDerivatives(); + // The variable position must be in represented by the given variable descriptor + assert(0 <= varPos && varPos < size); + + data_[varPos + dstart_] = 1.0; + Valgrind::CheckDefined(data_); + } + + // set all derivatives to zero + void clearDerivatives() + { + data_[1] = 0.0; + data_[2] = 0.0; + data_[3] = 0.0; + data_[4] = 0.0; + data_[5] = 0.0; + data_[6] = 0.0; + } + + // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) + template + 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 + 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 < size; ++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 + 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) + { + 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 + 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) + { + // while the values are multiplied, the derivatives follow the product rule, + // i.e., (u*v)' = (v'u + u'v). + const ValueType u = this->value(); + const ValueType v = other.value(); + + // value + data_[valuepos_] *= v ; + + // derivatives + 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; + + return *this; + } + + // m(c*u)' = c*u' + template + Evaluation& operator*=(const RhsValueType& other) + { + data_[0] *= other; + data_[1] *= other; + data_[2] *= other; + data_[3] *= other; + data_[4] *= other; + data_[5] *= other; + data_[6] *= other; + + 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; + + // value + data_[valuepos_] *= v_vv; + + // derivatives + 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; + } + + // divide value and derivatives by value of other + template + Evaluation& operator/=(const RhsValueType& other) + { + const ValueType tmp = 1.0/other; + + data_[0] *= tmp; + data_[1] *= tmp; + data_[2] *= tmp; + data_[3] *= tmp; + data_[4] *= tmp; + data_[5] *= tmp; + data_[6] *= tmp; + + return *this; + } + + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + + 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; + } + + // add two evaluation objects + Evaluation operator+(const Evaluation& other) const + { + Evaluation result(*this); + result += other; + return result; + } + + // add constant to this object + template + 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); + return (result -= other); + } + + // subtract constant from evaluation object + template + Evaluation operator-(const RhsValueType& other) const + { + Evaluation result(*this); + return (result -= other); + } + + // negation (unary minus) operator + Evaluation operator-() const + { + Evaluation result; + // set value and derivatives to negative + result.data_[0] = - data_[0]; + result.data_[1] = - data_[1]; + result.data_[2] = - data_[2]; + result.data_[3] = - data_[3]; + result.data_[4] = - data_[4]; + result.data_[5] = - data_[5]; + result.data_[6] = - data_[6]; + + return result; + } + + Evaluation operator*(const Evaluation& other) const + { + Evaluation result(*this); + result *= other; + return result; + } + + template + 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 + Evaluation operator/(const RhsValueType& other) const + { + Evaluation result(*this); + result /= other; + return result; + } + + template + Evaluation& operator=(const RhsValueType& other) + { + setValue( other ); + clearDerivatives(); + return *this; + } + + // copy assignment from evaluation + 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; + } + + template + 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 + bool operator>(RhsValueType other) const + { return value() > other; } + + bool operator>(const Evaluation& other) const + { return value() > other.value(); } + + template + bool operator<(RhsValueType other) const + { return value() < other; } + + bool operator<(const Evaluation& other) const + { return value() < other.value(); } + + template + bool operator>=(RhsValueType other) const + { return value() >= other; } + + bool operator>=(const Evaluation& other) const + { return value() >= other.value(); } + + template + 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 + template + void setValue(const RhsValueType& val) + { data_[valuepos_] = val; } + + // return varIdx'th derivative + const ValueType& derivative(int varIdx) const + { + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; + } + + // set derivative at position varIdx + void setDerivative(int varIdx, const ValueType& derVal) + { + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; + } + +private: + std::array data_; +}; + + + +} } // namespace DenseAd, Opm + + +#endif // OPM_DENSEAD_EVALUATION6_HPP diff --git a/opm/material/densead/Evaluation7.hpp b/opm/material/densead/Evaluation7.hpp new file mode 100644 index 000000000..72ebd2458 --- /dev/null +++ b/opm/material/densead/Evaluation7.hpp @@ -0,0 +1,502 @@ +// -*- 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 . + + 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 + + +#include "Math.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace DenseAd { + + +template +class Evaluation +{ +public: + //! field type + typedef ValueT ValueType; + + //! number of derivatives + static constexpr int size = 7; + +protected: + //! length of internal data vector + static constexpr int length_ = size + 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_[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]; + } + + // 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 + Evaluation(const RhsValueType& c) + { + setValue( c ); + clearDerivatives(); + Valgrind::CheckDefined( data_ ); + } + + // 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 + Evaluation(const RhsValueType& c, int varPos) + { + setValue( c ); + clearDerivatives(); + // The variable position must be in represented by the given variable descriptor + assert(0 <= varPos && varPos < size); + + data_[varPos + dstart_] = 1.0; + Valgrind::CheckDefined(data_); + } + + // set all derivatives to zero + void clearDerivatives() + { + data_[1] = 0.0; + data_[2] = 0.0; + data_[3] = 0.0; + data_[4] = 0.0; + data_[5] = 0.0; + data_[6] = 0.0; + data_[7] = 0.0; + } + + // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) + template + 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 + 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 < size; ++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]; + } + + + // 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]; + + return *this; + } + + // add value from other to this values + template + 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) + { + 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]; + + return *this; + } + + // subtract other's value from this values + template + 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) + { + // while the values are multiplied, the derivatives follow the product rule, + // i.e., (u*v)' = (v'u + u'v). + const ValueType u = this->value(); + const ValueType v = other.value(); + + // value + data_[valuepos_] *= v ; + + // derivatives + 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; + + return *this; + } + + // m(c*u)' = c*u' + template + Evaluation& operator*=(const RhsValueType& other) + { + data_[0] *= other; + data_[1] *= other; + data_[2] *= other; + data_[3] *= other; + data_[4] *= other; + data_[5] *= other; + data_[6] *= other; + data_[7] *= other; + + 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; + + // value + data_[valuepos_] *= v_vv; + + // derivatives + 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; + + return *this; + } + + // divide value and derivatives by value of other + template + Evaluation& operator/=(const RhsValueType& other) + { + const ValueType tmp = 1.0/other; + + data_[0] *= tmp; + data_[1] *= tmp; + data_[2] *= tmp; + data_[3] *= tmp; + data_[4] *= tmp; + data_[5] *= tmp; + data_[6] *= tmp; + data_[7] *= tmp; + + return *this; + } + + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + + 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; + } + + // add two evaluation objects + Evaluation operator+(const Evaluation& other) const + { + Evaluation result(*this); + result += other; + return result; + } + + // add constant to this object + template + 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); + return (result -= other); + } + + // subtract constant from evaluation object + template + Evaluation operator-(const RhsValueType& other) const + { + Evaluation result(*this); + return (result -= other); + } + + // negation (unary minus) operator + Evaluation operator-() const + { + Evaluation result; + // set value and derivatives to negative + result.data_[0] = - data_[0]; + result.data_[1] = - data_[1]; + result.data_[2] = - data_[2]; + result.data_[3] = - data_[3]; + result.data_[4] = - data_[4]; + result.data_[5] = - data_[5]; + result.data_[6] = - data_[6]; + result.data_[7] = - data_[7]; + + return result; + } + + Evaluation operator*(const Evaluation& other) const + { + Evaluation result(*this); + result *= other; + return result; + } + + template + 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 + Evaluation operator/(const RhsValueType& other) const + { + Evaluation result(*this); + result /= other; + return result; + } + + template + Evaluation& operator=(const RhsValueType& other) + { + setValue( other ); + clearDerivatives(); + return *this; + } + + // copy assignment from evaluation + 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]; + + return *this; + } + + template + 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 + bool operator>(RhsValueType other) const + { return value() > other; } + + bool operator>(const Evaluation& other) const + { return value() > other.value(); } + + template + bool operator<(RhsValueType other) const + { return value() < other; } + + bool operator<(const Evaluation& other) const + { return value() < other.value(); } + + template + bool operator>=(RhsValueType other) const + { return value() >= other; } + + bool operator>=(const Evaluation& other) const + { return value() >= other.value(); } + + template + 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 + template + void setValue(const RhsValueType& val) + { data_[valuepos_] = val; } + + // return varIdx'th derivative + const ValueType& derivative(int varIdx) const + { + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; + } + + // set derivative at position varIdx + void setDerivative(int varIdx, const ValueType& derVal) + { + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; + } + +private: + std::array data_; +}; + + + +} } // namespace DenseAd, Opm + + +#endif // OPM_DENSEAD_EVALUATION7_HPP diff --git a/opm/material/densead/Evaluation8.hpp b/opm/material/densead/Evaluation8.hpp new file mode 100644 index 000000000..030283af5 --- /dev/null +++ b/opm/material/densead/Evaluation8.hpp @@ -0,0 +1,514 @@ +// -*- 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 . + + 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 + + +#include "Math.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace DenseAd { + + +template +class Evaluation +{ +public: + //! field type + typedef ValueT ValueType; + + //! number of derivatives + static constexpr int size = 8; + +protected: + //! length of internal data vector + static constexpr int length_ = size + 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_[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]; + } + + // 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 + Evaluation(const RhsValueType& c) + { + setValue( c ); + clearDerivatives(); + Valgrind::CheckDefined( data_ ); + } + + // 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 + Evaluation(const RhsValueType& c, int varPos) + { + setValue( c ); + clearDerivatives(); + // The variable position must be in represented by the given variable descriptor + assert(0 <= varPos && varPos < size); + + data_[varPos + dstart_] = 1.0; + Valgrind::CheckDefined(data_); + } + + // set all derivatives to zero + void clearDerivatives() + { + data_[1] = 0.0; + data_[2] = 0.0; + data_[3] = 0.0; + data_[4] = 0.0; + data_[5] = 0.0; + data_[6] = 0.0; + data_[7] = 0.0; + data_[8] = 0.0; + } + + // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) + template + 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 + 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 < size; ++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]; + } + + + // 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]; + + return *this; + } + + // add value from other to this values + template + 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) + { + 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]; + + return *this; + } + + // subtract other's value from this values + template + 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) + { + // while the values are multiplied, the derivatives follow the product rule, + // i.e., (u*v)' = (v'u + u'v). + const ValueType u = this->value(); + const ValueType v = other.value(); + + // value + data_[valuepos_] *= v ; + + // derivatives + 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; + + return *this; + } + + // m(c*u)' = c*u' + template + Evaluation& operator*=(const RhsValueType& other) + { + 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; + + 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; + + // value + data_[valuepos_] *= v_vv; + + // derivatives + 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; + + return *this; + } + + // divide value and derivatives by value of other + template + Evaluation& operator/=(const RhsValueType& other) + { + const ValueType tmp = 1.0/other; + + data_[0] *= tmp; + data_[1] *= tmp; + data_[2] *= tmp; + data_[3] *= tmp; + data_[4] *= tmp; + data_[5] *= tmp; + data_[6] *= tmp; + data_[7] *= tmp; + data_[8] *= tmp; + + return *this; + } + + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + + 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; + } + + // add two evaluation objects + Evaluation operator+(const Evaluation& other) const + { + Evaluation result(*this); + result += other; + return result; + } + + // add constant to this object + template + 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); + return (result -= other); + } + + // subtract constant from evaluation object + template + Evaluation operator-(const RhsValueType& other) const + { + Evaluation result(*this); + return (result -= other); + } + + // negation (unary minus) operator + Evaluation operator-() const + { + Evaluation result; + // set value and derivatives to negative + result.data_[0] = - data_[0]; + result.data_[1] = - data_[1]; + result.data_[2] = - data_[2]; + result.data_[3] = - data_[3]; + result.data_[4] = - data_[4]; + result.data_[5] = - data_[5]; + result.data_[6] = - data_[6]; + result.data_[7] = - data_[7]; + result.data_[8] = - data_[8]; + + return result; + } + + Evaluation operator*(const Evaluation& other) const + { + Evaluation result(*this); + result *= other; + return result; + } + + template + 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 + Evaluation operator/(const RhsValueType& other) const + { + Evaluation result(*this); + result /= other; + return result; + } + + template + Evaluation& operator=(const RhsValueType& other) + { + setValue( other ); + clearDerivatives(); + return *this; + } + + // copy assignment from evaluation + 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]; + + return *this; + } + + template + 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 + bool operator>(RhsValueType other) const + { return value() > other; } + + bool operator>(const Evaluation& other) const + { return value() > other.value(); } + + template + bool operator<(RhsValueType other) const + { return value() < other; } + + bool operator<(const Evaluation& other) const + { return value() < other.value(); } + + template + bool operator>=(RhsValueType other) const + { return value() >= other; } + + bool operator>=(const Evaluation& other) const + { return value() >= other.value(); } + + template + 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 + template + void setValue(const RhsValueType& val) + { data_[valuepos_] = val; } + + // return varIdx'th derivative + const ValueType& derivative(int varIdx) const + { + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; + } + + // set derivative at position varIdx + void setDerivative(int varIdx, const ValueType& derVal) + { + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; + } + +private: + std::array data_; +}; + + + +} } // namespace DenseAd, Opm + + +#endif // OPM_DENSEAD_EVALUATION8_HPP diff --git a/opm/material/densead/Evaluation9.hpp b/opm/material/densead/Evaluation9.hpp new file mode 100644 index 000000000..eed038213 --- /dev/null +++ b/opm/material/densead/Evaluation9.hpp @@ -0,0 +1,526 @@ +// -*- 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 . + + 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 + + +#include "Math.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace DenseAd { + + +template +class Evaluation +{ +public: + //! field type + typedef ValueT ValueType; + + //! number of derivatives + static constexpr int size = 9; + +protected: + //! length of internal data vector + static constexpr int length_ = size + 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_[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]; + } + + // 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 + Evaluation(const RhsValueType& c) + { + setValue( c ); + clearDerivatives(); + Valgrind::CheckDefined( data_ ); + } + + // 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 + Evaluation(const RhsValueType& c, int varPos) + { + setValue( c ); + clearDerivatives(); + // The variable position must be in represented by the given variable descriptor + assert(0 <= varPos && varPos < size); + + data_[varPos + dstart_] = 1.0; + Valgrind::CheckDefined(data_); + } + + // set all derivatives to zero + void clearDerivatives() + { + data_[1] = 0.0; + data_[2] = 0.0; + data_[3] = 0.0; + data_[4] = 0.0; + data_[5] = 0.0; + data_[6] = 0.0; + data_[7] = 0.0; + data_[8] = 0.0; + data_[9] = 0.0; + } + + // create a function evaluation for a "naked" depending variable (i.e., f(x) = x) + template + 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 + 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 < size; ++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]; + } + + + // 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]; + + return *this; + } + + // add value from other to this values + template + 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) + { + 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]; + + return *this; + } + + // subtract other's value from this values + template + 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) + { + // while the values are multiplied, the derivatives follow the product rule, + // i.e., (u*v)' = (v'u + u'v). + const ValueType u = this->value(); + const ValueType v = other.value(); + + // value + data_[valuepos_] *= v ; + + // derivatives + 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; + + return *this; + } + + // m(c*u)' = c*u' + template + Evaluation& operator*=(const RhsValueType& other) + { + 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; + + 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; + + // value + data_[valuepos_] *= v_vv; + + // derivatives + 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; + + return *this; + } + + // divide value and derivatives by value of other + template + Evaluation& operator/=(const RhsValueType& other) + { + const ValueType tmp = 1.0/other; + + data_[0] *= tmp; + data_[1] *= tmp; + data_[2] *= tmp; + data_[3] *= tmp; + data_[4] *= tmp; + data_[5] *= tmp; + data_[6] *= tmp; + data_[7] *= tmp; + data_[8] *= tmp; + data_[9] *= tmp; + + return *this; + } + + // division of a constant by an Evaluation + template + static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) + { + Evaluation result; + const ValueType tmp = 1.0/b.value(); + result.setValue( a*tmp ); + const ValueType df_dg = - result.value()*tmp; + + 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; + } + + // add two evaluation objects + Evaluation operator+(const Evaluation& other) const + { + Evaluation result(*this); + result += other; + return result; + } + + // add constant to this object + template + 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); + return (result -= other); + } + + // subtract constant from evaluation object + template + Evaluation operator-(const RhsValueType& other) const + { + Evaluation result(*this); + return (result -= other); + } + + // negation (unary minus) operator + Evaluation operator-() const + { + Evaluation result; + // set value and derivatives to negative + result.data_[0] = - data_[0]; + result.data_[1] = - data_[1]; + result.data_[2] = - data_[2]; + result.data_[3] = - data_[3]; + result.data_[4] = - data_[4]; + result.data_[5] = - data_[5]; + result.data_[6] = - data_[6]; + result.data_[7] = - data_[7]; + result.data_[8] = - data_[8]; + result.data_[9] = - data_[9]; + + return result; + } + + Evaluation operator*(const Evaluation& other) const + { + Evaluation result(*this); + result *= other; + return result; + } + + template + 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 + Evaluation operator/(const RhsValueType& other) const + { + Evaluation result(*this); + result /= other; + return result; + } + + template + Evaluation& operator=(const RhsValueType& other) + { + setValue( other ); + clearDerivatives(); + return *this; + } + + // copy assignment from evaluation + 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]; + + return *this; + } + + template + 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 + bool operator>(RhsValueType other) const + { return value() > other; } + + bool operator>(const Evaluation& other) const + { return value() > other.value(); } + + template + bool operator<(RhsValueType other) const + { return value() < other; } + + bool operator<(const Evaluation& other) const + { return value() < other.value(); } + + template + bool operator>=(RhsValueType other) const + { return value() >= other; } + + bool operator>=(const Evaluation& other) const + { return value() >= other.value(); } + + template + 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 + template + void setValue(const RhsValueType& val) + { data_[valuepos_] = val; } + + // return varIdx'th derivative + const ValueType& derivative(int varIdx) const + { + assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; + } + + // set derivative at position varIdx + void setDerivative(int varIdx, const ValueType& derVal) + { + assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; + } + +private: + std::array data_; +}; + + + +} } // namespace DenseAd, Opm + + +#endif // OPM_DENSEAD_EVALUATION9_HPP diff --git a/opm/material/densead/EvaluationSpecializations.hpp b/opm/material/densead/EvaluationSpecializations.hpp new file mode 100644 index 000000000..4116ddb86 --- /dev/null +++ b/opm/material/densead/EvaluationSpecializations.hpp @@ -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 . + + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif // OPM_DENSEAD_EVALUATION_SPECIALIZATIONS_HPP \ No newline at end of file diff --git a/opm/material/densead/Math.hpp b/opm/material/densead/Math.hpp index 0076f1989..29e8ef589 100644 --- a/opm/material/densead/Math.hpp +++ b/opm/material/densead/Math.hpp @@ -39,45 +39,45 @@ namespace Opm { namespace DenseAd { // forward declaration of the Evaluation template class -template +template class Evaluation; // provide some algebraic functions -template +template Evaluation abs(const Evaluation& x) { return (x > 0.0)?x:-x; } -template +template Evaluation min(const Evaluation& x1, const Evaluation& x2) { return (x1 < x2)?x1:x2; } -template +template Evaluation min(const Arg1ValueType& x1, const Evaluation& x2) { return (x1 < x2)?x1:x2; } -template +template Evaluation min(const Evaluation& x1, const Arg2ValueType& x2) { return min(x2, x1); } -template +template Evaluation max(const Evaluation& x1, const Evaluation& x2) { return (x1 > x2)?x1:x2; } -template +template Evaluation max(const Arg1ValueType& x1, const Evaluation& x2) { return (x1 > x2)?x1:x2; } -template +template Evaluation max(const Evaluation& x1, const Arg2ValueType& x2) { return max(x2, x1); } -template +template Evaluation tan(const Evaluation& x) { typedef MathToolbox ValueTypeToolbox; @@ -89,13 +89,13 @@ Evaluation tan(const Evaluation& x) // derivatives use the chain rule const ValueType& df_dx = 1 + tmp*tmp; - for (unsigned curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) + for (int curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx)); return result; } -template +template Evaluation atan(const Evaluation& x) { typedef MathToolbox ValueTypeToolbox; @@ -106,13 +106,13 @@ Evaluation atan(const Evaluation& x) // derivatives use the chain rule const ValueType& df_dx = 1/(1 + x.value()*x.value()); - for (unsigned curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) + for (int curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx)); return result; } -template +template Evaluation atan2(const Evaluation& x, const Evaluation& y) { @@ -124,7 +124,7 @@ Evaluation atan2(const Evaluation& x, // derivatives use the chain rule const ValueType& alpha = 1/(1 + (x.value()*x.value())/(y.value()*y.value())); - for (unsigned curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) { + for (int curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) { result.setDerivative(curVarIdx, alpha/(y.value()*y.value()) *(x.derivative(curVarIdx)*y.value() - x.value()*y.derivative(curVarIdx))); @@ -133,7 +133,7 @@ Evaluation atan2(const Evaluation& x, return result; } -template +template Evaluation sin(const Evaluation& x) { typedef MathToolbox ValueTypeToolbox; @@ -144,13 +144,13 @@ Evaluation sin(const Evaluation& x) // derivatives use the chain rule const ValueType& df_dx = ValueTypeToolbox::cos(x.value()); - for (unsigned curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) + for (int curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx)); return result; } -template +template Evaluation asin(const Evaluation& x) { typedef MathToolbox ValueTypeToolbox; @@ -161,13 +161,13 @@ Evaluation asin(const Evaluation& x) // derivatives use the chain rule const ValueType& df_dx = 1.0/ValueTypeToolbox::sqrt(1 - x.value()*x.value()); - for (unsigned curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) + for (int curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx)); return result; } -template +template Evaluation cos(const Evaluation& x) { typedef MathToolbox ValueTypeToolbox; @@ -178,13 +178,13 @@ Evaluation cos(const Evaluation& x) // derivatives use the chain rule const ValueType& df_dx = -ValueTypeToolbox::sin(x.value()); - for (unsigned curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) + for (int curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx)); return result; } -template +template Evaluation acos(const Evaluation& x) { typedef MathToolbox ValueTypeToolbox; @@ -195,13 +195,13 @@ Evaluation acos(const Evaluation& x) // derivatives use the chain rule const ValueType& df_dx = - 1.0/ValueTypeToolbox::sqrt(1 - x.value()*x.value()); - for (unsigned curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) + for (int curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx)); return result; } -template +template Evaluation sqrt(const Evaluation& x) { typedef MathToolbox ValueTypeToolbox; @@ -213,14 +213,14 @@ Evaluation sqrt(const Evaluation& x) // derivatives use the chain rule ValueType df_dx = 0.5/sqrt_x; - for (unsigned curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) { + for (int curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) { result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx)); } return result; } -template +template Evaluation exp(const Evaluation& x) { typedef MathToolbox ValueTypeToolbox; @@ -231,14 +231,14 @@ Evaluation exp(const Evaluation& x) // derivatives use the chain rule const ValueType& df_dx = exp_x; - for (unsigned curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) + for (int curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx)); return result; } // exponentiation of arbitrary base with a fixed constant -template +template Evaluation pow(const Evaluation& base, const ExpType& exp) { @@ -256,7 +256,7 @@ Evaluation pow(const Evaluation& base, else { // derivatives use the chain rule const ValueType& df_dx = pow_x/base.value()*exp; - for (unsigned curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) + for (int curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) result.setDerivative(curVarIdx, df_dx*base.derivative(curVarIdx)); } @@ -264,7 +264,7 @@ Evaluation pow(const Evaluation& base, } // exponentiation of constant base with an arbitrary exponent -template +template Evaluation pow(const BaseType& base, const Evaluation& exp) { @@ -283,7 +283,7 @@ Evaluation pow(const BaseType& base, // derivatives use the chain rule const ValueType& df_dx = lnBase*result.value(); - for (unsigned curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) + for (int curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) result.setDerivative(curVarIdx, df_dx*exp.derivative(curVarIdx)); } @@ -292,7 +292,7 @@ Evaluation pow(const BaseType& base, // this is the most expensive power function. Computationally it is pretty expensive, so // one of the above two variants above should be preferred if possible. -template +template Evaluation pow(const Evaluation& base, const Evaluation& exp) { @@ -314,7 +314,7 @@ Evaluation pow(const Evaluation& base, const ValueType& f = base.value(); const ValueType& g = exp.value(); const ValueType& logF = ValueTypeToolbox::log(f); - for (unsigned curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) { + for (int curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) { const ValueType& fPrime = base.derivative(curVarIdx); const ValueType& gPrime = exp.derivative(curVarIdx); result.setDerivative(curVarIdx, (g*fPrime/f + logF*gPrime) * valuePow); @@ -324,7 +324,7 @@ Evaluation pow(const Evaluation& base, return result; } -template +template Evaluation log(const Evaluation& x) { typedef MathToolbox ValueTypeToolbox; @@ -335,7 +335,7 @@ Evaluation log(const Evaluation& x) // derivatives use the chain rule const ValueType& df_dx = 1/x.value(); - for (unsigned curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) + for (int curVarIdx = 0; curVarIdx < result.size; ++curVarIdx) result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx)); return result; @@ -345,7 +345,7 @@ Evaluation log(const Evaluation& x) // a kind of traits class for the automatic differentiation case. (The toolbox for the // scalar case is provided by the MathToolbox.hpp header file.) -template +template struct MathToolbox > { private: @@ -364,7 +364,7 @@ public: static Evaluation createConstant(ValueType value) { return Evaluation::createConstant(value); } - static Evaluation createVariable(ValueType value, unsigned varIdx) + static Evaluation createVariable(ValueType value, int varIdx) { return Evaluation::createVariable(value, varIdx); } template @@ -395,7 +395,7 @@ public: return false; // make sure that the derivatives are identical - for (unsigned curVarIdx = 0; curVarIdx < numVars; ++curVarIdx) + for (int curVarIdx = 0; curVarIdx < numVars; ++curVarIdx) if (!ValueTypeToolbox::isSame(a.derivative(curVarIdx), b.derivative(curVarIdx), tolerance)) return false; @@ -460,7 +460,7 @@ public: if (!InnerToolbox::isfinite(arg.value())) return false; - for (unsigned i = 0; i < numVars; ++i) + for (int i = 0; i < numVars; ++i) if (!InnerToolbox::isfinite(arg.derivative(i))) return false; @@ -472,7 +472,7 @@ public: if (InnerToolbox::isnan(arg.value())) return true; - for (unsigned i = 0; i < numVars; ++i) + for (int i = 0; i < numVars; ++i) if (InnerToolbox::isnan(arg.derivative(i))) return true; diff --git a/tests/test_densead.cpp b/tests/test_densead.cpp index 0d765b97c..5af2caaa9 100644 --- a/tests/test_densead.cpp +++ b/tests/test_densead.cpp @@ -50,9 +50,12 @@ #include #include -static const int numVars = 3; +//static const int numVars = 3; + +template +struct TestEnv +{ -template void testOperators(const Scalar tolerance) { typedef Opm::DenseAd::Evaluation Eval; @@ -256,7 +259,7 @@ void testOperators(const Scalar tolerance) } } -template +template void test1DFunction(AdFn* adFn, ClassicFn* classicFn, Scalar xMin = 1e-6, Scalar xMax = 1000) { typedef Opm::DenseAd::Evaluation Eval; @@ -289,8 +292,7 @@ void test1DFunction(AdFn* adFn, ClassicFn* classicFn, Scalar xMin = 1e-6, Scalar } } -template void test2DFunction1(AdFn* adFn, ClassicFn* classicFn, Scalar xMin, Scalar xMax, Scalar y) { @@ -326,8 +328,7 @@ void test2DFunction1(AdFn* adFn, ClassicFn* classicFn, Scalar xMin, Scalar xMax, } } -template void test2DFunction2(AdFn* adFn, ClassicFn* classicFn, Scalar x, Scalar yMin, Scalar yMax) { @@ -363,7 +364,6 @@ void test2DFunction2(AdFn* adFn, ClassicFn* classicFn, Scalar x, Scalar yMin, Sc } } -template void testPowBase(Scalar baseMin = 1e-2, Scalar baseMax = 100) { typedef Opm::DenseAd::Evaluation Eval; @@ -405,7 +405,6 @@ void testPowBase(Scalar baseMin = 1e-2, Scalar baseMax = 100) } } -template void testPowExp(Scalar expMin = -100, Scalar expMax = 100) { typedef Opm::DenseAd::Evaluation Eval; @@ -447,7 +446,6 @@ void testPowExp(Scalar expMin = -100, Scalar expMax = 100) } } -template void testAtan2() { typedef Opm::DenseAd::Evaluation Eval; @@ -497,16 +495,12 @@ void testAtan2() } // prototypes -double myScalarMin(double a, double b); -double myScalarMax(double a, double b); - -double myScalarMin(double a, double b) +static double myScalarMin(double a, double b) { return std::min(a, b); } -double myScalarMax(double a, double b) +static double myScalarMax(double a, double b) { return std::max(a, b); } -template inline void testAll() { // the following is commented out because it is supposed to produce a compiler @@ -516,82 +510,82 @@ inline void testAll() std::cout << "testing operators and constructors\n"; const Scalar eps = std::numeric_limits::epsilon()*1e3; - testOperators(eps); + testOperators(eps); std::cout << "testing min()\n"; - test2DFunction1(Opm::DenseAd::min, + test2DFunction1(Opm::DenseAd::min, myScalarMin, -1000, 1000, /*p=*/1.234); - test2DFunction2(Opm::DenseAd::min, + test2DFunction2(Opm::DenseAd::min, myScalarMin, /*T=*/1.234, -1000, 1000); std::cout << "testing max()\n"; - test2DFunction1(Opm::DenseAd::max, + test2DFunction1(Opm::DenseAd::max, myScalarMax, -1000, 1000, /*p=*/1.234); - test2DFunction2(Opm::DenseAd::max, + test2DFunction2(Opm::DenseAd::max, myScalarMax, /*T=*/1.234, -1000, 1000); std::cout << "testing pow()\n"; - testPowBase(); - testPowExp(); + testPowBase(); + testPowExp(); std::cout << "testing abs()\n"; - test1DFunction(Opm::DenseAd::abs, + test1DFunction(Opm::DenseAd::abs, static_cast(std::abs)); std::cout << "testing sqrt()\n"; - test1DFunction(Opm::DenseAd::sqrt, + test1DFunction(Opm::DenseAd::sqrt, static_cast(std::sqrt)); std::cout << "testing sin()\n"; - test1DFunction(Opm::DenseAd::sin, + test1DFunction(Opm::DenseAd::sin, static_cast(std::sin), 0, 2*M_PI); std::cout << "testing asin()\n"; - test1DFunction(Opm::DenseAd::asin, + test1DFunction(Opm::DenseAd::asin, static_cast(std::asin), -1.0, 1.0); std::cout << "testing cos()\n"; - test1DFunction(Opm::DenseAd::cos, + test1DFunction(Opm::DenseAd::cos, static_cast(std::cos), 0, 2*M_PI); std::cout << "testing acos()\n"; - test1DFunction(Opm::DenseAd::acos, + test1DFunction(Opm::DenseAd::acos, static_cast(std::acos), -1.0, 1.0); std::cout << "testing tan()\n"; - test1DFunction(Opm::DenseAd::tan, + test1DFunction(Opm::DenseAd::tan, static_cast(std::tan), -M_PI / 2 * 0.95, M_PI / 2 * 0.95); std::cout << "testing atan()\n"; - test1DFunction(Opm::DenseAd::atan, + test1DFunction(Opm::DenseAd::atan, static_cast(std::atan), -10*1000.0, 10*1000.0); std::cout << "testing atan2()\n"; - testAtan2(); + testAtan2(); std::cout << "testing exp()\n"; - test1DFunction(Opm::DenseAd::exp, + test1DFunction(Opm::DenseAd::exp, static_cast(std::exp), -100, 100); std::cout << "testing log()\n"; - test1DFunction(Opm::DenseAd::log, + test1DFunction(Opm::DenseAd::log, static_cast(std::log), 1e-6, 1e9); @@ -651,12 +645,17 @@ inline void testAll() } } +};//TestEnv + + int main(int argc, char **argv) { Dune::MPIHelper::instance(argc, argv); - testAll(); - testAll(); + TestEnv().testAll(); + TestEnv().testAll(); + TestEnv().testAll(); + TestEnv().testAll(); return 0; } From 19fb18dc206f5d953aa6f5b904748014790d28c6 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Sun, 26 Mar 2017 11:37:56 +0200 Subject: [PATCH 3/6] clean up the code generator script for Evaluations a bit this mainly removes superfluous newlines in the generated files, but also makes them bit more consistent. --- bin/genEvalSpecializations.py | 231 ++++++++++++++++++++-------------- 1 file changed, 140 insertions(+), 91 deletions(-) diff --git a/bin/genEvalSpecializations.py b/bin/genEvalSpecializations.py index 6c94ed452..3324dbf40 100755 --- a/bin/genEvalSpecializations.py +++ b/bin/genEvalSpecializations.py @@ -49,23 +49,23 @@ specializationTemplate = \ /*! * \\file * -{% if numDerivs < 0 %} +{% if numDerivs < 0 %}\ * \\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. -{% else %} +{% else %}\ * \\brief This file specializes the dense-AD Evaluation class for {{ numDerivs }} derivatives. -{% endif %} +{% endif %}\ * * \\attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "{{ scriptName }}" * SCRIPT. DO NOT EDIT IT MANUALLY! */ -{% if numDerivs < 0 %} +{% if numDerivs < 0 %}\ #ifndef OPM_DENSEAD_EVALUATION_HPP #define OPM_DENSEAD_EVALUATION_HPP -{% else %} +{% else %}\ #ifndef OPM_DENSEAD_EVALUATION{{numDerivs}}_HPP #define OPM_DENSEAD_EVALUATION{{numDerivs}}_HPP -{% endif %} +{% endif %}\ #include "Math.hpp" @@ -83,28 +83,29 @@ specializationTemplate = \ namespace Opm { namespace DenseAd { -{% if numDerivs < 0 %} +{% if numDerivs < 0 %}\ /*! * \\brief Represents a function evaluation and its derivatives w.r.t. a fixed set of * variables. */ template -class Evaluation\ -{% else %} +class Evaluation +{% else %}\ template -class Evaluation\ -{% endif %} +class Evaluation +{% endif %}\ { public: //! field type typedef ValueT ValueType; - //! number of derivatives\ - {% if numDerivs < 0 %} + //! number of derivatives +{% if numDerivs < 0 %}\ static constexpr int size = numDerivs; - {% else %} +{% else %}\ static constexpr int size = {{ numDerivs }}; - {% endif %} +{% endif %}\ + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -127,9 +128,10 @@ public: : data_(other.data_) { } {% else %}\ - {\ - {% for i in range(0, numDerivs+1) %} - data_[{{i}}] = other.data_[{{i}}];{% endfor %} + { +{% for i in range(0, numDerivs+1) %}\ + data_[{{i}}] = other.data_[{{i}}]; +{% endfor %}\ } {% endif %}\ @@ -152,25 +154,27 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - {\ - {% if numDerivs < 0 %} + { +{% if numDerivs < 0 %}\ for (int i = dstart_; i < dend_; ++i) { data_[i] = 0.0; } {% else %}\ - {% for i in range(1, numDerivs+1) %} - data_[{{i}}] = 0.0;{% endfor %} +{% for i in range(1, numDerivs+1) %}\ + data_[{{i}}] = 0.0; +{% endfor %}\ {% endif %}\ } @@ -196,6 +200,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -204,29 +209,31 @@ public: // copy all derivatives from other void copyDerivatives(const Evaluation& other) - {\ - {% if numDerivs < 0 %} + { +{% if numDerivs < 0 %}\ for (int i = dstart_; i < dend_; ++i) { data_[i] = other.data_[i]; } - {% else %}\ - {% for i in range(1, numDerivs+1) %} - data_[{{i}}] = other.data_[{{i}}];{% endfor %} - {% endif %}\ +{% else %}\ +{% for i in range(1, numDerivs+1) %}\ + data_[{{i}}] = other.data_[{{i}}]; +{% endfor %}\ +{% endif %}\ } // add value and derivatives from other to this values and derivatives Evaluation& operator+=(const Evaluation& other) - {\ - {% if numDerivs < 0 %} + { +{% if numDerivs < 0 %}\ for (int i = 0; i < length_; ++i) { data_[i] += other.data_[i]; } - {% else %}\ - {% for i in range(0, numDerivs+1) %} - data_[{{i}}] += other.data_[{{i}}];{% endfor %} - {% endif %}\ +{% else %}\ +{% for i in range(0, numDerivs+1) %}\ + data_[{{i}}] += other.data_[{{i}}]; +{% endfor %}\ +{% endif %}\ return *this; } @@ -237,20 +244,23 @@ public: { // 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) - {\ - {% if numDerivs < 0 %} + { +{% if numDerivs < 0 %}\ for (int i = 0; i < length_; ++i) { data_[i] -= other.data_[i]; } - {% else %}\ - {% for i in range(0, numDerivs+1) %} - data_[{{i}}] -= other.data_[{{i}}];{% endfor %} - {% endif %} +{% else %}\ +{% for i in range(0, numDerivs+1) %}\ + data_[{{i}}] -= other.data_[{{i}}]; +{% endfor %}\ +{% endif %}\ + return *this; } @@ -275,14 +285,15 @@ public: // value data_[valuepos_] *= v ; - // derivatives\ -{% if numDerivs < 0 %} + // derivatives +{% if numDerivs < 0 %}\ for (int i = dstart_; i < dend_; ++i) { data_[i] = data_[i] * v + other.data_[i] * u; } {% else %}\ - {% for i in range(1, numDerivs+1) %} - data_[{{i}}] = data_[{{i}}] * v + other.data_[{{i}}] * u;{% endfor %} +{% for i in range(1, numDerivs+1) %}\ + data_[{{i}}] = data_[{{i}}] * v + other.data_[{{i}}] * u; +{% endfor %}\ {% endif %}\ return *this; @@ -291,19 +302,21 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - {\ - {% if numDerivs < 0 %} + { +{% if numDerivs < 0 %}\ for (int i = 0; i < length_; ++i) { data_[i] *= other; } - {% else %}\ - {% for i in range(0, numDerivs+1) %} - data_[{{i}}] *= other;{% endfor %} - {% endif %} +{% else %}\ +{% for i in range(0, numDerivs+1) %}\ + data_[{{i}}] *= other; +{% endfor %}\ +{% endif %}\ + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 Evaluation& operator/=(const Evaluation& other) { // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - u'v)/v^2. @@ -313,15 +326,17 @@ public: // value data_[valuepos_] *= v_vv; - // derivatives\ - {% if numDerivs < 0 %} + // derivatives +{% if numDerivs < 0 %}\ for (int i = dstart_; i < dend_; ++i) { data_[i] = data_[i] * v_vv - other.data_[i] * u_vv; } - {% else %}\ - {% for i in range(1, numDerivs+1) %} - data_[{{i}}] = data_[{{i}}] * v_vv - other.data_[{{i}}] * u_vv;{% endfor %} - {% endif %} +{% else %}\ +{% for i in range(1, numDerivs+1) %}\ + data_[{{i}}] = data_[{{i}}] * v_vv - other.data_[{{i}}] * u_vv; +{% endfor %}\ +{% endif %}\ + return *this; } @@ -330,14 +345,17 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - {% if numDerivs < 0 %} + +{% if numDerivs < 0 %}\ for (int i = 0; i < length_; ++i) { data_[i] *= tmp; } - {% else %}\ - {% for i in range(0, numDerivs+1) %} - data_[{{i}}] *= tmp;{% endfor %} - {% endif %} +{% else %}\ +{% for i in range(0, numDerivs+1) %}\ + data_[{{i}}] *= tmp; +{% endfor %}\ +{% endif %}\ + return *this; } @@ -346,17 +364,21 @@ public: static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) { Evaluation result; + const ValueType tmp = 1.0/b.value(); result.setValue( a*tmp ); const ValueType df_dg = - result.value()*tmp; - {% if numDerivs < 0 %} + +{% if numDerivs < 0 %}\ for (int i = dstart_; i < dend_; ++i) { result.data_[i] = df_dg * b.data_[i]; } - {% else %}\ - {% for i in range(1, numDerivs+1) %} - result.data_[{{i}}] = df_dg * b.data_[{{i}}];{% endfor %} - {% endif %} +{% else %}\ +{% for i in range(1, numDerivs+1) %}\ + result.data_[{{i}}] = df_dg * b.data_[{{i}}]; +{% endfor %}\ +{% endif %}\ + return result; } @@ -364,7 +386,9 @@ public: Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -373,7 +397,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -381,7 +407,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -389,29 +418,37 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative\ - {% if numDerivs < 0 %} + + // set value and derivatives to negative +{% if numDerivs < 0 %}\ for (int i = 0; i < length_; ++i) { result.data_[i] = - data_[i]; } - {% else %}\ - {% for i in range(0, numDerivs+1) %} - result.data_[{{i}}] = - data_[{{i}}];{% endfor %} - {% endif %} +{% else %}\ +{% for i in range(0, numDerivs+1) %}\ + result.data_[{{i}}] = - data_[{{i}}]; +{% endfor %}\ +{% endif %}\ + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -419,14 +456,18 @@ public: 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; } @@ -434,7 +475,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -443,20 +486,23 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation Evaluation& operator=(const Evaluation& other) - {\ - {% if numDerivs < 0 %} + { +{% if numDerivs < 0 %}\ for (int i = 0; i < length_; ++i) { data_[i] = other.data_[i]; } - {% else %}\ - {% for i in range(0, numDerivs+1) %} - data_[{{i}}] = other.data_[{{i}}];{% endfor %} - {% endif %} +{% else %}\ +{% for i in range(0, numDerivs+1) %}\ + data_[{{i}}] = other.data_[{{i}}]; +{% endfor %}\ +{% endif %}\ + return *this; } @@ -518,6 +564,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -525,6 +572,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -532,8 +580,8 @@ private: std::array data_; }; -{# the generic operators are only required for the unspecialized case #} -{% if numDerivs < 0 %} +{% if numDerivs < 0 %}\ +// the generic operators are only required for the unspecialized case template bool operator<(const RhsValueType& a, const Evaluation& b) { return b > a; } @@ -590,10 +638,10 @@ std::ostream& operator<<(std::ostream& os, const Evaluation& os << eval.value(); return os; } -{% endif %} +{% endif %}\ } } // namespace DenseAd, Opm -{% if numDerivs < 0 %} +{% if numDerivs < 0 %}\ // In Dune 2.3, the Evaluation.hpp header must be included before the fmatrix.hh // header. Dune 2.4+ does not suffer from this because of some c++-foo. // @@ -659,9 +707,9 @@ public: #include "EvaluationSpecializations.hpp" #endif // OPM_DENSEAD_EVALUATION_HPP -{% else %} +{% else %}\ #endif // OPM_DENSEAD_EVALUATION{{numDerivs}}_HPP -{% endif %} +{% endif %}\ """ includeSpecializationsTemplate = \ @@ -698,8 +746,9 @@ includeSpecializationsTemplate = \ #ifndef OPM_DENSEAD_EVALUATION_SPECIALIZATIONS_HPP #define OPM_DENSEAD_EVALUATION_SPECIALIZATIONS_HPP -{% for fileName in fileNames %}#include <{{ fileName }}> -{% endfor %} +{% for fileName in fileNames %}\ +#include <{{ fileName }}> +{% endfor %}\ #endif // OPM_DENSEAD_EVALUATION_SPECIALIZATIONS_HPP """ From 1a1b17a5c899a483b18e01dabe30d8d049359fa2 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Wed, 7 Jun 2017 13:02:36 +0200 Subject: [PATCH 4/6] revert optimizing the division code for evaluations --- bin/genEvalSpecializations.py | 49 ++++++++++------------------------- 1 file changed, 14 insertions(+), 35 deletions(-) diff --git a/bin/genEvalSpecializations.py b/bin/genEvalSpecializations.py index 3324dbf40..89536d9e7 100755 --- a/bin/genEvalSpecializations.py +++ b/bin/genEvalSpecializations.py @@ -319,23 +319,23 @@ public: // m(u*v)' = (vu' - uv')/v^2 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; - - // value - data_[valuepos_] *= v_vv; - - // derivatives + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); {% if numDerivs < 0 %}\ - for (int i = dstart_; i < dend_; ++i) { - data_[i] = data_[i] * v_vv - other.data_[i] * u_vv; + for (unsigned idx = dstart_; idx < dend_; ++idx) { + const ValueType& uPrime = data_[idx]; + const ValueType& vPrime = other.data_[idx]; + + data_[idx] = (v*uPrime - u*vPrime)/(v*v); } {% else %}\ {% for i in range(1, numDerivs+1) %}\ - data_[{{i}}] = data_[{{i}}] * v_vv - other.data_[{{i}}] * u_vv; + data_[{{i}}] = (v*data_[{{i}}] - u*other.data_[{{i}}])/(v*v); {% endfor %}\ {% endif %}\ + u /= v; return *this; } @@ -359,29 +359,6 @@ public: return *this; } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - -{% if numDerivs < 0 %}\ - for (int i = dstart_; i < dend_; ++i) { - result.data_[i] = df_dg * b.data_[i]; - } -{% else %}\ -{% for i in range(1, numDerivs+1) %}\ - result.data_[{{i}}] = df_dg * b.data_[{{i}}]; -{% endfor %}\ -{% endif %}\ - - return result; - } - // add two evaluation objects Evaluation operator+(const Evaluation& other) const { @@ -621,7 +598,9 @@ Evaluation operator-(const RhsValueType& a, const Evaluation template Evaluation operator/(const RhsValueType& a, const Evaluation& b) { - return Evaluation::divide(a, b); + Evaluation tmp(a); + tmp /= b; + return tmp; } template From ee5ee215bd8731db60a217d3d4880bcf8d3f8d64 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Wed, 26 Apr 2017 11:10:58 +0200 Subject: [PATCH 5/6] explicitly include all Evaluations in the file for each specialization indirectly this was already the case: Math.hpp includes Evaluation.hpp, but this change should make it more explicit. --- bin/genEvalSpecializations.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/genEvalSpecializations.py b/bin/genEvalSpecializations.py index 89536d9e7..1e22bc916 100755 --- a/bin/genEvalSpecializations.py +++ b/bin/genEvalSpecializations.py @@ -67,6 +67,7 @@ specializationTemplate = \ #define OPM_DENSEAD_EVALUATION{{numDerivs}}_HPP {% endif %}\ +#include "Evaluation.hpp" #include "Math.hpp" #include From 7050193167e1896ab30208353ffdf246ee872b33 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Wed, 7 Jun 2017 13:06:32 +0200 Subject: [PATCH 6/6] update generated files --- opm/material/densead/Evaluation.hpp | 120 ++++++++------- opm/material/densead/Evaluation1.hpp | 111 +++++++------- opm/material/densead/Evaluation10.hpp | 138 ++++++++--------- opm/material/densead/Evaluation11.hpp | 141 ++++++++--------- opm/material/densead/Evaluation12.hpp | 144 ++++++++---------- opm/material/densead/Evaluation2.hpp | 114 +++++++------- opm/material/densead/Evaluation3.hpp | 117 +++++++------- opm/material/densead/Evaluation4.hpp | 120 +++++++-------- opm/material/densead/Evaluation5.hpp | 123 ++++++++------- opm/material/densead/Evaluation6.hpp | 126 ++++++++------- opm/material/densead/Evaluation7.hpp | 129 ++++++++-------- opm/material/densead/Evaluation8.hpp | 132 ++++++++-------- opm/material/densead/Evaluation9.hpp | 135 ++++++++-------- .../densead/EvaluationSpecializations.hpp | 1 - 14 files changed, 800 insertions(+), 851 deletions(-) diff --git a/opm/material/densead/Evaluation.hpp b/opm/material/densead/Evaluation.hpp index 18f977dad..2b06a72c7 100644 --- a/opm/material/densead/Evaluation.hpp +++ b/opm/material/densead/Evaluation.hpp @@ -23,19 +23,16 @@ /*! * \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. - * * \attention THIS FILE GETS AUTOMATICALLY GENERATED BY THE "genEvalSpecializations.py" * SCRIPT. DO NOT EDIT IT MANUALLY! */ - #ifndef OPM_DENSEAD_EVALUATION_HPP #define OPM_DENSEAD_EVALUATION_HPP - +#include "Evaluation.hpp" #include "Math.hpp" #include @@ -52,7 +49,6 @@ namespace Opm { namespace DenseAd { - /*! * \brief Represents a function evaluation and its derivatives w.r.t. a fixed set of * variables. @@ -64,9 +60,9 @@ public: //! field type typedef ValueT ValueType; - //! number of derivatives + //! number of derivatives static constexpr int size = numDerivs; - + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -107,18 +103,19 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - { + { for (int i = dstart_; i < dend_; ++i) { data_[i] = 0.0; } @@ -146,6 +143,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -154,20 +152,20 @@ public: // copy all derivatives from other void copyDerivatives(const Evaluation& other) - { + { for (int i = dstart_; i < dend_; ++i) { data_[i] = other.data_[i]; } - } + } // add value and derivatives from other to this values and derivatives Evaluation& operator+=(const Evaluation& other) - { + { for (int i = 0; i < length_; ++i) { data_[i] += other.data_[i]; } - + return *this; } @@ -177,16 +175,17 @@ public: { // 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) - { + { for (int i = 0; i < length_; ++i) { data_[i] -= other.data_[i]; } - + return *this; } @@ -222,29 +221,29 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - { + { for (int i = 0; i < length_; ++i) { data_[i] *= other; } - + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 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; + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); + for (unsigned idx = dstart_; idx < dend_; ++idx) { + const ValueType& uPrime = data_[idx]; + const ValueType& vPrime = other.data_[idx]; - // value - data_[valuepos_] *= v_vv; - - // derivatives - for (int i = dstart_; i < dend_; ++i) { - data_[i] = data_[i] * v_vv - other.data_[i] * u_vv; + data_[idx] = (v*uPrime - u*vPrime)/(v*v); } - + u /= v; + return *this; } @@ -253,35 +252,21 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - + for (int i = 0; i < length_; ++i) { data_[i] *= tmp; } - - return *this; - } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - - for (int i = dstart_; i < dend_; ++i) { - result.data_[i] = df_dg * b.data_[i]; - } - - return result; + return *this; } // add two evaluation objects Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -290,7 +275,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -298,7 +285,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -306,25 +296,31 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative + + // set value and derivatives to negative for (int i = 0; i < length_; ++i) { result.data_[i] = - data_[i]; } - + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -332,14 +328,18 @@ public: 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; } @@ -347,7 +347,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -356,16 +358,17 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation Evaluation& operator=(const Evaluation& other) - { + { for (int i = 0; i < length_; ++i) { data_[i] = other.data_[i]; } - + return *this; } @@ -427,6 +430,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -434,6 +438,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -441,8 +446,7 @@ private: std::array data_; }; - - +// the generic operators are only required for the unspecialized case template bool operator<(const RhsValueType& a, const Evaluation& b) { return b > a; } @@ -482,7 +486,9 @@ Evaluation operator-(const RhsValueType& a, const Evaluation template Evaluation operator/(const RhsValueType& a, const Evaluation& b) { - return Evaluation::divide(a, b); + Evaluation tmp(a); + tmp /= b; + return tmp; } template @@ -499,10 +505,8 @@ std::ostream& operator<<(std::ostream& os, const Evaluation& os << eval.value(); return os; } - } } // namespace DenseAd, Opm - // In Dune 2.3, the Evaluation.hpp header must be included before the fmatrix.hh // header. Dune 2.4+ does not suffer from this because of some c++-foo. // diff --git a/opm/material/densead/Evaluation1.hpp b/opm/material/densead/Evaluation1.hpp index dd6981ea0..c17353c1c 100644 --- a/opm/material/densead/Evaluation1.hpp +++ b/opm/material/densead/Evaluation1.hpp @@ -23,18 +23,15 @@ /*! * \file * - * \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_DENSEAD_EVALUATION1_HPP #define OPM_DENSEAD_EVALUATION1_HPP - +#include "Evaluation.hpp" #include "Math.hpp" #include @@ -51,7 +48,6 @@ namespace Opm { namespace DenseAd { - template class Evaluation { @@ -59,9 +55,9 @@ public: //! field type typedef ValueT ValueType; - //! number of derivatives + //! number of derivatives static constexpr int size = 1; - + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -80,7 +76,7 @@ public: //! copy other function evaluation Evaluation(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; } @@ -104,18 +100,19 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - { + { data_[1] = 0.0; } @@ -141,6 +138,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -149,17 +147,17 @@ public: // 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; } @@ -169,15 +167,16 @@ public: { // 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) - { + { data_[0] -= other.data_[0]; data_[1] -= other.data_[1]; - + return *this; } @@ -202,7 +201,7 @@ public: // value data_[valuepos_] *= v ; - // derivatives + // derivatives data_[1] = data_[1] * v + other.data_[1] * u; return *this; @@ -211,26 +210,23 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - { + { data_[0] *= other; data_[1] *= other; - + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 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; + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); + data_[1] = (v*data_[1] - u*other.data_[1])/(v*v); + u /= v; - // value - data_[valuepos_] *= v_vv; - - // derivatives - data_[1] = data_[1] * v_vv - other.data_[1] * u_vv; - return *this; } @@ -239,32 +235,20 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - + data_[0] *= tmp; data_[1] *= tmp; - - return *this; - } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - - result.data_[1] = df_dg * b.data_[1]; - - return result; + return *this; } // add two evaluation objects Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -273,7 +257,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -281,7 +267,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -289,24 +278,30 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative + + // set value and derivatives to negative result.data_[0] = - data_[0]; result.data_[1] = - data_[1]; - + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -314,14 +309,18 @@ public: 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; } @@ -329,7 +328,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -338,15 +339,16 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation Evaluation& operator=(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; - + return *this; } @@ -408,6 +410,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -415,6 +418,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -422,9 +426,6 @@ private: std::array data_; }; - - } } // namespace DenseAd, Opm - #endif // OPM_DENSEAD_EVALUATION1_HPP diff --git a/opm/material/densead/Evaluation10.hpp b/opm/material/densead/Evaluation10.hpp index 984c89968..088a20e57 100644 --- a/opm/material/densead/Evaluation10.hpp +++ b/opm/material/densead/Evaluation10.hpp @@ -23,18 +23,15 @@ /*! * \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 - +#include "Evaluation.hpp" #include "Math.hpp" #include @@ -51,7 +48,6 @@ namespace Opm { namespace DenseAd { - template class Evaluation { @@ -59,9 +55,9 @@ public: //! field type typedef ValueT ValueType; - //! number of derivatives + //! number of derivatives static constexpr int size = 10; - + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -80,7 +76,7 @@ public: //! copy other function evaluation Evaluation(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -113,18 +109,19 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - { + { data_[1] = 0.0; data_[2] = 0.0; data_[3] = 0.0; @@ -159,6 +156,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -167,7 +165,7 @@ public: // 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]; @@ -178,12 +176,12 @@ public: data_[8] = other.data_[8]; data_[9] = other.data_[9]; data_[10] = other.data_[10]; - } + } // 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]; @@ -195,7 +193,7 @@ public: data_[8] += other.data_[8]; data_[9] += other.data_[9]; data_[10] += other.data_[10]; - + return *this; } @@ -205,12 +203,13 @@ public: { // 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) - { + { data_[0] -= other.data_[0]; data_[1] -= other.data_[1]; data_[2] -= other.data_[2]; @@ -222,7 +221,7 @@ public: data_[8] -= other.data_[8]; data_[9] -= other.data_[9]; data_[10] -= other.data_[10]; - + return *this; } @@ -247,7 +246,7 @@ public: // value data_[valuepos_] *= v ; - // derivatives + // derivatives 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; @@ -265,7 +264,7 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - { + { data_[0] *= other; data_[1] *= other; data_[2] *= other; @@ -277,32 +276,29 @@ public: data_[8] *= other; data_[9] *= other; data_[10] *= other; - + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 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; + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); + data_[1] = (v*data_[1] - u*other.data_[1])/(v*v); + data_[2] = (v*data_[2] - u*other.data_[2])/(v*v); + data_[3] = (v*data_[3] - u*other.data_[3])/(v*v); + data_[4] = (v*data_[4] - u*other.data_[4])/(v*v); + data_[5] = (v*data_[5] - u*other.data_[5])/(v*v); + data_[6] = (v*data_[6] - u*other.data_[6])/(v*v); + data_[7] = (v*data_[7] - u*other.data_[7])/(v*v); + data_[8] = (v*data_[8] - u*other.data_[8])/(v*v); + data_[9] = (v*data_[9] - u*other.data_[9])/(v*v); + data_[10] = (v*data_[10] - u*other.data_[10])/(v*v); + u /= v; - // value - data_[valuepos_] *= v_vv; - - // derivatives - 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; - return *this; } @@ -311,7 +307,7 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - + data_[0] *= tmp; data_[1] *= tmp; data_[2] *= tmp; @@ -323,38 +319,17 @@ public: data_[8] *= tmp; data_[9] *= tmp; data_[10] *= tmp; - - return *this; - } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - - 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; + return *this; } // add two evaluation objects Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -363,7 +338,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -371,7 +348,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -379,14 +359,18 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative + + // set value and derivatives to negative result.data_[0] = - data_[0]; result.data_[1] = - data_[1]; result.data_[2] = - data_[2]; @@ -398,14 +382,16 @@ public: result.data_[8] = - data_[8]; result.data_[9] = - data_[9]; result.data_[10] = - data_[10]; - + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -413,14 +399,18 @@ public: 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; } @@ -428,7 +418,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -437,12 +429,13 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation Evaluation& operator=(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -454,7 +447,7 @@ public: data_[8] = other.data_[8]; data_[9] = other.data_[9]; data_[10] = other.data_[10]; - + return *this; } @@ -516,6 +509,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -523,6 +517,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -530,9 +525,6 @@ private: std::array data_; }; - - } } // namespace DenseAd, Opm - #endif // OPM_DENSEAD_EVALUATION10_HPP diff --git a/opm/material/densead/Evaluation11.hpp b/opm/material/densead/Evaluation11.hpp index b595356ce..ce1743c31 100644 --- a/opm/material/densead/Evaluation11.hpp +++ b/opm/material/densead/Evaluation11.hpp @@ -23,18 +23,15 @@ /*! * \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 - +#include "Evaluation.hpp" #include "Math.hpp" #include @@ -51,7 +48,6 @@ namespace Opm { namespace DenseAd { - template class Evaluation { @@ -59,9 +55,9 @@ public: //! field type typedef ValueT ValueType; - //! number of derivatives + //! number of derivatives static constexpr int size = 11; - + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -80,7 +76,7 @@ public: //! copy other function evaluation Evaluation(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -114,18 +110,19 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - { + { data_[1] = 0.0; data_[2] = 0.0; data_[3] = 0.0; @@ -161,6 +158,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -169,7 +167,7 @@ public: // 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]; @@ -181,12 +179,12 @@ public: data_[9] = other.data_[9]; data_[10] = other.data_[10]; data_[11] = other.data_[11]; - } + } // 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]; @@ -199,7 +197,7 @@ public: data_[9] += other.data_[9]; data_[10] += other.data_[10]; data_[11] += other.data_[11]; - + return *this; } @@ -209,12 +207,13 @@ public: { // 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) - { + { data_[0] -= other.data_[0]; data_[1] -= other.data_[1]; data_[2] -= other.data_[2]; @@ -227,7 +226,7 @@ public: data_[9] -= other.data_[9]; data_[10] -= other.data_[10]; data_[11] -= other.data_[11]; - + return *this; } @@ -252,7 +251,7 @@ public: // value data_[valuepos_] *= v ; - // derivatives + // derivatives 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; @@ -271,7 +270,7 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - { + { data_[0] *= other; data_[1] *= other; data_[2] *= other; @@ -284,33 +283,30 @@ public: data_[9] *= other; data_[10] *= other; data_[11] *= other; - + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 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; + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); + data_[1] = (v*data_[1] - u*other.data_[1])/(v*v); + data_[2] = (v*data_[2] - u*other.data_[2])/(v*v); + data_[3] = (v*data_[3] - u*other.data_[3])/(v*v); + data_[4] = (v*data_[4] - u*other.data_[4])/(v*v); + data_[5] = (v*data_[5] - u*other.data_[5])/(v*v); + data_[6] = (v*data_[6] - u*other.data_[6])/(v*v); + data_[7] = (v*data_[7] - u*other.data_[7])/(v*v); + data_[8] = (v*data_[8] - u*other.data_[8])/(v*v); + data_[9] = (v*data_[9] - u*other.data_[9])/(v*v); + data_[10] = (v*data_[10] - u*other.data_[10])/(v*v); + data_[11] = (v*data_[11] - u*other.data_[11])/(v*v); + u /= v; - // value - data_[valuepos_] *= v_vv; - - // derivatives - 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; - return *this; } @@ -319,7 +315,7 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - + data_[0] *= tmp; data_[1] *= tmp; data_[2] *= tmp; @@ -332,39 +328,17 @@ public: data_[9] *= tmp; data_[10] *= tmp; data_[11] *= tmp; - - return *this; - } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - - 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; + return *this; } // add two evaluation objects Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -373,7 +347,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -381,7 +357,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -389,14 +368,18 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative + + // set value and derivatives to negative result.data_[0] = - data_[0]; result.data_[1] = - data_[1]; result.data_[2] = - data_[2]; @@ -409,14 +392,16 @@ public: result.data_[9] = - data_[9]; result.data_[10] = - data_[10]; result.data_[11] = - data_[11]; - + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -424,14 +409,18 @@ public: 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; } @@ -439,7 +428,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -448,12 +439,13 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation Evaluation& operator=(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -466,7 +458,7 @@ public: data_[9] = other.data_[9]; data_[10] = other.data_[10]; data_[11] = other.data_[11]; - + return *this; } @@ -528,6 +520,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -535,6 +528,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -542,9 +536,6 @@ private: std::array data_; }; - - } } // namespace DenseAd, Opm - #endif // OPM_DENSEAD_EVALUATION11_HPP diff --git a/opm/material/densead/Evaluation12.hpp b/opm/material/densead/Evaluation12.hpp index caeff8dd7..15a6fe2de 100644 --- a/opm/material/densead/Evaluation12.hpp +++ b/opm/material/densead/Evaluation12.hpp @@ -23,18 +23,15 @@ /*! * \file * - * \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_DENSEAD_EVALUATION12_HPP #define OPM_DENSEAD_EVALUATION12_HPP - +#include "Evaluation.hpp" #include "Math.hpp" #include @@ -51,7 +48,6 @@ namespace Opm { namespace DenseAd { - template class Evaluation { @@ -59,9 +55,9 @@ public: //! field type typedef ValueT ValueType; - //! number of derivatives + //! number of derivatives static constexpr int size = 12; - + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -80,7 +76,7 @@ public: //! copy other function evaluation Evaluation(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -115,18 +111,19 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - { + { data_[1] = 0.0; data_[2] = 0.0; data_[3] = 0.0; @@ -163,6 +160,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -171,7 +169,7 @@ public: // 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]; @@ -184,12 +182,12 @@ public: 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]; @@ -203,7 +201,7 @@ public: data_[10] += other.data_[10]; data_[11] += other.data_[11]; data_[12] += other.data_[12]; - + return *this; } @@ -213,12 +211,13 @@ public: { // 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) - { + { data_[0] -= other.data_[0]; data_[1] -= other.data_[1]; data_[2] -= other.data_[2]; @@ -232,7 +231,7 @@ public: data_[10] -= other.data_[10]; data_[11] -= other.data_[11]; data_[12] -= other.data_[12]; - + return *this; } @@ -257,7 +256,7 @@ public: // value data_[valuepos_] *= v ; - // derivatives + // derivatives 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; @@ -277,7 +276,7 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - { + { data_[0] *= other; data_[1] *= other; data_[2] *= other; @@ -291,34 +290,31 @@ public: data_[10] *= other; data_[11] *= other; data_[12] *= other; - + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 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; + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); + data_[1] = (v*data_[1] - u*other.data_[1])/(v*v); + data_[2] = (v*data_[2] - u*other.data_[2])/(v*v); + data_[3] = (v*data_[3] - u*other.data_[3])/(v*v); + data_[4] = (v*data_[4] - u*other.data_[4])/(v*v); + data_[5] = (v*data_[5] - u*other.data_[5])/(v*v); + data_[6] = (v*data_[6] - u*other.data_[6])/(v*v); + data_[7] = (v*data_[7] - u*other.data_[7])/(v*v); + data_[8] = (v*data_[8] - u*other.data_[8])/(v*v); + data_[9] = (v*data_[9] - u*other.data_[9])/(v*v); + data_[10] = (v*data_[10] - u*other.data_[10])/(v*v); + data_[11] = (v*data_[11] - u*other.data_[11])/(v*v); + data_[12] = (v*data_[12] - u*other.data_[12])/(v*v); + u /= v; - // value - data_[valuepos_] *= v_vv; - - // derivatives - 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; } @@ -327,7 +323,7 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - + data_[0] *= tmp; data_[1] *= tmp; data_[2] *= tmp; @@ -341,40 +337,17 @@ public: data_[10] *= tmp; data_[11] *= tmp; data_[12] *= tmp; - - return *this; - } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - - 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; + return *this; } // add two evaluation objects Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -383,7 +356,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -391,7 +366,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -399,14 +377,18 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative + + // set value and derivatives to negative result.data_[0] = - data_[0]; result.data_[1] = - data_[1]; result.data_[2] = - data_[2]; @@ -420,14 +402,16 @@ public: result.data_[10] = - data_[10]; result.data_[11] = - data_[11]; result.data_[12] = - data_[12]; - + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -435,14 +419,18 @@ public: 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; } @@ -450,7 +438,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -459,12 +449,13 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation Evaluation& operator=(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -478,7 +469,7 @@ public: data_[10] = other.data_[10]; data_[11] = other.data_[11]; data_[12] = other.data_[12]; - + return *this; } @@ -540,6 +531,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -547,6 +539,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -554,9 +547,6 @@ private: std::array data_; }; - - } } // namespace DenseAd, Opm - #endif // OPM_DENSEAD_EVALUATION12_HPP diff --git a/opm/material/densead/Evaluation2.hpp b/opm/material/densead/Evaluation2.hpp index fdfcb7ee7..1c9b9efca 100644 --- a/opm/material/densead/Evaluation2.hpp +++ b/opm/material/densead/Evaluation2.hpp @@ -23,18 +23,15 @@ /*! * \file * - * \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_DENSEAD_EVALUATION2_HPP #define OPM_DENSEAD_EVALUATION2_HPP - +#include "Evaluation.hpp" #include "Math.hpp" #include @@ -51,7 +48,6 @@ namespace Opm { namespace DenseAd { - template class Evaluation { @@ -59,9 +55,9 @@ public: //! field type typedef ValueT ValueType; - //! number of derivatives + //! number of derivatives static constexpr int size = 2; - + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -80,7 +76,7 @@ public: //! copy other function evaluation Evaluation(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -105,18 +101,19 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - { + { data_[1] = 0.0; data_[2] = 0.0; } @@ -143,6 +140,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -151,19 +149,19 @@ public: // 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; } @@ -173,16 +171,17 @@ public: { // 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) - { + { data_[0] -= other.data_[0]; data_[1] -= other.data_[1]; data_[2] -= other.data_[2]; - + return *this; } @@ -207,7 +206,7 @@ public: // value data_[valuepos_] *= v ; - // derivatives + // derivatives data_[1] = data_[1] * v + other.data_[1] * u; data_[2] = data_[2] * v + other.data_[2] * u; @@ -217,28 +216,25 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - { + { data_[0] *= other; data_[1] *= other; data_[2] *= other; - + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 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; + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); + data_[1] = (v*data_[1] - u*other.data_[1])/(v*v); + data_[2] = (v*data_[2] - u*other.data_[2])/(v*v); + u /= v; - // value - data_[valuepos_] *= v_vv; - - // derivatives - data_[1] = data_[1] * v_vv - other.data_[1] * u_vv; - data_[2] = data_[2] * v_vv - other.data_[2] * u_vv; - return *this; } @@ -247,34 +243,21 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - + data_[0] *= tmp; data_[1] *= tmp; data_[2] *= tmp; - - return *this; - } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - - result.data_[1] = df_dg * b.data_[1]; - result.data_[2] = df_dg * b.data_[2]; - - return result; + return *this; } // add two evaluation objects Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -283,7 +266,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -291,7 +276,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -299,25 +287,31 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative + + // set value and derivatives to negative result.data_[0] = - data_[0]; result.data_[1] = - data_[1]; result.data_[2] = - data_[2]; - + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -325,14 +319,18 @@ public: 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; } @@ -340,7 +338,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -349,16 +349,17 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation Evaluation& operator=(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; - + return *this; } @@ -420,6 +421,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -427,6 +429,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -434,9 +437,6 @@ private: std::array data_; }; - - } } // namespace DenseAd, Opm - #endif // OPM_DENSEAD_EVALUATION2_HPP diff --git a/opm/material/densead/Evaluation3.hpp b/opm/material/densead/Evaluation3.hpp index f31ca52e5..c715acd08 100644 --- a/opm/material/densead/Evaluation3.hpp +++ b/opm/material/densead/Evaluation3.hpp @@ -23,18 +23,15 @@ /*! * \file * - * \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_DENSEAD_EVALUATION3_HPP #define OPM_DENSEAD_EVALUATION3_HPP - +#include "Evaluation.hpp" #include "Math.hpp" #include @@ -51,7 +48,6 @@ namespace Opm { namespace DenseAd { - template class Evaluation { @@ -59,9 +55,9 @@ public: //! field type typedef ValueT ValueType; - //! number of derivatives + //! number of derivatives static constexpr int size = 3; - + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -80,7 +76,7 @@ public: //! copy other function evaluation Evaluation(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -106,18 +102,19 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - { + { data_[1] = 0.0; data_[2] = 0.0; data_[3] = 0.0; @@ -145,6 +142,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -153,21 +151,21 @@ public: // 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; } @@ -177,17 +175,18 @@ public: { // 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) - { + { data_[0] -= other.data_[0]; data_[1] -= other.data_[1]; data_[2] -= other.data_[2]; data_[3] -= other.data_[3]; - + return *this; } @@ -212,7 +211,7 @@ public: // value data_[valuepos_] *= v ; - // derivatives + // derivatives 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; @@ -223,30 +222,27 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - { + { data_[0] *= other; data_[1] *= other; data_[2] *= other; data_[3] *= other; - + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 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; + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); + data_[1] = (v*data_[1] - u*other.data_[1])/(v*v); + data_[2] = (v*data_[2] - u*other.data_[2])/(v*v); + data_[3] = (v*data_[3] - u*other.data_[3])/(v*v); + u /= v; - // value - data_[valuepos_] *= v_vv; - - // derivatives - 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; } @@ -255,36 +251,22 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - + data_[0] *= tmp; data_[1] *= tmp; data_[2] *= tmp; data_[3] *= tmp; - - return *this; - } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - - 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; + return *this; } // add two evaluation objects Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -293,7 +275,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -301,7 +285,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -309,26 +296,32 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative + + // set value and derivatives to negative result.data_[0] = - data_[0]; result.data_[1] = - data_[1]; result.data_[2] = - data_[2]; result.data_[3] = - data_[3]; - + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -336,14 +329,18 @@ public: 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; } @@ -351,7 +348,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -360,17 +359,18 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation 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; } @@ -432,6 +432,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -439,6 +440,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -446,9 +448,6 @@ private: std::array data_; }; - - } } // namespace DenseAd, Opm - #endif // OPM_DENSEAD_EVALUATION3_HPP diff --git a/opm/material/densead/Evaluation4.hpp b/opm/material/densead/Evaluation4.hpp index b703d8ab2..978f37f4e 100644 --- a/opm/material/densead/Evaluation4.hpp +++ b/opm/material/densead/Evaluation4.hpp @@ -23,18 +23,15 @@ /*! * \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 - +#include "Evaluation.hpp" #include "Math.hpp" #include @@ -51,7 +48,6 @@ namespace Opm { namespace DenseAd { - template class Evaluation { @@ -59,9 +55,9 @@ public: //! field type typedef ValueT ValueType; - //! number of derivatives + //! number of derivatives static constexpr int size = 4; - + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -80,7 +76,7 @@ public: //! copy other function evaluation Evaluation(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -107,18 +103,19 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - { + { data_[1] = 0.0; data_[2] = 0.0; data_[3] = 0.0; @@ -147,6 +144,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -155,23 +153,23 @@ public: // 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]; - } + } // 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]; - + return *this; } @@ -181,18 +179,19 @@ public: { // 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) - { + { 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]; - + return *this; } @@ -217,7 +216,7 @@ public: // value data_[valuepos_] *= v ; - // derivatives + // derivatives 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; @@ -229,32 +228,29 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - { + { data_[0] *= other; data_[1] *= other; data_[2] *= other; data_[3] *= other; data_[4] *= other; - + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 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; + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); + data_[1] = (v*data_[1] - u*other.data_[1])/(v*v); + data_[2] = (v*data_[2] - u*other.data_[2])/(v*v); + data_[3] = (v*data_[3] - u*other.data_[3])/(v*v); + data_[4] = (v*data_[4] - u*other.data_[4])/(v*v); + u /= v; - // value - data_[valuepos_] *= v_vv; - - // derivatives - 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; - return *this; } @@ -263,38 +259,23 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - + data_[0] *= tmp; data_[1] *= tmp; data_[2] *= tmp; data_[3] *= tmp; data_[4] *= tmp; - - return *this; - } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - - 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; + return *this; } // add two evaluation objects Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -303,7 +284,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -311,7 +294,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -319,27 +305,33 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative + + // set value and derivatives to negative result.data_[0] = - data_[0]; result.data_[1] = - data_[1]; result.data_[2] = - data_[2]; result.data_[3] = - data_[3]; result.data_[4] = - data_[4]; - + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -347,14 +339,18 @@ public: 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; } @@ -362,7 +358,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -371,18 +369,19 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation 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]; - + return *this; } @@ -444,6 +443,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -451,6 +451,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -458,9 +459,6 @@ private: std::array data_; }; - - } } // namespace DenseAd, Opm - #endif // OPM_DENSEAD_EVALUATION4_HPP diff --git a/opm/material/densead/Evaluation5.hpp b/opm/material/densead/Evaluation5.hpp index 230e1dc7f..36577c46c 100644 --- a/opm/material/densead/Evaluation5.hpp +++ b/opm/material/densead/Evaluation5.hpp @@ -23,18 +23,15 @@ /*! * \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 - +#include "Evaluation.hpp" #include "Math.hpp" #include @@ -51,7 +48,6 @@ namespace Opm { namespace DenseAd { - template class Evaluation { @@ -59,9 +55,9 @@ public: //! field type typedef ValueT ValueType; - //! number of derivatives + //! number of derivatives static constexpr int size = 5; - + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -80,7 +76,7 @@ public: //! copy other function evaluation Evaluation(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -108,18 +104,19 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - { + { data_[1] = 0.0; data_[2] = 0.0; data_[3] = 0.0; @@ -149,6 +146,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -157,25 +155,25 @@ public: // 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]; - } + } // 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]; - + return *this; } @@ -185,19 +183,20 @@ public: { // 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) - { + { 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]; - + return *this; } @@ -222,7 +221,7 @@ public: // value data_[valuepos_] *= v ; - // derivatives + // derivatives 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; @@ -235,34 +234,31 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - { + { data_[0] *= other; data_[1] *= other; data_[2] *= other; data_[3] *= other; data_[4] *= other; data_[5] *= other; - + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 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; + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); + data_[1] = (v*data_[1] - u*other.data_[1])/(v*v); + data_[2] = (v*data_[2] - u*other.data_[2])/(v*v); + data_[3] = (v*data_[3] - u*other.data_[3])/(v*v); + data_[4] = (v*data_[4] - u*other.data_[4])/(v*v); + data_[5] = (v*data_[5] - u*other.data_[5])/(v*v); + u /= v; - // value - data_[valuepos_] *= v_vv; - - // derivatives - 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; - return *this; } @@ -271,40 +267,24 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - + data_[0] *= tmp; data_[1] *= tmp; data_[2] *= tmp; data_[3] *= tmp; data_[4] *= tmp; data_[5] *= tmp; - - return *this; - } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - - 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; + return *this; } // add two evaluation objects Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -313,7 +293,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -321,7 +303,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -329,28 +314,34 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative + + // set value and derivatives to negative result.data_[0] = - data_[0]; result.data_[1] = - data_[1]; result.data_[2] = - data_[2]; result.data_[3] = - data_[3]; result.data_[4] = - data_[4]; result.data_[5] = - data_[5]; - + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -358,14 +349,18 @@ public: 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; } @@ -373,7 +368,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -382,19 +379,20 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation 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]; - + return *this; } @@ -456,6 +454,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -463,6 +462,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -470,9 +470,6 @@ private: std::array data_; }; - - } } // namespace DenseAd, Opm - #endif // OPM_DENSEAD_EVALUATION5_HPP diff --git a/opm/material/densead/Evaluation6.hpp b/opm/material/densead/Evaluation6.hpp index 25a13984c..eca218b8d 100644 --- a/opm/material/densead/Evaluation6.hpp +++ b/opm/material/densead/Evaluation6.hpp @@ -23,18 +23,15 @@ /*! * \file * - * \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_DENSEAD_EVALUATION6_HPP #define OPM_DENSEAD_EVALUATION6_HPP - +#include "Evaluation.hpp" #include "Math.hpp" #include @@ -51,7 +48,6 @@ namespace Opm { namespace DenseAd { - template class Evaluation { @@ -59,9 +55,9 @@ public: //! field type typedef ValueT ValueType; - //! number of derivatives + //! number of derivatives static constexpr int size = 6; - + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -80,7 +76,7 @@ public: //! copy other function evaluation Evaluation(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -109,18 +105,19 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - { + { data_[1] = 0.0; data_[2] = 0.0; data_[3] = 0.0; @@ -151,6 +148,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -159,19 +157,19 @@ public: // 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]; @@ -179,7 +177,7 @@ public: data_[4] += other.data_[4]; data_[5] += other.data_[5]; data_[6] += other.data_[6]; - + return *this; } @@ -189,12 +187,13 @@ public: { // 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) - { + { data_[0] -= other.data_[0]; data_[1] -= other.data_[1]; data_[2] -= other.data_[2]; @@ -202,7 +201,7 @@ public: data_[4] -= other.data_[4]; data_[5] -= other.data_[5]; data_[6] -= other.data_[6]; - + return *this; } @@ -227,7 +226,7 @@ public: // value data_[valuepos_] *= v ; - // derivatives + // derivatives 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; @@ -241,7 +240,7 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - { + { data_[0] *= other; data_[1] *= other; data_[2] *= other; @@ -249,28 +248,25 @@ public: data_[4] *= other; data_[5] *= other; data_[6] *= other; - + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 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; + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); + data_[1] = (v*data_[1] - u*other.data_[1])/(v*v); + data_[2] = (v*data_[2] - u*other.data_[2])/(v*v); + data_[3] = (v*data_[3] - u*other.data_[3])/(v*v); + data_[4] = (v*data_[4] - u*other.data_[4])/(v*v); + data_[5] = (v*data_[5] - u*other.data_[5])/(v*v); + data_[6] = (v*data_[6] - u*other.data_[6])/(v*v); + u /= v; - // value - data_[valuepos_] *= v_vv; - - // derivatives - 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; } @@ -279,7 +275,7 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - + data_[0] *= tmp; data_[1] *= tmp; data_[2] *= tmp; @@ -287,34 +283,17 @@ public: data_[4] *= tmp; data_[5] *= tmp; data_[6] *= tmp; - - return *this; - } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - - 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; + return *this; } // add two evaluation objects Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -323,7 +302,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -331,7 +312,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -339,14 +323,18 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative + + // set value and derivatives to negative result.data_[0] = - data_[0]; result.data_[1] = - data_[1]; result.data_[2] = - data_[2]; @@ -354,14 +342,16 @@ public: result.data_[4] = - data_[4]; result.data_[5] = - data_[5]; result.data_[6] = - data_[6]; - + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -369,14 +359,18 @@ public: 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; } @@ -384,7 +378,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -393,12 +389,13 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation Evaluation& operator=(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -406,7 +403,7 @@ public: data_[4] = other.data_[4]; data_[5] = other.data_[5]; data_[6] = other.data_[6]; - + return *this; } @@ -468,6 +465,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -475,6 +473,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -482,9 +481,6 @@ private: std::array data_; }; - - } } // namespace DenseAd, Opm - #endif // OPM_DENSEAD_EVALUATION6_HPP diff --git a/opm/material/densead/Evaluation7.hpp b/opm/material/densead/Evaluation7.hpp index 72ebd2458..8703ef515 100644 --- a/opm/material/densead/Evaluation7.hpp +++ b/opm/material/densead/Evaluation7.hpp @@ -23,18 +23,15 @@ /*! * \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 - +#include "Evaluation.hpp" #include "Math.hpp" #include @@ -51,7 +48,6 @@ namespace Opm { namespace DenseAd { - template class Evaluation { @@ -59,9 +55,9 @@ public: //! field type typedef ValueT ValueType; - //! number of derivatives + //! number of derivatives static constexpr int size = 7; - + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -80,7 +76,7 @@ public: //! copy other function evaluation Evaluation(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -110,18 +106,19 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - { + { data_[1] = 0.0; data_[2] = 0.0; data_[3] = 0.0; @@ -153,6 +150,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -161,7 +159,7 @@ public: // 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]; @@ -169,12 +167,12 @@ public: data_[5] = other.data_[5]; data_[6] = other.data_[6]; data_[7] = other.data_[7]; - } + } // 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]; @@ -183,7 +181,7 @@ public: data_[5] += other.data_[5]; data_[6] += other.data_[6]; data_[7] += other.data_[7]; - + return *this; } @@ -193,12 +191,13 @@ public: { // 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) - { + { data_[0] -= other.data_[0]; data_[1] -= other.data_[1]; data_[2] -= other.data_[2]; @@ -207,7 +206,7 @@ public: data_[5] -= other.data_[5]; data_[6] -= other.data_[6]; data_[7] -= other.data_[7]; - + return *this; } @@ -232,7 +231,7 @@ public: // value data_[valuepos_] *= v ; - // derivatives + // derivatives 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; @@ -247,7 +246,7 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - { + { data_[0] *= other; data_[1] *= other; data_[2] *= other; @@ -256,29 +255,26 @@ public: data_[5] *= other; data_[6] *= other; data_[7] *= other; - + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 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; + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); + data_[1] = (v*data_[1] - u*other.data_[1])/(v*v); + data_[2] = (v*data_[2] - u*other.data_[2])/(v*v); + data_[3] = (v*data_[3] - u*other.data_[3])/(v*v); + data_[4] = (v*data_[4] - u*other.data_[4])/(v*v); + data_[5] = (v*data_[5] - u*other.data_[5])/(v*v); + data_[6] = (v*data_[6] - u*other.data_[6])/(v*v); + data_[7] = (v*data_[7] - u*other.data_[7])/(v*v); + u /= v; - // value - data_[valuepos_] *= v_vv; - - // derivatives - 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; - return *this; } @@ -287,7 +283,7 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - + data_[0] *= tmp; data_[1] *= tmp; data_[2] *= tmp; @@ -296,35 +292,17 @@ public: data_[5] *= tmp; data_[6] *= tmp; data_[7] *= tmp; - - return *this; - } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - - 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; + return *this; } // add two evaluation objects Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -333,7 +311,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -341,7 +321,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -349,14 +332,18 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative + + // set value and derivatives to negative result.data_[0] = - data_[0]; result.data_[1] = - data_[1]; result.data_[2] = - data_[2]; @@ -365,14 +352,16 @@ public: result.data_[5] = - data_[5]; result.data_[6] = - data_[6]; result.data_[7] = - data_[7]; - + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -380,14 +369,18 @@ public: 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; } @@ -395,7 +388,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -404,12 +399,13 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation Evaluation& operator=(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -418,7 +414,7 @@ public: data_[5] = other.data_[5]; data_[6] = other.data_[6]; data_[7] = other.data_[7]; - + return *this; } @@ -480,6 +476,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -487,6 +484,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -494,9 +492,6 @@ private: std::array data_; }; - - } } // namespace DenseAd, Opm - #endif // OPM_DENSEAD_EVALUATION7_HPP diff --git a/opm/material/densead/Evaluation8.hpp b/opm/material/densead/Evaluation8.hpp index 030283af5..5165f07b5 100644 --- a/opm/material/densead/Evaluation8.hpp +++ b/opm/material/densead/Evaluation8.hpp @@ -23,18 +23,15 @@ /*! * \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 - +#include "Evaluation.hpp" #include "Math.hpp" #include @@ -51,7 +48,6 @@ namespace Opm { namespace DenseAd { - template class Evaluation { @@ -59,9 +55,9 @@ public: //! field type typedef ValueT ValueType; - //! number of derivatives + //! number of derivatives static constexpr int size = 8; - + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -80,7 +76,7 @@ public: //! copy other function evaluation Evaluation(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -111,18 +107,19 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - { + { data_[1] = 0.0; data_[2] = 0.0; data_[3] = 0.0; @@ -155,6 +152,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -163,7 +161,7 @@ public: // 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]; @@ -172,12 +170,12 @@ public: data_[6] = other.data_[6]; data_[7] = other.data_[7]; data_[8] = other.data_[8]; - } + } // 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]; @@ -187,7 +185,7 @@ public: data_[6] += other.data_[6]; data_[7] += other.data_[7]; data_[8] += other.data_[8]; - + return *this; } @@ -197,12 +195,13 @@ public: { // 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) - { + { data_[0] -= other.data_[0]; data_[1] -= other.data_[1]; data_[2] -= other.data_[2]; @@ -212,7 +211,7 @@ public: data_[6] -= other.data_[6]; data_[7] -= other.data_[7]; data_[8] -= other.data_[8]; - + return *this; } @@ -237,7 +236,7 @@ public: // value data_[valuepos_] *= v ; - // derivatives + // derivatives 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; @@ -253,7 +252,7 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - { + { data_[0] *= other; data_[1] *= other; data_[2] *= other; @@ -263,30 +262,27 @@ public: data_[6] *= other; data_[7] *= other; data_[8] *= other; - + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 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; + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); + data_[1] = (v*data_[1] - u*other.data_[1])/(v*v); + data_[2] = (v*data_[2] - u*other.data_[2])/(v*v); + data_[3] = (v*data_[3] - u*other.data_[3])/(v*v); + data_[4] = (v*data_[4] - u*other.data_[4])/(v*v); + data_[5] = (v*data_[5] - u*other.data_[5])/(v*v); + data_[6] = (v*data_[6] - u*other.data_[6])/(v*v); + data_[7] = (v*data_[7] - u*other.data_[7])/(v*v); + data_[8] = (v*data_[8] - u*other.data_[8])/(v*v); + u /= v; - // value - data_[valuepos_] *= v_vv; - - // derivatives - 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; - return *this; } @@ -295,7 +291,7 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - + data_[0] *= tmp; data_[1] *= tmp; data_[2] *= tmp; @@ -305,36 +301,17 @@ public: data_[6] *= tmp; data_[7] *= tmp; data_[8] *= tmp; - - return *this; - } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - - 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; + return *this; } // add two evaluation objects Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -343,7 +320,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -351,7 +330,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -359,14 +341,18 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative + + // set value and derivatives to negative result.data_[0] = - data_[0]; result.data_[1] = - data_[1]; result.data_[2] = - data_[2]; @@ -376,14 +362,16 @@ public: result.data_[6] = - data_[6]; result.data_[7] = - data_[7]; result.data_[8] = - data_[8]; - + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -391,14 +379,18 @@ public: 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; } @@ -406,7 +398,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -415,12 +409,13 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation Evaluation& operator=(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -430,7 +425,7 @@ public: data_[6] = other.data_[6]; data_[7] = other.data_[7]; data_[8] = other.data_[8]; - + return *this; } @@ -492,6 +487,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -499,6 +495,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -506,9 +503,6 @@ private: std::array data_; }; - - } } // namespace DenseAd, Opm - #endif // OPM_DENSEAD_EVALUATION8_HPP diff --git a/opm/material/densead/Evaluation9.hpp b/opm/material/densead/Evaluation9.hpp index eed038213..fe8f7343a 100644 --- a/opm/material/densead/Evaluation9.hpp +++ b/opm/material/densead/Evaluation9.hpp @@ -23,18 +23,15 @@ /*! * \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 - +#include "Evaluation.hpp" #include "Math.hpp" #include @@ -51,7 +48,6 @@ namespace Opm { namespace DenseAd { - template class Evaluation { @@ -59,9 +55,9 @@ public: //! field type typedef ValueT ValueType; - //! number of derivatives + //! number of derivatives static constexpr int size = 9; - + protected: //! length of internal data vector static constexpr int length_ = size + 1; @@ -80,7 +76,7 @@ public: //! copy other function evaluation Evaluation(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -112,18 +108,19 @@ public: template Evaluation(const RhsValueType& c, int varPos) { - setValue( c ); - clearDerivatives(); // The variable position must be in represented by the given variable descriptor assert(0 <= varPos && varPos < size); + setValue( c ); + clearDerivatives(); + data_[varPos + dstart_] = 1.0; Valgrind::CheckDefined(data_); } // set all derivatives to zero void clearDerivatives() - { + { data_[1] = 0.0; data_[2] = 0.0; data_[3] = 0.0; @@ -157,6 +154,7 @@ public: { // print value os << "v: " << value() << " / d:"; + // print derivatives for (int varIdx = 0; varIdx < size; ++varIdx) { os << " " << derivative(varIdx); @@ -165,7 +163,7 @@ public: // 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]; @@ -175,12 +173,12 @@ public: data_[7] = other.data_[7]; data_[8] = other.data_[8]; data_[9] = other.data_[9]; - } + } // 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]; @@ -191,7 +189,7 @@ public: data_[7] += other.data_[7]; data_[8] += other.data_[8]; data_[9] += other.data_[9]; - + return *this; } @@ -201,12 +199,13 @@ public: { // 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) - { + { data_[0] -= other.data_[0]; data_[1] -= other.data_[1]; data_[2] -= other.data_[2]; @@ -217,7 +216,7 @@ public: data_[7] -= other.data_[7]; data_[8] -= other.data_[8]; data_[9] -= other.data_[9]; - + return *this; } @@ -242,7 +241,7 @@ public: // value data_[valuepos_] *= v ; - // derivatives + // derivatives 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; @@ -259,7 +258,7 @@ public: // m(c*u)' = c*u' template Evaluation& operator*=(const RhsValueType& other) - { + { data_[0] *= other; data_[1] *= other; data_[2] *= other; @@ -270,31 +269,28 @@ public: data_[7] *= other; data_[8] *= other; data_[9] *= other; - + return *this; } - // m(u*v)' = (v'u + u'v) + // m(u*v)' = (vu' - uv')/v^2 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; + // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u - + // u'v)/v^2. + ValueType& u = data_[ valuepos_ ]; + const ValueType& v = other.value(); + data_[1] = (v*data_[1] - u*other.data_[1])/(v*v); + data_[2] = (v*data_[2] - u*other.data_[2])/(v*v); + data_[3] = (v*data_[3] - u*other.data_[3])/(v*v); + data_[4] = (v*data_[4] - u*other.data_[4])/(v*v); + data_[5] = (v*data_[5] - u*other.data_[5])/(v*v); + data_[6] = (v*data_[6] - u*other.data_[6])/(v*v); + data_[7] = (v*data_[7] - u*other.data_[7])/(v*v); + data_[8] = (v*data_[8] - u*other.data_[8])/(v*v); + data_[9] = (v*data_[9] - u*other.data_[9])/(v*v); + u /= v; - // value - data_[valuepos_] *= v_vv; - - // derivatives - 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; - return *this; } @@ -303,7 +299,7 @@ public: Evaluation& operator/=(const RhsValueType& other) { const ValueType tmp = 1.0/other; - + data_[0] *= tmp; data_[1] *= tmp; data_[2] *= tmp; @@ -314,37 +310,17 @@ public: data_[7] *= tmp; data_[8] *= tmp; data_[9] *= tmp; - - return *this; - } - // division of a constant by an Evaluation - template - static inline Evaluation divide(const RhsValueType& a, const Evaluation& b) - { - Evaluation result; - const ValueType tmp = 1.0/b.value(); - result.setValue( a*tmp ); - const ValueType df_dg = - result.value()*tmp; - - 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; + return *this; } // add two evaluation objects Evaluation operator+(const Evaluation& other) const { Evaluation result(*this); + result += other; + return result; } @@ -353,7 +329,9 @@ public: Evaluation operator+(const RhsValueType& other) const { Evaluation result(*this); + result += other; + return result; } @@ -361,7 +339,10 @@ public: Evaluation operator-(const Evaluation& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // subtract constant from evaluation object @@ -369,14 +350,18 @@ public: Evaluation operator-(const RhsValueType& other) const { Evaluation result(*this); - return (result -= other); + + result -= other; + + return result; } // negation (unary minus) operator Evaluation operator-() const { Evaluation result; - // set value and derivatives to negative + + // set value and derivatives to negative result.data_[0] = - data_[0]; result.data_[1] = - data_[1]; result.data_[2] = - data_[2]; @@ -387,14 +372,16 @@ public: result.data_[7] = - data_[7]; result.data_[8] = - data_[8]; result.data_[9] = - data_[9]; - + return result; } Evaluation operator*(const Evaluation& other) const { Evaluation result(*this); + result *= other; + return result; } @@ -402,14 +389,18 @@ public: 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; } @@ -417,7 +408,9 @@ public: Evaluation operator/(const RhsValueType& other) const { Evaluation result(*this); + result /= other; + return result; } @@ -426,12 +419,13 @@ public: { setValue( other ); clearDerivatives(); + return *this; } // copy assignment from evaluation Evaluation& operator=(const Evaluation& other) - { + { data_[0] = other.data_[0]; data_[1] = other.data_[1]; data_[2] = other.data_[2]; @@ -442,7 +436,7 @@ public: data_[7] = other.data_[7]; data_[8] = other.data_[8]; data_[9] = other.data_[9]; - + return *this; } @@ -504,6 +498,7 @@ public: const ValueType& derivative(int varIdx) const { assert(0 <= varIdx && varIdx < size); + return data_[dstart_ + varIdx]; } @@ -511,6 +506,7 @@ public: void setDerivative(int varIdx, const ValueType& derVal) { assert(0 <= varIdx && varIdx < size); + data_[dstart_ + varIdx] = derVal; } @@ -518,9 +514,6 @@ private: std::array data_; }; - - } } // namespace DenseAd, Opm - #endif // OPM_DENSEAD_EVALUATION9_HPP diff --git a/opm/material/densead/EvaluationSpecializations.hpp b/opm/material/densead/EvaluationSpecializations.hpp index 4116ddb86..4d3666387 100644 --- a/opm/material/densead/EvaluationSpecializations.hpp +++ b/opm/material/densead/EvaluationSpecializations.hpp @@ -44,5 +44,4 @@ #include #include - #endif // OPM_DENSEAD_EVALUATION_SPECIALIZATIONS_HPP \ No newline at end of file