My Project
Loading...
Searching...
No Matches
Evaluation4.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*/
31#ifndef OPM_DENSEAD_EVALUATION4_HPP
32#define OPM_DENSEAD_EVALUATION4_HPP
33
34#ifndef NDEBUG
36#endif
37
38#include <array>
39#include <cassert>
40#include <iosfwd>
41#include <stdexcept>
42
43namespace Opm {
44namespace DenseAd {
45
46template <class ValueT>
47class Evaluation<ValueT, 4>
48{
49public:
52 static const int numVars = 4;
53
55 typedef ValueT ValueType;
56
58 constexpr int size() const
59 { return 4; };
60
61protected:
63 constexpr int length_() const
64 { return size() + 1; }
65
66
68 constexpr int valuepos_() const
69 { return 0; }
71 constexpr int dstart_() const
72 { return 1; }
74 constexpr int dend_() const
75 { return length_(); }
76
79 void checkDefined_() const
80 {
81#ifndef NDEBUG
82 for (const auto& v: data_)
83 Valgrind::CheckDefined(v);
84#endif
85 }
86
87public:
89 Evaluation() : data_()
90 {}
91
93 Evaluation(const Evaluation& other) = default;
94
95
96 // create an evaluation which represents a constant function
97 //
98 // i.e., f(x) = c. this implies an evaluation with the given value and all
99 // derivatives being zero.
100 template <class RhsValueType>
101 Evaluation(const RhsValueType& c)
102 {
103 setValue(c);
104 clearDerivatives();
105
107 }
108
109 // create an evaluation which represents a constant function
110 //
111 // i.e., f(x) = c. this implies an evaluation with the given value and all
112 // derivatives being zero.
113 template <class RhsValueType>
114 Evaluation(const RhsValueType& c, int varPos)
115 {
116 // The variable position must be in represented by the given variable descriptor
117 assert(0 <= varPos && varPos < size());
118
119 setValue( c );
120 clearDerivatives();
121
122 data_[varPos + dstart_()] = 1.0;
123
125 }
126
127 // set all derivatives to zero
128 void clearDerivatives()
129 {
130 data_[1] = 0.0;
131 data_[2] = 0.0;
132 data_[3] = 0.0;
133 data_[4] = 0.0;
134 }
135
136 // create an uninitialized Evaluation object that is compatible with the
137 // argument, but not initialized
138 //
139 // This basically boils down to the copy constructor without copying
140 // anything. If the number of derivatives is known at compile time, this
141 // is equivalent to creating an uninitialized object using the default
142 // constructor, while for dynamic evaluations, it creates an Evaluation
143 // object which exhibits the same number of derivatives as the argument.
144 static Evaluation createBlank(const Evaluation&)
145 { return Evaluation(); }
146
147 // create an Evaluation with value and all the derivatives to be zero
148 static Evaluation createConstantZero(const Evaluation&)
149 { return Evaluation(0.); }
150
151 // create an Evaluation with value to be one and all the derivatives to be zero
152 static Evaluation createConstantOne(const Evaluation&)
153 { return Evaluation(1.); }
154
155 // create a function evaluation for a "naked" depending variable (i.e., f(x) = x)
156 template <class RhsValueType>
157 static Evaluation createVariable(const RhsValueType& value, int varPos)
158 {
159 // copy function value and set all derivatives to 0, except for the variable
160 // which is represented by the value (which is set to 1.0)
161 return Evaluation(value, varPos);
162 }
163
164 template <class RhsValueType>
165 static Evaluation createVariable(int nVars, const RhsValueType& value, int varPos)
166 {
167 if (nVars != 4)
168 throw std::logic_error("This statically-sized evaluation can only represent objects"
169 " with 4 derivatives");
170
171 // copy function value and set all derivatives to 0, except for the variable
172 // which is represented by the value (which is set to 1.0)
173 return Evaluation(nVars, value, varPos);
174 }
175
176 template <class RhsValueType>
177 static Evaluation createVariable(const Evaluation&, const RhsValueType& value, int varPos)
178 {
179 // copy function value and set all derivatives to 0, except for the variable
180 // which is represented by the value (which is set to 1.0)
181 return Evaluation(value, varPos);
182 }
183
184
185 // "evaluate" a constant function (i.e. a function that does not depend on the set of
186 // relevant variables, f(x) = c).
187 template <class RhsValueType>
188 static Evaluation createConstant(int nVars, const RhsValueType& value)
189 {
190 if (nVars != 4)
191 throw std::logic_error("This statically-sized evaluation can only represent objects"
192 " with 4 derivatives");
193 return Evaluation(value);
194 }
195
196 // "evaluate" a constant function (i.e. a function that does not depend on the set of
197 // relevant variables, f(x) = c).
198 template <class RhsValueType>
199 static Evaluation createConstant(const RhsValueType& value)
200 {
201 return Evaluation(value);
202 }
203
204 // "evaluate" a constant function (i.e. a function that does not depend on the set of
205 // relevant variables, f(x) = c).
206 template <class RhsValueType>
207 static Evaluation createConstant(const Evaluation&, const RhsValueType& value)
208 {
209 return Evaluation(value);
210 }
211
212 // copy all derivatives from other
213 void copyDerivatives(const Evaluation& other)
214 {
215 assert(size() == other.size());
216
217 data_[1] = other.data_[1];
218 data_[2] = other.data_[2];
219 data_[3] = other.data_[3];
220 data_[4] = other.data_[4];
221 }
222
223
224 // add value and derivatives from other to this values and derivatives
225 Evaluation& operator+=(const Evaluation& other)
226 {
227 assert(size() == other.size());
228
229 data_[0] += other.data_[0];
230 data_[1] += other.data_[1];
231 data_[2] += other.data_[2];
232 data_[3] += other.data_[3];
233 data_[4] += other.data_[4];
234
235 return *this;
236 }
237
238 // add value from other to this values
239 template <class RhsValueType>
240 Evaluation& operator+=(const RhsValueType& other)
241 {
242 // value is added, derivatives stay the same
243 data_[valuepos_()] += other;
244
245 return *this;
246 }
247
248 // subtract other's value and derivatives from this values
249 Evaluation& operator-=(const Evaluation& other)
250 {
251 assert(size() == other.size());
252
253 data_[0] -= other.data_[0];
254 data_[1] -= other.data_[1];
255 data_[2] -= other.data_[2];
256 data_[3] -= other.data_[3];
257 data_[4] -= other.data_[4];
258
259 return *this;
260 }
261
262 // subtract other's value from this values
263 template <class RhsValueType>
264 Evaluation& operator-=(const RhsValueType& other)
265 {
266 // for constants, values are subtracted, derivatives stay the same
267 data_[valuepos_()] -= other;
268
269 return *this;
270 }
271
272 // multiply values and apply chain rule to derivatives: (u*v)' = (v'u + u'v)
273 Evaluation& operator*=(const Evaluation& other)
274 {
275 assert(size() == other.size());
276
277 // while the values are multiplied, the derivatives follow the product rule,
278 // i.e., (u*v)' = (v'u + u'v).
279 const ValueType u = this->value();
280 const ValueType v = other.value();
281
282 // value
283 data_[valuepos_()] *= v ;
284
285 // derivatives
286 data_[1] = data_[1] * v + other.data_[1] * u;
287 data_[2] = data_[2] * v + other.data_[2] * u;
288 data_[3] = data_[3] * v + other.data_[3] * u;
289 data_[4] = data_[4] * v + other.data_[4] * u;
290
291 return *this;
292 }
293
294 // m(c*u)' = c*u'
295 template <class RhsValueType>
296 Evaluation& operator*=(const RhsValueType& other)
297 {
298 data_[0] *= other;
299 data_[1] *= other;
300 data_[2] *= other;
301 data_[3] *= other;
302 data_[4] *= other;
303
304 return *this;
305 }
306
307 // m(u*v)' = (vu' - uv')/v^2
308 Evaluation& operator/=(const Evaluation& other)
309 {
310 assert(size() == other.size());
311
312 // values are divided, derivatives follow the rule for division, i.e., (u/v)' = (v'u -
313 // u'v)/v^2.
314 ValueType& u = data_[valuepos_()];
315 const ValueType& v = other.value();
316 data_[1] = (v*data_[1] - u*other.data_[1])/(v*v);
317 data_[2] = (v*data_[2] - u*other.data_[2])/(v*v);
318 data_[3] = (v*data_[3] - u*other.data_[3])/(v*v);
319 data_[4] = (v*data_[4] - u*other.data_[4])/(v*v);
320 u /= v;
321
322 return *this;
323 }
324
325 // divide value and derivatives by value of other
326 template <class RhsValueType>
327 Evaluation& operator/=(const RhsValueType& other)
328 {
329 const ValueType tmp = 1.0/other;
330
331 data_[0] *= tmp;
332 data_[1] *= tmp;
333 data_[2] *= tmp;
334 data_[3] *= tmp;
335 data_[4] *= tmp;
336
337 return *this;
338 }
339
340 // add two evaluation objects
341 Evaluation operator+(const Evaluation& other) const
342 {
343 assert(size() == other.size());
344
345 Evaluation result(*this);
346
347 result += other;
348
349 return result;
350 }
351
352 // add constant to this object
353 template <class RhsValueType>
354 Evaluation operator+(const RhsValueType& other) const
355 {
356 Evaluation result(*this);
357
358 result += other;
359
360 return result;
361 }
362
363 // subtract two evaluation objects
364 Evaluation operator-(const Evaluation& other) const
365 {
366 assert(size() == other.size());
367
368 Evaluation result(*this);
369
370 result -= other;
371
372 return result;
373 }
374
375 // subtract constant from evaluation object
376 template <class RhsValueType>
377 Evaluation operator-(const RhsValueType& other) const
378 {
379 Evaluation result(*this);
380
381 result -= other;
382
383 return result;
384 }
385
386 // negation (unary minus) operator
387 Evaluation operator-() const
388 {
389 Evaluation result;
390
391 // set value and derivatives to negative
392 result.data_[0] = - data_[0];
393 result.data_[1] = - data_[1];
394 result.data_[2] = - data_[2];
395 result.data_[3] = - data_[3];
396 result.data_[4] = - data_[4];
397
398 return result;
399 }
400
401 Evaluation operator*(const Evaluation& other) const
402 {
403 assert(size() == other.size());
404
405 Evaluation result(*this);
406
407 result *= other;
408
409 return result;
410 }
411
412 template <class RhsValueType>
413 Evaluation operator*(const RhsValueType& other) const
414 {
415 Evaluation result(*this);
416
417 result *= other;
418
419 return result;
420 }
421
422 Evaluation operator/(const Evaluation& other) const
423 {
424 assert(size() == other.size());
425
426 Evaluation result(*this);
427
428 result /= other;
429
430 return result;
431 }
432
433 template <class RhsValueType>
434 Evaluation operator/(const RhsValueType& other) const
435 {
436 Evaluation result(*this);
437
438 result /= other;
439
440 return result;
441 }
442
443 template <class RhsValueType>
444 Evaluation& operator=(const RhsValueType& other)
445 {
446 setValue( other );
447 clearDerivatives();
448
449 return *this;
450 }
451
452 // copy assignment from evaluation
453 Evaluation& operator=(const Evaluation& other) = default;
454
455 template <class RhsValueType>
456 bool operator==(const RhsValueType& other) const
457 { return value() == other; }
458
459 bool operator==(const Evaluation& other) const
460 {
461 assert(size() == other.size());
462
463 for (int idx = 0; idx < length_(); ++idx) {
464 if (data_[idx] != other.data_[idx]) {
465 return false;
466 }
467 }
468 return true;
469 }
470
471 bool operator!=(const Evaluation& other) const
472 { return !operator==(other); }
473
474 template <class RhsValueType>
475 bool operator!=(const RhsValueType& other) const
476 { return !operator==(other); }
477
478 template <class RhsValueType>
479 bool operator>(RhsValueType other) const
480 { return value() > other; }
481
482 bool operator>(const Evaluation& other) const
483 {
484 assert(size() == other.size());
485
486 return value() > other.value();
487 }
488
489 template <class RhsValueType>
490 bool operator<(RhsValueType other) const
491 { return value() < other; }
492
493 bool operator<(const Evaluation& other) const
494 {
495 assert(size() == other.size());
496
497 return value() < other.value();
498 }
499
500 template <class RhsValueType>
501 bool operator>=(RhsValueType other) const
502 { return value() >= other; }
503
504 bool operator>=(const Evaluation& other) const
505 {
506 assert(size() == other.size());
507
508 return value() >= other.value();
509 }
510
511 template <class RhsValueType>
512 bool operator<=(RhsValueType other) const
513 { return value() <= other; }
514
515 bool operator<=(const Evaluation& other) const
516 {
517 assert(size() == other.size());
518
519 return value() <= other.value();
520 }
521
522 // return value of variable
523 const ValueType& value() const
524 { return data_[valuepos_()]; }
525
526 // set value of variable
527 template <class RhsValueType>
528 void setValue(const RhsValueType& val)
529 { data_[valuepos_()] = val; }
530
531 // return varIdx'th derivative
532 const ValueType& derivative(int varIdx) const
533 {
534 assert(0 <= varIdx && varIdx < size());
535
536 return data_[dstart_() + varIdx];
537 }
538
539 // set derivative at position varIdx
540 void setDerivative(int varIdx, const ValueType& derVal)
541 {
542 assert(0 <= varIdx && varIdx < size());
543
544 data_[dstart_() + varIdx] = derVal;
545 }
546
547 template<class Serializer>
548 void serializeOp(Serializer& serializer)
549 {
550 serializer(data_);
551 }
552
553private:
554 std::array<ValueT, 5> data_;
555};
556
557} // namespace DenseAd
558} // namespace Opm
559
560#endif // OPM_DENSEAD_EVALUATION4_HPP
Some templates to wrap the valgrind client request macros.
constexpr int dstart_() const
start index for derivatives
Definition Evaluation4.hpp:71
ValueT ValueType
field type
Definition Evaluation4.hpp:55
Evaluation(const Evaluation &other)=default
copy other function evaluation
constexpr int valuepos_() const
position index for value
Definition Evaluation4.hpp:68
constexpr int dend_() const
end+1 index for derivatives
Definition Evaluation4.hpp:74
constexpr int size() const
number of derivatives
Definition Evaluation4.hpp:58
void checkDefined_() const
instruct valgrind to check that the value and all derivatives of the Evaluation object are well-defin...
Definition Evaluation4.hpp:79
Evaluation()
default constructor
Definition Evaluation4.hpp:89
constexpr int length_() const
length of internal data vector
Definition Evaluation4.hpp:63
Represents a function evaluation and its derivatives w.r.t.
Definition Evaluation.hpp:57
Evaluation()
default constructor
Definition Evaluation.hpp:98
ValueT ValueType
field type
Definition Evaluation.hpp:64
void checkDefined_() const
instruct valgrind to check that the value and all derivatives of the Evaluation object are well-defin...
Definition Evaluation.hpp:88
static const int numVars
the template argument which specifies the number of derivatives (-1 == "DynamicSize" means runtime de...
Definition Evaluation.hpp:61
constexpr int size() const
number of derivatives
Definition Evaluation.hpp:67
constexpr int valuepos_() const
position index for value
Definition Evaluation.hpp:77
constexpr int length_() const
length of internal data vector
Definition Evaluation.hpp:72
constexpr int dstart_() const
start index for derivatives
Definition Evaluation.hpp:80
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30