since the undersaturated PVT relations may use bi-linear 2D
interpolation but the saturated ones always use linear 1D
interpolation, not having this leads to a discontinuity. that
discontinuity turns out to be very bad news if the partial derivatives
are calculated using finite differences. On the other hand, the
untersaturated PVT relations cannot be used unconditionally (this
would be the clean solution, IMO) because this causes the results to
deflect from those produced by ECL. The hack to make DR[SV]DT work is
to only use the saturated PVT quantities if the R value is
sufficiently large. (This may lead to issues in the future because
there now is a discontinuity w.r.t. R, but let's burn that bridge when
we come to it.)
in the oil case the previous condition that the saturation of the gas
phase is non-zero is cheaper to evaluate, but it does not work when
the maximum Rs value at which the gas phase starts to appear is lower
than the Rs value of the saturated gas. In particular this happens for
the DRSDT keyword.
note that the best solution would be to eliminate these case
distinctions alltogether, but this does not work because ECL does not
seem to use bi-linear interpolation if the pressure gets larger than
the maximum pressure specified by the PVT table. (it only seems to use
the pressure to extrapolate linearly.)
this causes problems with things like DRSDT where
"isSaturated(oilPhasIdx)" is not necessarily related to the presence
of the gas phase. (analogous for DRVDT.)
The impact of performance seems to be negligible:
```
Total time (seconds): 550.185
Solver time (seconds): 534.769
Assembly time (seconds): 251.509 (Failed: 4.51604; 1.79558%)
Linear solve time (seconds): 263.03 (Failed: 5.78332; 2.19873%)
Update time (seconds): 11.0526 (Failed: 0.220144; 1.99177%)
Output write time (seconds): 18.1411
Overall Well Iterations: 902 (Failed: 7; 0.776053%)
Overall Linearizations: 1890 (Failed: 33; 1.74603%)
Overall Newton Iterations: 1553 (Failed: 33; 2.12492%)
Overall Linear Iterations: 23525 (Failed: 511; 2.17216%)
```
before and
```
Total time (seconds): 556.463
Solver time (seconds): 541.06
Assembly time (seconds): 253.165 (Failed: 4.42903; 1.74946%)
Linear solve time (seconds): 267.343 (Failed: 4.52042; 1.69087%)
Update time (seconds): 11.334 (Failed: 0.214721; 1.89449%)
Output write time (seconds): 18.0694
Overall Well Iterations: 903 (Failed: 8; 0.885936%)
Overall Linearizations: 1909 (Failed: 33; 1.72865%)
Overall Newton Iterations: 1572 (Failed: 33; 2.09924%)
Overall Linear Iterations: 23866 (Failed: 391; 1.63831%)
```
after this patch, i.e., on my machine the runtime for Norne went from
550 to 556 seconds due to slightly larger number of non-linear and
linear iterations. Note that this also happens if the 1e-4 threshold
value is changed instead of the case distinction being removed. (This
hints on the into the direction that the performance difference is
just numerical noise.)
this flag is way too non-descript (a complex relation for one person
may be a simple one for another), the implementation is pretty
inconsistent and it makes the code more complicated and harder to
maintain. Thus, IMO the approach turned out to be a bummer, so let's
pull the plug.
I missed the fact that in the enthalpy() function, the polynomial
coefficients are divided, i.e., this component defines a polynomial
for the heat capacity and integrates it for the enthalpy. (not
the other way around.)
I looked at all components: For the ones that use simple enthalpy
relations, heatCapacity() and enthalpy() should now be
consistent. (Here "simple" means "an approach that I understood without
reading literature for several hours".)
a reduction of Rs and Rv of a factor 1000 should be enough physically
and the numerical stability is quite a bit better with this. In
particular, this is should not really matter because the whole concept
of VAPPARS is a staggeringly ugly hack from the outset.
std::exception is a polymorphic type and catching these by values
generates warnings when using the latest GCC from SVN. Besides this,
catching objects by value is bad style and was unintended from the
start.
In fact, the temperature at the reservoir is not constant, so this
should be more thought of as "representative temperature" of the
reservoir.
In ECL, this value is specified using the RTEMP or the RTEMPA
keywords, opm-parser provides this via the table manager. (NB: is this
really something that belongs there?)
the problem is that some of these function names clash with those for
code using AutoDiffBlock. This is normally not a problem because of
the SFINAE rule, but the static assertation makes the compiler bail
out before SFINAE kicks in.
IMO this is a little unfortunate because without this static_assert
compiler errors are bound to becomming quite a bit more obscure, but
as long there is code which uses both AD approaches at the same time,
I cannot see a way to keep the assert without moving one approach or
the other to a different namespace (or renaming the math function for
one).
this patch converts to code to use the convenience functions instead
of the math toolboxes whereever possible. the main advantage is that
Opm::foo(x) will work regardless of the type of `x`, but it also
reduces visual clutter.
also, constant Evaluations are now directly created by assigning
Scalars, which removes further visual noise.
while I hope it improves the readability of the code,
functionality-wise this patch should not change anything.