00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00031 #ifndef OPM_DENSEAD_EVALUATION4_HPP
00032 #define OPM_DENSEAD_EVALUATION4_HPP
00033
00034 #include "Evaluation.hpp"
00035 #include "Math.hpp"
00036
00037 #include <opm/common/Valgrind.hpp>
00038
00039 #include <dune/common/version.hh>
00040
00041 #include <array>
00042 #include <cmath>
00043 #include <cassert>
00044 #include <cstring>
00045 #include <iostream>
00046 #include <algorithm>
00047
00048 namespace Opm {
00049 namespace DenseAd {
00050
00051 template <class ValueT>
00052 class Evaluation<ValueT, 4>
00053 {
00054 public:
00056 typedef ValueT ValueType;
00057
00059 static constexpr int size = 4;
00060
00061 protected:
00063 static constexpr int length_ = size + 1;
00064
00066 static constexpr int valuepos_ = 0;
00068 static constexpr int dstart_ = 1;
00070 static constexpr int dend_ = length_;
00071
00072 public:
00074 Evaluation() : data_()
00075 {}
00076
00078 Evaluation(const Evaluation& other) = default;
00079
00080
00081
00082
00083
00084 template <class RhsValueType>
00085 Evaluation(const RhsValueType& c)
00086 {
00087 setValue( c );
00088 clearDerivatives();
00089 Valgrind::CheckDefined( data_ );
00090 }
00091
00092
00093
00094
00095
00096 template <class RhsValueType>
00097 Evaluation(const RhsValueType& c, int varPos)
00098 {
00099
00100 assert(0 <= varPos && varPos < size);
00101
00102 setValue( c );
00103 clearDerivatives();
00104
00105 data_[varPos + dstart_] = 1.0;
00106 Valgrind::CheckDefined(data_);
00107 }
00108
00109
00110 void clearDerivatives()
00111 {
00112 data_[1] = 0.0;
00113 data_[2] = 0.0;
00114 data_[3] = 0.0;
00115 data_[4] = 0.0;
00116 }
00117
00118
00119 template <class RhsValueType>
00120 static Evaluation createVariable(const RhsValueType& value, int varPos)
00121 {
00122
00123
00124 return Evaluation( value, varPos );
00125 }
00126
00127
00128
00129 template <class RhsValueType>
00130 static Evaluation createConstant(const RhsValueType& value)
00131 {
00132 return Evaluation( value );
00133 }
00134
00135
00136 void print(std::ostream& os = std::cout) const
00137 {
00138
00139 os << "v: " << value() << " / d:";
00140
00141
00142 for (int varIdx = 0; varIdx < size; ++varIdx) {
00143 os << " " << derivative(varIdx);
00144 }
00145 }
00146
00147
00148 void copyDerivatives(const Evaluation& other)
00149 {
00150 data_[1] = other.data_[1];
00151 data_[2] = other.data_[2];
00152 data_[3] = other.data_[3];
00153 data_[4] = other.data_[4];
00154 }
00155
00156
00157
00158 Evaluation& operator+=(const Evaluation& other)
00159 {
00160 data_[0] += other.data_[0];
00161 data_[1] += other.data_[1];
00162 data_[2] += other.data_[2];
00163 data_[3] += other.data_[3];
00164 data_[4] += other.data_[4];
00165
00166 return *this;
00167 }
00168
00169
00170 template <class RhsValueType>
00171 Evaluation& operator+=(const RhsValueType& other)
00172 {
00173
00174 data_[valuepos_] += other;
00175
00176 return *this;
00177 }
00178
00179
00180 Evaluation& operator-=(const Evaluation& other)
00181 {
00182 data_[0] -= other.data_[0];
00183 data_[1] -= other.data_[1];
00184 data_[2] -= other.data_[2];
00185 data_[3] -= other.data_[3];
00186 data_[4] -= other.data_[4];
00187
00188 return *this;
00189 }
00190
00191
00192 template <class RhsValueType>
00193 Evaluation& operator-=(const RhsValueType& other)
00194 {
00195
00196 data_[ valuepos_ ] -= other;
00197
00198 return *this;
00199 }
00200
00201
00202 Evaluation& operator*=(const Evaluation& other)
00203 {
00204
00205
00206 const ValueType u = this->value();
00207 const ValueType v = other.value();
00208
00209
00210 data_[valuepos_] *= v ;
00211
00212
00213 data_[1] = data_[1] * v + other.data_[1] * u;
00214 data_[2] = data_[2] * v + other.data_[2] * u;
00215 data_[3] = data_[3] * v + other.data_[3] * u;
00216 data_[4] = data_[4] * v + other.data_[4] * u;
00217
00218 return *this;
00219 }
00220
00221
00222 template <class RhsValueType>
00223 Evaluation& operator*=(const RhsValueType& other)
00224 {
00225 data_[0] *= other;
00226 data_[1] *= other;
00227 data_[2] *= other;
00228 data_[3] *= other;
00229 data_[4] *= other;
00230
00231 return *this;
00232 }
00233
00234
00235 Evaluation& operator/=(const Evaluation& other)
00236 {
00237
00238
00239 ValueType& u = data_[ valuepos_ ];
00240 const ValueType& v = other.value();
00241 data_[1] = (v*data_[1] - u*other.data_[1])/(v*v);
00242 data_[2] = (v*data_[2] - u*other.data_[2])/(v*v);
00243 data_[3] = (v*data_[3] - u*other.data_[3])/(v*v);
00244 data_[4] = (v*data_[4] - u*other.data_[4])/(v*v);
00245 u /= v;
00246
00247 return *this;
00248 }
00249
00250
00251 template <class RhsValueType>
00252 Evaluation& operator/=(const RhsValueType& other)
00253 {
00254 const ValueType tmp = 1.0/other;
00255
00256 data_[0] *= tmp;
00257 data_[1] *= tmp;
00258 data_[2] *= tmp;
00259 data_[3] *= tmp;
00260 data_[4] *= tmp;
00261
00262 return *this;
00263 }
00264
00265
00266 Evaluation operator+(const Evaluation& other) const
00267 {
00268 Evaluation result(*this);
00269
00270 result += other;
00271
00272 return result;
00273 }
00274
00275
00276 template <class RhsValueType>
00277 Evaluation operator+(const RhsValueType& other) const
00278 {
00279 Evaluation result(*this);
00280
00281 result += other;
00282
00283 return result;
00284 }
00285
00286
00287 Evaluation operator-(const Evaluation& other) const
00288 {
00289 Evaluation result(*this);
00290
00291 result -= other;
00292
00293 return result;
00294 }
00295
00296
00297 template <class RhsValueType>
00298 Evaluation operator-(const RhsValueType& other) const
00299 {
00300 Evaluation result(*this);
00301
00302 result -= other;
00303
00304 return result;
00305 }
00306
00307
00308 Evaluation operator-() const
00309 {
00310 Evaluation result;
00311
00312
00313 result.data_[0] = - data_[0];
00314 result.data_[1] = - data_[1];
00315 result.data_[2] = - data_[2];
00316 result.data_[3] = - data_[3];
00317 result.data_[4] = - data_[4];
00318
00319 return result;
00320 }
00321
00322 Evaluation operator*(const Evaluation& other) const
00323 {
00324 Evaluation result(*this);
00325
00326 result *= other;
00327
00328 return result;
00329 }
00330
00331 template <class RhsValueType>
00332 Evaluation operator*(const RhsValueType& other) const
00333 {
00334 Evaluation result(*this);
00335
00336 result *= other;
00337
00338 return result;
00339 }
00340
00341 Evaluation operator/(const Evaluation& other) const
00342 {
00343 Evaluation result(*this);
00344
00345 result /= other;
00346
00347 return result;
00348 }
00349
00350 template <class RhsValueType>
00351 Evaluation operator/(const RhsValueType& other) const
00352 {
00353 Evaluation result(*this);
00354
00355 result /= other;
00356
00357 return result;
00358 }
00359
00360 template <class RhsValueType>
00361 Evaluation& operator=(const RhsValueType& other)
00362 {
00363 setValue( other );
00364 clearDerivatives();
00365
00366 return *this;
00367 }
00368
00369
00370 Evaluation& operator=(const Evaluation& other) = default;
00371
00372 template <class RhsValueType>
00373 bool operator==(const RhsValueType& other) const
00374 { return value() == other; }
00375
00376 bool operator==(const Evaluation& other) const
00377 {
00378 for (int idx = 0; idx < length_; ++idx) {
00379 if (data_[idx] != other.data_[idx]) {
00380 return false;
00381 }
00382 }
00383 return true;
00384 }
00385
00386 bool operator!=(const Evaluation& other) const
00387 { return !operator==(other); }
00388
00389 template <class RhsValueType>
00390 bool operator>(RhsValueType other) const
00391 { return value() > other; }
00392
00393 bool operator>(const Evaluation& other) const
00394 { return value() > other.value(); }
00395
00396 template <class RhsValueType>
00397 bool operator<(RhsValueType other) const
00398 { return value() < other; }
00399
00400 bool operator<(const Evaluation& other) const
00401 { return value() < other.value(); }
00402
00403 template <class RhsValueType>
00404 bool operator>=(RhsValueType other) const
00405 { return value() >= other; }
00406
00407 bool operator>=(const Evaluation& other) const
00408 { return value() >= other.value(); }
00409
00410 template <class RhsValueType>
00411 bool operator<=(RhsValueType other) const
00412 { return value() <= other; }
00413
00414 bool operator<=(const Evaluation& other) const
00415 { return value() <= other.value(); }
00416
00417
00418 const ValueType& value() const
00419 { return data_[valuepos_]; }
00420
00421
00422 template <class RhsValueType>
00423 void setValue(const RhsValueType& val)
00424 { data_[valuepos_] = val; }
00425
00426
00427 const ValueType& derivative(int varIdx) const
00428 {
00429 assert(0 <= varIdx && varIdx < size);
00430
00431 return data_[dstart_ + varIdx];
00432 }
00433
00434
00435 void setDerivative(int varIdx, const ValueType& derVal)
00436 {
00437 assert(0 <= varIdx && varIdx < size);
00438
00439 data_[dstart_ + varIdx] = derVal;
00440 }
00441
00442 private:
00443 std::array<ValueT, length_> data_;
00444 };
00445
00446 } }
00447
00448 #endif // OPM_DENSEAD_EVALUATION4_HPP