IMO this is pretty cool because it allows to transparantly calculate
higher order derivatives. for example this enables to implement the
linearization stage of higher-order non-linear solvers without much
additional effort compared to just evaluating the function in
question. (essentially, such higher order non-linear solvers are based
on truncating the Taylor series not after the first term -- like for the
Newton scheme -- but later. That said, they require to solve linear
systems of equations which involve tensors of orders greater than 2,
so they are not really practical as far as I can see.)
A more practical motivation for this is to allow the constraint
solvers to be used in "nested mode", i.e., linearizing the system of
equations they need to solve using automatic differentiation, but
allowing the value objects which are passed to the constraint solvers
be function evaluations themselves. (E.g. the result of a flash
calculation can also include the derivatives with regard to the
primary variables of the flow model. Note that the individual
constraint solvers need to some patches to make this work.)
this method is an artifact from the beginning of the automatic
differentiation code and is not needed anymore: its original pupose
was to be able to retain a full function evaluation object if it was
available or a function evaluation object representing a constant
function if only a primitive scalar is available. Nowadays, the method
can be replaced by a direct initialization:
template <class T, class V>
T fn(const V& v)
{ return T(v); }
is equivalent to
template <class T, class V>
T fn(const V& v)
{
typedef Opm::MathToolbox<T> Toolbox;
return passThroughOrCreateConstant(v);
}
In my recent experience it did more harm than good: tags often made
the compiler errors mucht longer and more unreadable, and I have not
encountered a single instance where they were really helpful...
so far, using function evaluation objects instead of primitive
floating point scalars only worked for trivial parameter caches which
do not store any values (most of the time, this means that the
ParameterCache is `NullParameterCache`), or it explicitly did not work
(like for `Spe5ParameterCache`). this patch fixes the problem by
making the parameter caches of fluid systems template classes which
are templated on the type of scalar values. On the flipside, this
requires changes to all downstream modules that use fluid systems.
this patch removes the in-file lists in favor of a global list of in
the COPYING file. this is done because (a) maintaining a list of
authors at the beginning of each source file is a major pain in the
a**, (b) for this reason, the list of authors was not accurate in
about 85% of all cases where more than one person was involved and (c)
this list is not legally binding in any way (the copyright is at the
person who authored a given change; if these lists had any legal
relevance, one could "aquire" the copyright of the module by forking
it and replacing the lists...)
in my testing, the GCC SVN version from 4th of March causes problems
if lvalue references are just passed through and neither GCC-5 nor
clang 3.6 show any obvious differences in performance. (I guess that's
because of the copy elision compiler optimizations in conjunction with
inlining.)
It is also worthwhile to know that clang 3.6 is about 20% faster with
ebos than both, GCC-6 and GCC-5. I can only speculate why this is the
case, but since the performance improvement seems to evenly apply to
the linearization and linear-solve parts, the auto-vectorizer of clang
possibly works better for ebos than the one of GCC...
opm-parser#677 changes the return types for the Deck family of classes.
This patch fixes all broken code from that patch set.
https://github.com/OPM/opm-parser/pull/677
if the base fluid state returns a reference, the overlay fluid state
should just pass it through instead if copying it. The difference
became relevant with the introduction of Evaluations for localized
AD. (is not relevant if Scalars are floating point values, which was
the only choice when the overlay fluid states were written.)
the problem is that references to lvalues can be just passed through,
whilst the objects the rvalue references point are temporary and thus
need need to be copied. Fixing this issue forced me to go into the
rabbit hole of the c++ memory model, but at least I guess I now know
what rvalue references ('Foo&&' instead of 'Foo&') are good for...