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