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