My Project
Loading...
Searching...
No Matches
Evaluation.hpp
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
32#ifndef OPM_DENSEAD_EVALUATION_HPP
33#define OPM_DENSEAD_EVALUATION_HPP
34
35#ifndef NDEBUG
37#endif
38
39#include <array>
40#include <cassert>
41#include <iosfwd>
42#include <stdexcept>
43
44#include <opm/common/utility/gpuDecorators.hpp>
45
46namespace Opm {
47namespace DenseAd {
48
51static constexpr int DynamicSize = -1;
52
57template <class ValueT, int numDerivs, unsigned staticSize = 0>
59{
60public:
63 static const int numVars = numDerivs;
64
66 typedef ValueT ValueType;
67
69 OPM_HOST_DEVICE constexpr int size() const
70 { return numDerivs; }
71
72protected:
74 OPM_HOST_DEVICE constexpr int length_() const
75 { return size() + 1; }
76
77
79 OPM_HOST_DEVICE constexpr int valuepos_() const
80 { return 0; }
82 OPM_HOST_DEVICE constexpr int dstart_() const
83 { return 1; }
85 OPM_HOST_DEVICE constexpr int dend_() const
86 { return length_(); }
87
90 OPM_HOST_DEVICE void checkDefined_() const
91 {
92#ifndef NDEBUG
93 for (const auto& v: data_)
94 Valgrind::CheckDefined(v);
95#endif
96 }
97
98public:
100 OPM_HOST_DEVICE Evaluation() : data_()
101 {}
102
104 Evaluation(const Evaluation& other) = default;
105
106
107 // create an evaluation which represents a constant function
108 //
109 // i.e., f(x) = c. this implies an evaluation with the given value and all
110 // derivatives being zero.
111 template <class RhsValueType>
112 OPM_HOST_DEVICE Evaluation(const RhsValueType& c)
113 {
114 setValue(c);
115 clearDerivatives();
116
118 }
119
120 // create an evaluation which represents a constant function
121 //
122 // i.e., f(x) = c. this implies an evaluation with the given value and all
123 // derivatives being zero.
124 template <class RhsValueType>
125 OPM_HOST_DEVICE Evaluation(const RhsValueType& c, int varPos)
126 {
127 // The variable position must be in represented by the given variable descriptor
128 assert(0 <= varPos && varPos < size());
129
130 setValue( c );
131 clearDerivatives();
132
133 data_[varPos + dstart_()] = 1.0;
134
136 }
137
138 // set all derivatives to zero
139 OPM_HOST_DEVICE void clearDerivatives()
140 {
141 for (int i = dstart_(); i < dend_(); ++i)
142 data_[i] = 0.0;
143 }
144
145 // create an uninitialized Evaluation object that is compatible with the
146 // argument, but not initialized
147 //
148 // This basically boils down to the copy constructor without copying
149 // anything. If the number of derivatives is known at compile time, this
150 // is equivalent to creating an uninitialized object using the default
151 // constructor, while for dynamic evaluations, it creates an Evaluation
152 // object which exhibits the same number of derivatives as the argument.
153 OPM_HOST_DEVICE static Evaluation createBlank(const Evaluation&)
154 { return Evaluation(); }
155
156 // create an Evaluation with value and all the derivatives to be zero
157 OPM_HOST_DEVICE static Evaluation createConstantZero(const Evaluation&)
158 { return Evaluation(0.); }
159
160 // create an Evaluation with value to be one and all the derivatives to be zero
161 OPM_HOST_DEVICE static Evaluation createConstantOne(const Evaluation&)
162 { return Evaluation(1.); }
163
164 // create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
165 template <class RhsValueType>
166 OPM_HOST_DEVICE static Evaluation createVariable(const RhsValueType& value, int varPos)
167 {
168 // copy function value and set all derivatives to 0, except for the variable
169 // which is represented by the value (which is set to 1.0)
170 return Evaluation(value, varPos);
171 }
172
173 template <class RhsValueType>
174 OPM_HOST_DEVICE static Evaluation createVariable(int nVars, const RhsValueType& value, int varPos)
175 {
176 if (nVars != 0)
177 throw std::logic_error("This statically-sized evaluation can only represent objects"
178 " with 0 derivatives");
179
180 // copy function value and set all derivatives to 0, except for the variable
181 // which is represented by the value (which is set to 1.0)
182 return Evaluation(nVars, value, varPos);
183 }
184
185 template <class RhsValueType>
186 OPM_HOST_DEVICE static Evaluation createVariable(const Evaluation&, const RhsValueType& value, int varPos)
187 {
188 // copy function value and set all derivatives to 0, except for the variable
189 // which is represented by the value (which is set to 1.0)
190 return Evaluation(value, varPos);
191 }
192
193
194 // "evaluate" a constant function (i.e. a function that does not depend on the set of
195 // relevant variables, f(x) = c).
196 template <class RhsValueType>
197 OPM_HOST_DEVICE static Evaluation createConstant(int nVars, const RhsValueType& value)
198 {
199 if (nVars != 0)
200 throw std::logic_error("This statically-sized evaluation can only represent objects"
201 " with 0 derivatives");
202 return Evaluation(value);
203 }
204
205 // "evaluate" a constant function (i.e. a function that does not depend on the set of
206 // relevant variables, f(x) = c).
207 template <class RhsValueType>
208 OPM_HOST_DEVICE static Evaluation createConstant(const RhsValueType& value)
209 {
210 return Evaluation(value);
211 }
212
213 // "evaluate" a constant function (i.e. a function that does not depend on the set of
214 // relevant variables, f(x) = c).
215 template <class RhsValueType>
216 OPM_HOST_DEVICE static Evaluation createConstant(const Evaluation&, const RhsValueType& value)
217 {
218 return Evaluation(value);
219 }
220
221 // copy all derivatives from other
222 OPM_HOST_DEVICE void copyDerivatives(const Evaluation& other)
223 {
224 assert(size() == other.size());
225
226 for (int i = dstart_(); i < dend_(); ++i)
227 data_[i] = other.data_[i];
228 }
229
230
231 // add value and derivatives from other to this values and derivatives
232 OPM_HOST_DEVICE Evaluation& operator+=(const Evaluation& other)
233 {
234 assert(size() == other.size());
235
236 for (int i = 0; i < length_(); ++i)
237 data_[i] += other.data_[i];
238
239 return *this;
240 }
241
242 // add value from other to this values
243 template <class RhsValueType>
244 OPM_HOST_DEVICE Evaluation& operator+=(const RhsValueType& other)
245 {
246 // value is added, derivatives stay the same
247 data_[valuepos_()] += other;
248
249 return *this;
250 }
251
252 // subtract other's value and derivatives from this values
253 OPM_HOST_DEVICE Evaluation& operator-=(const Evaluation& other)
254 {
255 assert(size() == other.size());
256
257 for (int i = 0; i < length_(); ++i)
258 data_[i] -= other.data_[i];
259
260 return *this;
261 }
262
263 // subtract other's value from this values
264 template <class RhsValueType>
265 OPM_HOST_DEVICE Evaluation& operator-=(const RhsValueType& other)
266 {
267 // for constants, values are subtracted, derivatives stay the same
268 data_[valuepos_()] -= other;
269
270 return *this;
271 }
272
273 // multiply values and apply chain rule to derivatives: (u*v)' = (v'u + u'v)
274 OPM_HOST_DEVICE Evaluation& operator*=(const Evaluation& other)
275 {
276 assert(size() == other.size());
277
278 // while the values are multiplied, the derivatives follow the product rule,
279 // i.e., (u*v)' = (v'u + u'v).
280 const ValueType u = this->value();
281 const ValueType v = other.value();
282
283 // value
284 data_[valuepos_()] *= v ;
285
286 // derivatives
287 for (int i = dstart_(); i < dend_(); ++i)
288 data_[i] = data_[i] * v + other.data_[i] * u;
289
290 return *this;
291 }
292
293 // m(c*u)' = c*u'
294 template <class RhsValueType>
295 OPM_HOST_DEVICE Evaluation& operator*=(const RhsValueType& other)
296 {
297 for (int i = 0; i < length_(); ++i)
298 data_[i] *= other;
299
300 return *this;
301 }
302
303 // m(u*v)' = (vu' - uv')/v^2
304 OPM_HOST_DEVICE Evaluation& operator/=(const Evaluation& other)
305 {
306 assert(size() == other.size());
307
308 // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u -
309 // u'v)/v^2.
310 ValueType& u = data_[valuepos_()];
311 const ValueType& v = other.value();
312 for (int idx = dstart_(); idx < dend_(); ++idx) {
313 const ValueType& uPrime = data_[idx];
314 const ValueType& vPrime = other.data_[idx];
315
316 data_[idx] = (v*uPrime - u*vPrime)/(v*v);
317 }
318 u /= v;
319
320 return *this;
321 }
322
323 // divide value and derivatives by value of other
324 template <class RhsValueType>
325 OPM_HOST_DEVICE Evaluation& operator/=(const RhsValueType& other)
326 {
327 const ValueType tmp = 1.0/other;
328
329 for (int i = 0; i < length_(); ++i)
330 data_[i] *= tmp;
331
332 return *this;
333 }
334
335 // add two evaluation objects
336 OPM_HOST_DEVICE Evaluation operator+(const Evaluation& other) const
337 {
338 assert(size() == other.size());
339
340 Evaluation result(*this);
341
342 result += other;
343
344 return result;
345 }
346
347 // add constant to this object
348 template <class RhsValueType>
349 OPM_HOST_DEVICE Evaluation operator+(const RhsValueType& other) const
350 {
351 Evaluation result(*this);
352
353 result += other;
354
355 return result;
356 }
357
358 // subtract two evaluation objects
359 OPM_HOST_DEVICE Evaluation operator-(const Evaluation& other) const
360 {
361 assert(size() == other.size());
362
363 Evaluation result(*this);
364
365 result -= other;
366
367 return result;
368 }
369
370 // subtract constant from evaluation object
371 template <class RhsValueType>
372 OPM_HOST_DEVICE Evaluation operator-(const RhsValueType& other) const
373 {
374 Evaluation result(*this);
375
376 result -= other;
377
378 return result;
379 }
380
381 // negation (unary minus) operator
382 OPM_HOST_DEVICE Evaluation operator-() const
383 {
384 Evaluation result;
385
386 // set value and derivatives to negative
387 for (int i = 0; i < length_(); ++i)
388 result.data_[i] = - data_[i];
389
390 return result;
391 }
392
393 OPM_HOST_DEVICE Evaluation operator*(const Evaluation& other) const
394 {
395 assert(size() == other.size());
396
397 Evaluation result(*this);
398
399 result *= other;
400
401 return result;
402 }
403
404 template <class RhsValueType>
405 OPM_HOST_DEVICE Evaluation operator*(const RhsValueType& other) const
406 {
407 Evaluation result(*this);
408
409 result *= other;
410
411 return result;
412 }
413
414 OPM_HOST_DEVICE Evaluation operator/(const Evaluation& other) const
415 {
416 assert(size() == other.size());
417
418 Evaluation result(*this);
419
420 result /= other;
421
422 return result;
423 }
424
425 template <class RhsValueType>
426 OPM_HOST_DEVICE Evaluation operator/(const RhsValueType& other) const
427 {
428 Evaluation result(*this);
429
430 result /= other;
431
432 return result;
433 }
434
435 template <class RhsValueType>
436 OPM_HOST_DEVICE Evaluation& operator=(const RhsValueType& other)
437 {
438 setValue( other );
439 clearDerivatives();
440
441 return *this;
442 }
443
444 // copy assignment from evaluation
445 Evaluation& operator=(const Evaluation& other) = default;
446
447 template <class RhsValueType>
448 OPM_HOST_DEVICE bool operator==(const RhsValueType& other) const
449 { return value() == other; }
450
451 OPM_HOST_DEVICE bool operator==(const Evaluation& other) const
452 {
453 assert(size() == other.size());
454
455 for (int idx = 0; idx < length_(); ++idx) {
456 if (data_[idx] != other.data_[idx]) {
457 return false;
458 }
459 }
460 return true;
461 }
462
463 OPM_HOST_DEVICE bool operator!=(const Evaluation& other) const
464 { return !operator==(other); }
465
466 template <class RhsValueType>
467 OPM_HOST_DEVICE bool operator!=(const RhsValueType& other) const
468 { return !operator==(other); }
469
470 template <class RhsValueType>
471 OPM_HOST_DEVICE bool operator>(RhsValueType other) const
472 { return value() > other; }
473
474 OPM_HOST_DEVICE bool operator>(const Evaluation& other) const
475 {
476 assert(size() == other.size());
477
478 return value() > other.value();
479 }
480
481 template <class RhsValueType>
482 OPM_HOST_DEVICE bool operator<(RhsValueType other) const
483 { return value() < other; }
484
485 OPM_HOST_DEVICE bool operator<(const Evaluation& other) const
486 {
487 assert(size() == other.size());
488
489 return value() < other.value();
490 }
491
492 template <class RhsValueType>
493 OPM_HOST_DEVICE bool operator>=(RhsValueType other) const
494 { return value() >= other; }
495
496 OPM_HOST_DEVICE bool operator>=(const Evaluation& other) const
497 {
498 assert(size() == other.size());
499
500 return value() >= other.value();
501 }
502
503 template <class RhsValueType>
504 OPM_HOST_DEVICE bool operator<=(RhsValueType other) const
505 { return value() <= other; }
506
507 OPM_HOST_DEVICE bool operator<=(const Evaluation& other) const
508 {
509 assert(size() == other.size());
510
511 return value() <= other.value();
512 }
513
514 // return value of variable
515 OPM_HOST_DEVICE const ValueType& value() const
516 { return data_[valuepos_()]; }
517
518 // set value of variable
519 template <class RhsValueType>
520 OPM_HOST_DEVICE void setValue(const RhsValueType& val)
521 { data_[valuepos_()] = val; }
522
523 // return varIdx'th derivative
524 OPM_HOST_DEVICE const ValueType& derivative(int varIdx) const
525 {
526 assert(0 <= varIdx && varIdx < size());
527
528 return data_[dstart_() + varIdx];
529 }
530
531 // set derivative at position varIdx
532 OPM_HOST_DEVICE void setDerivative(int varIdx, const ValueType& derVal)
533 {
534 assert(0 <= varIdx && varIdx < size());
535
536 data_[dstart_() + varIdx] = derVal;
537 }
538
539 template<class Serializer>
540 OPM_HOST_DEVICE void serializeOp(Serializer& serializer)
541 {
542 serializer(data_);
543 }
544
545private:
546 std::array<ValueT, numDerivs + 1> data_;
547};
548
549// the generic operators are only required for the unspecialized case
550template <class RhsValueType, class ValueType, int numVars, unsigned staticSize>
551OPM_HOST_DEVICE bool operator<(const RhsValueType& a, const Evaluation<ValueType, numVars, staticSize>& b)
552{ return b > a; }
553
554template <class RhsValueType, class ValueType, int numVars, unsigned staticSize>
555OPM_HOST_DEVICE bool operator>(const RhsValueType& a, const Evaluation<ValueType, numVars, staticSize>& b)
556{ return b < a; }
557
558template <class RhsValueType, class ValueType, int numVars, unsigned staticSize>
559OPM_HOST_DEVICE bool operator<=(const RhsValueType& a, const Evaluation<ValueType, numVars, staticSize>& b)
560{ return b >= a; }
561
562template <class RhsValueType, class ValueType, int numVars, unsigned staticSize>
563OPM_HOST_DEVICE bool operator>=(const RhsValueType& a, const Evaluation<ValueType, numVars, staticSize>& b)
564{ return b <= a; }
565
566template <class RhsValueType, class ValueType, int numVars, unsigned staticSize>
567OPM_HOST_DEVICE bool operator!=(const RhsValueType& a, const Evaluation<ValueType, numVars, staticSize>& b)
568{ return a != b.value(); }
569
570template <class RhsValueType, class ValueType, int numVars, unsigned staticSize>
571OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> operator+(const RhsValueType& a, const Evaluation<ValueType, numVars, staticSize>& b)
572{
573 Evaluation<ValueType, numVars, staticSize> result(b);
574 result += a;
575 return result;
576}
577
578template <class RhsValueType, class ValueType, int numVars, unsigned staticSize>
579OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> operator-(const RhsValueType& a, const Evaluation<ValueType, numVars, staticSize>& b)
580{
581 return -(b - a);
582}
583
584template <class RhsValueType, class ValueType, int numVars, unsigned staticSize>
585OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> operator/(const RhsValueType& a, const Evaluation<ValueType, numVars, staticSize>& b)
586{
587 Evaluation<ValueType, numVars, staticSize> tmp(a);
588 tmp /= b;
589 return tmp;
590}
591
592template <class RhsValueType, class ValueType, int numVars, unsigned staticSize>
593OPM_HOST_DEVICE Evaluation<ValueType, numVars, staticSize> operator*(const RhsValueType& a, const Evaluation<ValueType, numVars, staticSize>& b)
594{
595 Evaluation<ValueType, numVars, staticSize> result(b);
596 result *= a;
597 return result;
598}
599
600template<class T>
602{
603 static constexpr bool value = false;
604};
605
606template <class ValueType, int numVars, unsigned staticSize>
607struct is_evaluation<Evaluation<ValueType,numVars,staticSize>>
608{
609 static constexpr bool value = true;
610};
611
612template <class ValueType, int numVars, unsigned staticSize>
613OPM_HOST_DEVICE void printEvaluation(std::ostream& os,
615 bool withDer = false);
616
617template <class ValueType, int numVars, unsigned staticSize>
618OPM_HOST_DEVICE std::ostream& operator<<(std::ostream& os, const Evaluation<ValueType, numVars, staticSize>& eval)
619{
621 printEvaluation(os, eval.value(), false);
622 else
623 printEvaluation(os, eval, true);
624
625 return os;
626}
627
628} // namespace DenseAd
629} // namespace Opm
630
632
633#endif // OPM_DENSEAD_EVALUATION_HPP
This file includes all specializations for the dense-AD Evaluation class.
Some templates to wrap the valgrind client request macros.
Represents a function evaluation and its derivatives w.r.t.
Definition Evaluation.hpp:59
ValueT ValueType
field type
Definition Evaluation.hpp:66
OPM_HOST_DEVICE constexpr int dstart_() const
start index for derivatives
Definition Evaluation.hpp:82
static const int numVars
the template argument which specifies the number of derivatives (-1 == "DynamicSize" means runtime de...
Definition Evaluation.hpp:63
OPM_HOST_DEVICE constexpr int length_() const
length of internal data vector
Definition Evaluation.hpp:74
OPM_HOST_DEVICE void checkDefined_() const
instruct valgrind to check that the value and all derivatives of the Evaluation object are well-defin...
Definition Evaluation.hpp:90
OPM_HOST_DEVICE Evaluation()
default constructor
Definition Evaluation.hpp:100
OPM_HOST_DEVICE constexpr int valuepos_() const
position index for value
Definition Evaluation.hpp:79
Evaluation(const Evaluation &other)=default
copy other function evaluation
OPM_HOST_DEVICE constexpr int size() const
number of derivatives
Definition Evaluation.hpp:69
OPM_HOST_DEVICE constexpr int dend_() const
end+1 index for derivatives
Definition Evaluation.hpp:85
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
Definition Evaluation.hpp:602