This commit switches to outputting all relative permeability values
less than TOLCRIT (default 1.0E-6) as zero when writing saturation
function tables to the INIT file's TAB vector. Doing so also
nominally affects the relative permeability function derivatives for
small values of Kr.
Update the SPE1-based unit test since this has very low Kr values
for water and some of the nodes now fall below the 1.0e-6 threshold.
This commit makes the table linearisation code independent of
LibECL's "ecl_kw_magic.h" header. In particular, we add a new set
of vector items (tabdims.hpp) that describe the items we currently
define and reimplement the member functions of the 'Tables' class in
terms of these items.
Update the unit test accordingly.
This commit removes the original member functions
void Tables::addPVTO()
void Tables::addPVTW()
void Tables::addPVTG()
since these are no longer needed. The PVT tables are now defined in
terms of the 'addPVTTables()' member function
While here, also remove the fwrite() free function which was defined
in terms of LibECL types.
Update the unit test accordingly.
This commit expands the private member function
Tables::addGasPVTTables(const EclipseState&)
to create structurally correct TAB vector entries from the PVTG
(wet gas) input table data when gas is an active phase in a
simulation run. Specifically, the main result array has the columns
[ Rv, 1/Bg, 1/(Bg*mu_g), d(1/Bg)/dRv, d(1/(Bg*mu_g))/dRv ]
and the ancillary table (base pointer JBPVTG) holds the gas pressure
nodes.
Note that while we do create structurally correct output tables, we
do not fill in undersaturated states that have been defaulted in the
input table.
The number of table rows in the main table is equal to number of PVT
regions times the number of declared pressure nodes (TABDIMS item 4,
NPPVT) times the number of declared composition nodes (TABDIMS item
6, NRPVT). In other words, the main result array is expanded to
fill NRPVT rows per gas pressure node per PVT region. Fill value
-2.0e+20. We have verified the results with ECLIPSE 100. The
ancillary table is expanded to the number of declared pressure nodes
for each PVT region. Here the fill value is +2.0e+20.
As an OPM extension, we will use the maximum number of active
composition and pressure nodes across all PVTG tables if the
declared maximum pressure nodes in TABDIMS is too small. This will
create TAB vector representations that are not compatible with
ECLIPSE, but which will nevertheless be useful in the context of
ResInsight's flux calculation.
Add unit tests for all gas-related PVT tables.
This commit expands the private member function
Tables::addOilPVTTables(const EclipseState&)
to create structurally correct TAB vector entries from the PVTO
(live oil) input table data when oil is an active phase in a
simulation run. Specifically, the main result array has the columns
[ Po, 1/Bo, 1/(Bo*mu_o), d(1/Bo)/dPo, d(1/(Bo*mu_o))/dPo ]
and the ancillary table (base pointer JBPVTO) holds the composition
nodes.
Note that while we do create structurally correct output tables, we
do not fill in undersaturated states that have been defaulted in the
input table.
The number of table rows in the main table is equal to number of PVT
regions times the number of declared composition nodes (TABDIMS item
6, NRPVT) times the number of declared pressure nodes (TABDIMS item
4, NPPVT). In other words, the main result array is expanded to
fill NPPVT rows per Rs node per PVT region. Fill value +2.0e+20.
We have verified the results with ECLIPSE 100. The ancillary table
is expanded to number of declared composition nodes for each PVT
region. Fill value +2.0e+20.
As an OPM extension, we will use the maximum number of active
pressure and composition nodes across all PVTO tables if the
declared maximum pressure nodes in TABDIMS is too small. This will
create a TAB vector representations that are not compatible with
ECLIPSE, but which will nevertheless be useful in the context of
ResInsight's flux calculation.
Add unit tests for all supported oil-related PVT tables.
This commit adds a new public member function
Tables::addPVTTables(const EclipseState&)
that calls into a new private member function
Tables::addWaterPVTTables(const EclipseState&)
to create structurally correct TAB vector entries from the PVTW
input table data when water is an active phase in a simulation run.
Specifically, the result array has the columns
[ Pw, 1/Bw, Cw, 1/(Bw * mu_w), Cw - Cv ]
in which 'Cw' denotes the water compressibility and 'Cv' denotes the
water viscosibility. Column 4 and 5 follow ECLIPSE 100 conventions.
Number of table rows equal to number of PVT regions. This result
array differs from the existing Tables::addPVTW() member function in
the treatment of viscosity and viscosibility data. We have verified
the results with ECLIPSE 100.
At present the function is not called by Flow's INIT file writer.
Add a unit test to exercise the new member function.
This commit extends the INIT file Table writing to also output the
saturation function tables in normalised form. We support
generating the INIT file's SGFN, SOFN, and SWFN tables--including
the derivative information--for both two and three phases from both
families of saturation function keywords (S{G,W}OF and S{G,W}FN +
SOF{2,3}). We do not yet support generating the appropriate tables
from input keyword SLGOF.
We leverage the LinearisedOutputTable to abstract away some of the
details of indexing into the linear 'tab' array and create a helper
function to loop across saturation function regions whence each
table generator need only be concerned about the specific data
pertaining to that region's saturation function (i.e., the values of
independent and dependent variates and number of active rows). We
allocate the output tables according to information in the TABDIMS
keyword, notably the number of saturation nodes (item 3 of TABDIMS).
Generating the three-phase SOFN table, which has the same columns as
the input table SOF3, in the case of family One (SGOF and SWOF) is
slightly involved. In particular we need to join the SGOF and SWOF
tables on common oil saturation values and derive/insert missing
KroX data through piecewise linear interpolation in the appropriate
input table. We defer the details of merging on common (and uniqe)
oil saturation values to the standard library routine 'set_union()'
which outputs repeated saturation values exactly once rather than
for each occurrence. That way we only need to wrap the input tables
in a simple class to facilitate look-up of oil saturation values and
the mechanics of piecewise linear interpolation of the relative
permeability column for oil. Due to this merging process, the
number of rows in SOFN is twice the number of saturation nodes in
this case.
Since this support depends on being able to determine which phases
are active in a particular run, what table sizes to use for the
output and which keywords are being used to represent the saturation
function tables we introduce a single new public member function
void Tables::addSatFunc(const EclipseState& es)
This function determines the run's active phases and dispatches to
the new helper functions
void Tables::addSatFunc_FamilyOne()
void Tables::addSatFunc_FamilyTwo()
according to which keyword family exists in the input deck. These
functions in turn call additional helper functions to handle each
phase table separately. For instance addSatFunc_FamilyOne() uses
the helper function
SatFunc::Oil::ThreePhase::fromSGOFandSWOF()
to generate a three-phase SOFN table based on the information in the
SGOF and SWOF tables.
Information about slopes/derivatives for the piecewise interpolants
of the dependent variates is computed through the helper function
DifferentiateOutputTable::calcSlopes()
whence the first entry of each derivative column is undefined (i.e.,
assigned the sentinel value 1e+20). This should arguably be zero
instead. Further testing and comparison with INIT result sets
generated by ECL will inform the decision here.
We add unit tests for all combinations of number of active phases
(two or three) and which saturation function keyword family is
present in the simulation case. The unit tests use the tables from
SPE 9 for keyword family One and the tables from SPE 1 for keyword
family Two. Comparison data is extracted directly from the ECL INIT
file in the case of the SPE 9 tables and derived from independent
calculation for the SPE 1 tables.
This commit switches the internal implementation of the 'tab' and
'tabdims' vectors from being a mix of ECL keyword structures and
std::vector<>s to being purely std::vector<>s. We remove the
fwrite() member function and rather reimplement the feature in terms
of new query member functions
const std::vector<int>& tabdims() const
const std::vector<double>& tab() const
that return read-only references to internal data members.