2016-11-16 09:12:59 -06:00
|
|
|
/*
|
|
|
|
Copyright 2016 Statoil ASA.
|
|
|
|
|
|
|
|
This file is part of the Open Porous Media project (OPM).
|
|
|
|
|
|
|
|
OPM is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
OPM is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
INIT File: Add Support for Writing Saturation Function Tables
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.
2017-11-16 09:34:05 -06:00
|
|
|
#define BOOST_TEST_MODULE Tabular_INIT_Output
|
2016-11-16 09:12:59 -06:00
|
|
|
#include <boost/test/unit_test.hpp>
|
INIT File: Add Support for Writing Saturation Function Tables
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.
2017-11-16 09:34:05 -06:00
|
|
|
|
|
|
|
#include <opm/output/eclipse/Tables.hpp>
|
|
|
|
|
2016-11-16 09:12:59 -06:00
|
|
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
|
|
|
|
INIT File: Add Support for Writing Saturation Function Tables
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.
2017-11-16 09:34:05 -06:00
|
|
|
#include <cstddef>
|
|
|
|
#include <exception>
|
2016-11-16 09:12:59 -06:00
|
|
|
#include <fstream>
|
INIT File: Add Support for Writing Saturation Function Tables
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.
2017-11-16 09:34:05 -06:00
|
|
|
#include <initializer_list>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <vector>
|
2016-11-16 09:12:59 -06:00
|
|
|
|
|
|
|
#include <ert/ecl/ecl_kw_magic.h>
|
|
|
|
#include <ert/ecl/ecl_sum.h>
|
|
|
|
#include <ert/ecl/ecl_file.h>
|
|
|
|
#include <ert/util/util.h>
|
2018-09-13 10:25:33 -05:00
|
|
|
#include <ert/util/test_work_area.h>
|
2016-11-16 09:12:59 -06:00
|
|
|
|
|
|
|
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
|
|
|
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
|
|
|
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
|
|
|
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
|
|
|
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
|
|
|
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
|
|
|
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
|
|
|
|
|
|
|
using namespace Opm;
|
|
|
|
|
|
|
|
|
|
|
|
struct setup {
|
|
|
|
Deck deck;
|
|
|
|
EclipseState es;
|
2018-09-13 10:25:33 -05:00
|
|
|
test_work_area_type * ta;
|
2016-11-16 09:12:59 -06:00
|
|
|
|
2016-12-29 06:51:07 -06:00
|
|
|
setup( const std::string& path , const ParseContext& parseContext = ParseContext( )) :
|
2016-11-16 09:12:59 -06:00
|
|
|
deck( Parser().parseFile( path, parseContext ) ),
|
|
|
|
es( deck, ParseContext() ),
|
2018-09-13 10:25:33 -05:00
|
|
|
ta( test_work_area_alloc( "test_tables"))
|
2016-11-16 09:12:59 -06:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-09-13 10:25:33 -05:00
|
|
|
~setup() {
|
|
|
|
test_work_area_free(this->ta);
|
|
|
|
}
|
|
|
|
|
2016-11-16 09:12:59 -06:00
|
|
|
};
|
|
|
|
|
INIT File: Add Support for Writing Saturation Function Tables
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.
2017-11-16 09:34:05 -06:00
|
|
|
namespace {
|
|
|
|
template <class Collection1, class Collection2>
|
|
|
|
void check_is_close(const Collection1& c1, const Collection2& c2)
|
|
|
|
{
|
|
|
|
BOOST_REQUIRE_EQUAL(c1.size(), c2.size());
|
|
|
|
|
|
|
|
if (! c1.empty()) {
|
|
|
|
auto i1 = c1.begin(), e1 = c1.end();
|
|
|
|
auto i2 = c2.begin();
|
|
|
|
|
|
|
|
for (; i1 != e1; ++i1, ++i2) {
|
|
|
|
BOOST_CHECK_CLOSE(*i1, *i2, 1.0e-10);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double>
|
|
|
|
makeTable(const std::size_t ncol,
|
|
|
|
std::initializer_list<double> data)
|
|
|
|
{
|
|
|
|
auto result = std::vector<double>(data.size(), 0.0);
|
|
|
|
const auto nrows = data.size() / ncol;
|
|
|
|
|
|
|
|
auto di = std::begin(data);
|
|
|
|
for (auto i = 0*nrows; i < nrows; ++i) {
|
|
|
|
for (auto j = 0*ncol; j < ncol; ++j, ++di) {
|
|
|
|
result[i + j*nrows] = *di;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace SPE1 { // Family II (SGFN, SOF{2,3}, SWFN)
|
|
|
|
namespace TwoPhase {
|
|
|
|
namespace GasOil {
|
|
|
|
Opm::EclipseState satfuncTables()
|
|
|
|
{
|
|
|
|
const auto* input = R"(
|
|
|
|
RUNSPEC
|
|
|
|
OIL
|
|
|
|
GAS
|
|
|
|
|
|
|
|
METRIC
|
|
|
|
|
|
|
|
DIMENS
|
|
|
|
1 1 1 /
|
|
|
|
|
|
|
|
TABDIMS
|
|
|
|
/
|
|
|
|
|
|
|
|
-- =======================================
|
|
|
|
GRID
|
|
|
|
|
|
|
|
DXV
|
|
|
|
1 /
|
|
|
|
|
|
|
|
DYV
|
|
|
|
1 /
|
|
|
|
|
|
|
|
DZV
|
|
|
|
0.1 /
|
|
|
|
|
|
|
|
DEPTHZ
|
|
|
|
4*2000.0 /
|
|
|
|
|
|
|
|
PERMX
|
|
|
|
100.0 /
|
|
|
|
|
|
|
|
COPY
|
|
|
|
'PERMX' 'PERMY' /
|
|
|
|
'PERMX' 'PERMZ' /
|
|
|
|
/
|
|
|
|
|
|
|
|
MULTIPLY
|
|
|
|
'PERMZ' 0.1 /
|
|
|
|
/
|
|
|
|
|
|
|
|
PORO
|
|
|
|
0.3 /
|
|
|
|
|
|
|
|
-- =======================================
|
|
|
|
PROPS
|
|
|
|
|
|
|
|
SGFN
|
|
|
|
-- SPE 1 Table
|
|
|
|
0 0 0
|
|
|
|
0.001 0 0
|
|
|
|
0.02 0 0
|
|
|
|
0.05 0.005 0
|
|
|
|
0.12 0.025 0
|
|
|
|
0.2 0.075 0
|
|
|
|
0.25 0.125 0
|
|
|
|
0.3 0.190 0
|
|
|
|
0.4 0.410 0
|
|
|
|
0.45 0.60 0
|
|
|
|
0.5 0.72 0
|
|
|
|
0.6 0.87 0
|
|
|
|
0.7 0.94 0
|
|
|
|
0.85 0.98 0
|
|
|
|
0.88 0.984 0 /
|
|
|
|
|
|
|
|
SOF2
|
|
|
|
-- SPE 1 Table
|
|
|
|
0 0
|
|
|
|
0.03 0
|
|
|
|
0.18 0
|
|
|
|
0.28 0.0001
|
|
|
|
0.38 0.001
|
|
|
|
0.43 0.01
|
|
|
|
0.48 0.021
|
|
|
|
0.58 0.09
|
|
|
|
0.63 0.2
|
|
|
|
0.68 0.35
|
|
|
|
0.76 0.7
|
|
|
|
0.83 0.98
|
|
|
|
0.86 0.997
|
|
|
|
0.879 1
|
|
|
|
0.88 1 /
|
|
|
|
|
|
|
|
DENSITY
|
|
|
|
853.0 1014.0 0.75 /
|
|
|
|
|
|
|
|
END
|
|
|
|
)";
|
|
|
|
|
|
|
|
const auto deck = Opm::Deck{
|
|
|
|
Opm::Parser{}.parseString(input, Opm::ParseContext{})
|
|
|
|
};
|
|
|
|
|
|
|
|
return {deck, Opm::ParseContext{}};
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SGFN()
|
|
|
|
{
|
|
|
|
return makeTable(5, {
|
|
|
|
0, 0, 0, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e-03, 0, 0, 0, 0,
|
|
|
|
2.00e-02, 0, 0, 0, 0,
|
|
|
|
5.00e-02, 5.000000000000000e-03, 0, 1.666666666666667e-01, 0,
|
|
|
|
1.20e-01, 2.500000000000000e-02, 0, 2.857142857142858e-01, 0,
|
|
|
|
2.00e-01, 7.500000000000000e-02, 0, 6.249999999999998e-01, 0,
|
|
|
|
2.50e-01, 1.250000000000000e-01, 0, 1.000000000000000e+00, 0,
|
|
|
|
3.00e-01, 1.900000000000000e-01, 0, 1.300000000000000e+00, 0,
|
|
|
|
4.00e-01, 4.100000000000000e-01, 0, 2.199999999999999e+00, 0,
|
|
|
|
4.50e-01, 6.000000000000000e-01, 0, 3.800000000000001e+00, 0,
|
|
|
|
5.00e-01, 7.200000000000000e-01, 0, 2.400000000000000e+00, 0,
|
|
|
|
6.00e-01, 8.700000000000000e-01, 0, 1.500000000000001e+00, 0,
|
|
|
|
7.00e-01, 9.399999999999999e-01, 0, 6.999999999999996e-01, 0,
|
|
|
|
8.50e-01, 9.800000000000000e-01, 0, 2.666666666666669e-01, 0,
|
|
|
|
8.80e-01, 9.840000000000000e-01, 0, 1.333333333333333e-01, 0,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SOFN()
|
|
|
|
{
|
|
|
|
return makeTable(3, {
|
|
|
|
0, 0, 1.000000000000000e+20,
|
|
|
|
3.00e-02, 0, 0,
|
|
|
|
1.80e-01, 0, 0,
|
|
|
|
2.80e-01, 1.00e-04, 9.999999999999998e-04,
|
|
|
|
3.80e-01, 1.00e-03, 9.000000000000001e-03,
|
|
|
|
4.30e-01, 1.00e-02, 1.800000000000000e-01,
|
|
|
|
4.80e-01, 2.10e-02, 2.200000000000001e-01,
|
|
|
|
5.80e-01, 9.00e-02, 6.900000000000001e-01,
|
|
|
|
6.30e-01, 2.00e-01, 2.199999999999998e+00,
|
|
|
|
6.80e-01, 3.50e-01, 2.999999999999997e+00,
|
|
|
|
7.60e-01, 7.00e-01, 4.375000000000002e+00,
|
|
|
|
8.30e-01, 9.80e-01, 4.000000000000004e+00,
|
|
|
|
8.60e-01, 9.97e-01, 5.666666666666667e-01,
|
|
|
|
8.79e-01, 1.00e+00, 1.578947368421053e-01,
|
|
|
|
8.80e-01, 1.00e+00, 0,
|
|
|
|
1.00e+20, 1.00e+20, 1.000000000000000e+20,
|
|
|
|
1.00e+20, 1.00e+20, 1.000000000000000e+20,
|
|
|
|
1.00e+20, 1.00e+20, 1.000000000000000e+20,
|
|
|
|
1.00e+20, 1.00e+20, 1.000000000000000e+20,
|
|
|
|
1.00e+20, 1.00e+20, 1.000000000000000e+20,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} // GasOil
|
|
|
|
|
|
|
|
namespace OilWater {
|
|
|
|
Opm::EclipseState satfuncTables()
|
|
|
|
{
|
|
|
|
const auto* input = R"(
|
|
|
|
RUNSPEC
|
|
|
|
WATER
|
|
|
|
OIL
|
|
|
|
|
|
|
|
METRIC
|
|
|
|
|
|
|
|
DIMENS
|
|
|
|
1 1 1 /
|
|
|
|
|
|
|
|
TABDIMS
|
|
|
|
/
|
|
|
|
|
|
|
|
-- =======================================
|
|
|
|
GRID
|
|
|
|
|
|
|
|
DXV
|
|
|
|
1 /
|
|
|
|
|
|
|
|
DYV
|
|
|
|
1 /
|
|
|
|
|
|
|
|
DZV
|
|
|
|
0.1 /
|
|
|
|
|
|
|
|
DEPTHZ
|
|
|
|
4*2000.0 /
|
|
|
|
|
|
|
|
PERMX
|
|
|
|
100.0 /
|
|
|
|
|
|
|
|
COPY
|
|
|
|
'PERMX' 'PERMY' /
|
|
|
|
'PERMX' 'PERMZ' /
|
|
|
|
/
|
|
|
|
|
|
|
|
MULTIPLY
|
|
|
|
'PERMZ' 0.1 /
|
|
|
|
/
|
|
|
|
|
|
|
|
PORO
|
|
|
|
0.3 /
|
|
|
|
|
|
|
|
-- =======================================
|
|
|
|
PROPS
|
|
|
|
|
|
|
|
SWFN
|
|
|
|
-- SPE 1 Table
|
|
|
|
0.12 0 0
|
|
|
|
0.18 4.64876033057851E-008 0
|
|
|
|
0.24 0.000000186 0
|
|
|
|
0.3 4.18388429752066E-007 0
|
|
|
|
0.36 7.43801652892562E-007 0
|
|
|
|
0.42 1.16219008264463E-006 0
|
|
|
|
0.48 1.67355371900826E-006 0
|
|
|
|
0.54 2.27789256198347E-006 0
|
|
|
|
0.6 2.97520661157025E-006 0
|
|
|
|
0.66 3.7654958677686E-006 0
|
|
|
|
0.72 4.64876033057851E-006 0
|
|
|
|
0.78 0.000005625 0
|
|
|
|
0.84 6.69421487603306E-006 0
|
|
|
|
0.91 8.05914256198347E-006 0
|
|
|
|
1 0.00001 0 /
|
|
|
|
|
|
|
|
SOF2
|
|
|
|
-- SPE 1 Table
|
|
|
|
0 0
|
|
|
|
0.03 0
|
|
|
|
0.18 0
|
|
|
|
0.28 0.0001
|
|
|
|
0.38 0.001
|
|
|
|
0.43 0.01
|
|
|
|
0.48 0.021
|
|
|
|
0.58 0.09
|
|
|
|
0.63 0.2
|
|
|
|
0.68 0.35
|
|
|
|
0.76 0.7
|
|
|
|
0.83 0.98
|
|
|
|
0.86 0.997
|
|
|
|
0.879 1
|
|
|
|
0.88 1
|
|
|
|
/
|
|
|
|
|
|
|
|
DENSITY
|
|
|
|
853.0 1014.0 0.75 /
|
|
|
|
|
|
|
|
END
|
|
|
|
)";
|
|
|
|
|
|
|
|
const auto deck = Opm::Deck{
|
|
|
|
Opm::Parser{}.parseString(input, Opm::ParseContext{})
|
|
|
|
};
|
|
|
|
|
|
|
|
return {deck, Opm::ParseContext{}};
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SOFN()
|
|
|
|
{
|
|
|
|
return makeTable(3, {
|
|
|
|
0, 0, 1.000000000000000e+20,
|
|
|
|
3.00e-02, 0, 0,
|
|
|
|
1.80e-01, 0, 0,
|
|
|
|
2.80e-01, 1.00e-04, 9.999999999999998e-04,
|
|
|
|
3.80e-01, 1.00e-03, 9.000000000000001e-03,
|
|
|
|
4.30e-01, 1.00e-02, 1.800000000000000e-01,
|
|
|
|
4.80e-01, 2.10e-02, 2.200000000000001e-01,
|
|
|
|
5.80e-01, 9.00e-02, 6.900000000000001e-01,
|
|
|
|
6.30e-01, 2.00e-01, 2.199999999999998e+00,
|
|
|
|
6.80e-01, 3.50e-01, 2.999999999999997e+00,
|
|
|
|
7.60e-01, 7.00e-01, 4.375000000000002e+00,
|
|
|
|
8.30e-01, 9.80e-01, 4.000000000000004e+00,
|
|
|
|
8.60e-01, 9.97e-01, 5.666666666666667e-01,
|
|
|
|
8.79e-01, 1.00e+00, 1.578947368421053e-01,
|
|
|
|
8.80e-01, 1.00e+00, 0,
|
|
|
|
1.00e+20, 1.00e+20, 1.000000000000000e+20,
|
|
|
|
1.00e+20, 1.00e+20, 1.000000000000000e+20,
|
|
|
|
1.00e+20, 1.00e+20, 1.000000000000000e+20,
|
|
|
|
1.00e+20, 1.00e+20, 1.000000000000000e+20,
|
|
|
|
1.00e+20, 1.00e+20, 1.000000000000000e+20,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SWFN()
|
|
|
|
{
|
|
|
|
return makeTable(5, {
|
|
|
|
1.20e-01, 0, 0, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.80e-01, 4.648760330578510e-08, 0, 7.747933884297517e-07, 0,
|
|
|
|
2.40e-01, 1.860000000000000e-07, 0, 2.325206611570248e-06, 0,
|
|
|
|
3.00e-01, 4.183884297520660e-07, 0, 3.873140495867767e-06, 0,
|
|
|
|
3.60e-01, 7.438016528925620e-07, 0, 5.423553719008267e-06, 0,
|
|
|
|
4.20e-01, 1.162190082644630e-06, 0, 6.973140495867802e-06, 0,
|
|
|
|
4.80e-01, 1.673553719008260e-06, 0, 8.522727272727165e-06, 0,
|
|
|
|
5.40e-01, 2.277892561983470e-06, 0, 1.007231404958682e-05, 0,
|
|
|
|
6.00e-01, 2.975206611570250e-06, 0, 1.162190082644635e-05, 0,
|
|
|
|
6.60e-01, 3.765495867768600e-06, 0, 1.317148760330582e-05, 0,
|
|
|
|
7.20e-01, 4.648760330578510e-06, 0, 1.472107438016518e-05, 0,
|
|
|
|
7.80e-01, 5.625000000000000e-06, 0, 1.627066115702482e-05, 0,
|
|
|
|
8.40e-01, 6.694214876033060e-06, 0, 1.782024793388435e-05, 0,
|
|
|
|
9.10e-01, 8.059142561983471e-06, 0, 1.949896694214870e-05, 0,
|
|
|
|
1.00e+00, 1.000000000000000e-05, 0, 2.156508264462812e-05, 0,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} // OilWater
|
|
|
|
} // TwoPhase
|
|
|
|
|
|
|
|
namespace ThreePhase {
|
|
|
|
Opm::EclipseState satfuncTables()
|
|
|
|
{
|
|
|
|
const auto* input = R"(
|
|
|
|
RUNSPEC
|
|
|
|
WATER
|
|
|
|
OIL
|
|
|
|
GAS
|
|
|
|
|
|
|
|
METRIC
|
|
|
|
|
|
|
|
DIMENS
|
|
|
|
1 1 1 /
|
|
|
|
|
|
|
|
TABDIMS
|
|
|
|
/
|
|
|
|
|
|
|
|
-- =======================================
|
|
|
|
GRID
|
|
|
|
|
|
|
|
DXV
|
|
|
|
1 /
|
|
|
|
|
|
|
|
DYV
|
|
|
|
1 /
|
|
|
|
|
|
|
|
DZV
|
|
|
|
0.1 /
|
|
|
|
|
|
|
|
DEPTHZ
|
|
|
|
4*2000.0 /
|
|
|
|
|
|
|
|
PERMX
|
|
|
|
100.0 /
|
|
|
|
|
|
|
|
COPY
|
|
|
|
'PERMX' 'PERMY' /
|
|
|
|
'PERMX' 'PERMZ' /
|
|
|
|
/
|
|
|
|
|
|
|
|
MULTIPLY
|
|
|
|
'PERMZ' 0.1 /
|
|
|
|
/
|
|
|
|
|
|
|
|
PORO
|
|
|
|
0.3 /
|
|
|
|
|
|
|
|
-- =======================================
|
|
|
|
PROPS
|
|
|
|
|
|
|
|
SWFN
|
|
|
|
-- SPE 1 Table
|
|
|
|
0.12 0 0
|
|
|
|
0.18 4.64876033057851E-008 0
|
|
|
|
0.24 0.000000186 0
|
|
|
|
0.3 4.18388429752066E-007 0
|
|
|
|
0.36 7.43801652892562E-007 0
|
|
|
|
0.42 1.16219008264463E-006 0
|
|
|
|
0.48 1.67355371900826E-006 0
|
|
|
|
0.54 2.27789256198347E-006 0
|
|
|
|
0.6 2.97520661157025E-006 0
|
|
|
|
0.66 3.7654958677686E-006 0
|
|
|
|
0.72 4.64876033057851E-006 0
|
|
|
|
0.78 0.000005625 0
|
|
|
|
0.84 6.69421487603306E-006 0
|
|
|
|
0.91 8.05914256198347E-006 0
|
|
|
|
1 0.00001 0 /
|
|
|
|
|
|
|
|
SGFN
|
|
|
|
-- SPE 1 Table
|
|
|
|
0 0 0
|
|
|
|
0.001 0 0
|
|
|
|
0.02 0 0
|
|
|
|
0.05 0.005 0
|
|
|
|
0.12 0.025 0
|
|
|
|
0.2 0.075 0
|
|
|
|
0.25 0.125 0
|
|
|
|
0.3 0.190 0
|
|
|
|
0.4 0.410 0
|
|
|
|
0.45 0.60 0
|
|
|
|
0.5 0.72 0
|
|
|
|
0.6 0.87 0
|
|
|
|
0.7 0.94 0
|
|
|
|
0.85 0.98 0
|
|
|
|
0.88 0.984 0 /
|
|
|
|
|
|
|
|
SOF3
|
|
|
|
-- SPE 1 Table
|
|
|
|
0 0 0
|
|
|
|
0.03 0 0
|
|
|
|
0.18 0 0
|
|
|
|
0.28 0.0001 0.0001
|
|
|
|
0.38 0.001 0.001
|
|
|
|
0.43 0.01 0.01
|
|
|
|
0.48 0.021 0.021
|
|
|
|
0.58 0.09 0.09
|
|
|
|
0.63 0.2 0.2
|
|
|
|
0.68 0.35 0.35
|
|
|
|
0.76 0.7 0.7
|
|
|
|
0.83 0.98 0.98
|
|
|
|
0.86 0.997 0.997
|
|
|
|
0.879 1 1
|
|
|
|
0.88 1 1 /
|
|
|
|
|
|
|
|
DENSITY
|
|
|
|
853.0 1014.0 0.75 /
|
|
|
|
|
|
|
|
END
|
|
|
|
)";
|
|
|
|
|
|
|
|
const auto deck = Opm::Deck{
|
|
|
|
Opm::Parser{}.parseString(input, Opm::ParseContext{})
|
|
|
|
};
|
|
|
|
|
|
|
|
return {deck, Opm::ParseContext{}};
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SGFN()
|
|
|
|
{
|
|
|
|
return makeTable(5, {
|
|
|
|
0, 0, 0, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e-03, 0, 0, 0, 0,
|
|
|
|
2.00e-02, 0, 0, 0, 0,
|
|
|
|
5.00e-02, 5.000000000000000e-03, 0, 1.666666666666667e-01, 0,
|
|
|
|
1.20e-01, 2.500000000000000e-02, 0, 2.857142857142858e-01, 0,
|
|
|
|
2.00e-01, 7.500000000000000e-02, 0, 6.249999999999998e-01, 0,
|
|
|
|
2.50e-01, 1.250000000000000e-01, 0, 1.000000000000000e+00, 0,
|
|
|
|
3.00e-01, 1.900000000000000e-01, 0, 1.300000000000000e+00, 0,
|
|
|
|
4.00e-01, 4.100000000000000e-01, 0, 2.199999999999999e+00, 0,
|
|
|
|
4.50e-01, 6.000000000000000e-01, 0, 3.800000000000001e+00, 0,
|
|
|
|
5.00e-01, 7.200000000000000e-01, 0, 2.400000000000000e+00, 0,
|
|
|
|
6.00e-01, 8.700000000000000e-01, 0, 1.500000000000001e+00, 0,
|
|
|
|
7.00e-01, 9.399999999999999e-01, 0, 6.999999999999996e-01, 0,
|
|
|
|
8.50e-01, 9.800000000000000e-01, 0, 2.666666666666669e-01, 0,
|
|
|
|
8.80e-01, 9.840000000000000e-01, 0, 1.333333333333333e-01, 0,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SOFN()
|
|
|
|
{
|
|
|
|
return makeTable(5, {
|
|
|
|
0, 0, 0, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
3.00e-02, 0, 0, 0, 0,
|
|
|
|
1.80e-01, 0, 0, 0, 0,
|
|
|
|
2.80e-01, 1.00e-04, 1.00e-04, 9.999999999999998e-04, 9.999999999999998e-04,
|
|
|
|
3.80e-01, 1.00e-03, 1.00e-03, 9.000000000000001e-03, 9.000000000000001e-03,
|
|
|
|
4.30e-01, 1.00e-02, 1.00e-02, 1.800000000000000e-01, 1.800000000000000e-01,
|
|
|
|
4.80e-01, 2.10e-02, 2.10e-02, 2.200000000000001e-01, 2.200000000000001e-01,
|
|
|
|
5.80e-01, 9.00e-02, 9.00e-02, 6.900000000000001e-01, 6.900000000000001e-01,
|
|
|
|
6.30e-01, 2.00e-01, 2.00e-01, 2.199999999999998e+00, 2.199999999999998e+00,
|
|
|
|
6.80e-01, 3.50e-01, 3.50e-01, 2.999999999999997e+00, 2.999999999999997e+00,
|
|
|
|
7.60e-01, 7.00e-01, 7.00e-01, 4.375000000000002e+00, 4.375000000000002e+00,
|
|
|
|
8.30e-01, 9.80e-01, 9.80e-01, 4.000000000000004e+00, 4.000000000000004e+00,
|
|
|
|
8.60e-01, 9.97e-01, 9.97e-01, 5.666666666666667e-01, 5.666666666666667e-01,
|
|
|
|
8.79e-01, 1.00e+00, 1.00e+00, 1.578947368421053e-01, 1.578947368421053e-01,
|
|
|
|
8.80e-01, 1.00e+00, 1.00e+00, 0, 0,
|
|
|
|
1.00e+20, 1.00e+20, 1.00e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.00e+20, 1.00e+20, 1.00e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.00e+20, 1.00e+20, 1.00e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.00e+20, 1.00e+20, 1.00e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.00e+20, 1.00e+20, 1.00e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SWFN()
|
|
|
|
{
|
|
|
|
return makeTable(5, {
|
|
|
|
1.20e-01, 0, 0, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.80e-01, 4.648760330578510e-08, 0, 7.747933884297517e-07, 0,
|
|
|
|
2.40e-01, 1.860000000000000e-07, 0, 2.325206611570248e-06, 0,
|
|
|
|
3.00e-01, 4.183884297520660e-07, 0, 3.873140495867767e-06, 0,
|
|
|
|
3.60e-01, 7.438016528925620e-07, 0, 5.423553719008267e-06, 0,
|
|
|
|
4.20e-01, 1.162190082644630e-06, 0, 6.973140495867802e-06, 0,
|
|
|
|
4.80e-01, 1.673553719008260e-06, 0, 8.522727272727165e-06, 0,
|
|
|
|
5.40e-01, 2.277892561983470e-06, 0, 1.007231404958682e-05, 0,
|
|
|
|
6.00e-01, 2.975206611570250e-06, 0, 1.162190082644635e-05, 0,
|
|
|
|
6.60e-01, 3.765495867768600e-06, 0, 1.317148760330582e-05, 0,
|
|
|
|
7.20e-01, 4.648760330578510e-06, 0, 1.472107438016518e-05, 0,
|
|
|
|
7.80e-01, 5.625000000000000e-06, 0, 1.627066115702482e-05, 0,
|
|
|
|
8.40e-01, 6.694214876033060e-06, 0, 1.782024793388435e-05, 0,
|
|
|
|
9.10e-01, 8.059142561983471e-06, 0, 1.949896694214870e-05, 0,
|
|
|
|
1.00e+00, 1.000000000000000e-05, 0, 2.156508264462812e-05, 0,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
1.00e+20, 1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20, 1.0e+20,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} // ThreePhase
|
|
|
|
} // SPE1
|
|
|
|
|
|
|
|
namespace SPE9 { // Family One (SGOF and SWOF)
|
|
|
|
namespace TwoPhase {
|
|
|
|
namespace GasOil {
|
|
|
|
Opm::EclipseState satfuncTables()
|
|
|
|
{
|
|
|
|
const auto* input = R"(
|
|
|
|
RUNSPEC
|
|
|
|
OIL
|
|
|
|
GAS
|
|
|
|
|
|
|
|
METRIC
|
|
|
|
|
|
|
|
DIMENS
|
|
|
|
1 1 1 /
|
|
|
|
|
|
|
|
TABDIMS
|
|
|
|
1 1 30 20 1 20 /
|
|
|
|
|
|
|
|
-- =======================================
|
|
|
|
GRID
|
|
|
|
|
|
|
|
DXV
|
|
|
|
1 /
|
|
|
|
|
|
|
|
DYV
|
|
|
|
1 /
|
|
|
|
|
|
|
|
DZV
|
|
|
|
0.1 /
|
|
|
|
|
|
|
|
DEPTHZ
|
|
|
|
4*2000.0 /
|
|
|
|
|
|
|
|
PERMX
|
|
|
|
100.0 /
|
|
|
|
|
|
|
|
COPY
|
|
|
|
'PERMX' 'PERMY' /
|
|
|
|
'PERMX' 'PERMZ' /
|
|
|
|
/
|
|
|
|
|
|
|
|
MULTIPLY
|
|
|
|
'PERMZ' 0.1 /
|
|
|
|
/
|
|
|
|
|
|
|
|
PORO
|
|
|
|
0.3 /
|
|
|
|
|
|
|
|
-- =======================================
|
|
|
|
PROPS
|
|
|
|
|
|
|
|
SGOF
|
|
|
|
-- SPE 9 Table
|
|
|
|
0 0 1.000000000000000e+00 0
|
|
|
|
4.000000000000000e-02 0 6.000000000000000e-01 1.378951458633672e-02
|
|
|
|
1.000000000000000e-01 2.200000000000000e-02 3.300000000000000e-01 3.447378646584180e-02
|
|
|
|
2.000000000000000e-01 1.000000000000000e-01 1.000000000000000e-01 6.894757293168360e-02
|
|
|
|
3.000000000000000e-01 2.400000000000000e-01 2.000000000000000e-02 1.034213593975254e-01
|
|
|
|
4.000000000000000e-01 3.400000000000000e-01 0 1.378951458633672e-01
|
|
|
|
5.000000000000000e-01 4.200000000000000e-01 0 1.723689323292090e-01
|
|
|
|
6.000000000000000e-01 5.000000000000000e-01 0 2.068427187950508e-01
|
|
|
|
7.000000000000000e-01 8.125000000000000e-01 0 2.413165052608926e-01
|
|
|
|
8.489100000000001e-01 9.635000000000000e-01 0 2.633797285990314e-01 /
|
|
|
|
|
|
|
|
DENSITY
|
|
|
|
853.0 1014.0 0.75 /
|
|
|
|
|
|
|
|
END
|
|
|
|
)";
|
|
|
|
|
|
|
|
const auto deck = Opm::Deck{
|
|
|
|
Opm::Parser{}.parseString(input, Opm::ParseContext{})
|
|
|
|
};
|
|
|
|
|
|
|
|
return {deck, Opm::ParseContext{}};
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SGFN()
|
|
|
|
{
|
|
|
|
// Columns 1, 2, 4 (+ derivatives) of SGOF
|
|
|
|
return makeTable(5, {
|
|
|
|
0, 0, 0, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
4.0000e-02, 0, 1.378951458633672e-02, 0, 3.447378646584180e-01,
|
|
|
|
1.0000e-01, 2.200e-02, 3.447378646584180e-02, 3.666666666666666e-01, 3.447378646584180e-01,
|
|
|
|
2.0000e-01, 1.000e-01, 6.894757293168360e-02, 7.800000000000001e-01, 3.447378646584180e-01,
|
|
|
|
3.0000e-01, 2.400e-01, 1.034213593975254e-01, 1.400000000000000e+00, 3.447378646584180e-01,
|
|
|
|
4.0000e-01, 3.400e-01, 1.378951458633672e-01, 1.000000000000000e+00, 3.447378646584179e-01,
|
|
|
|
5.0000e-01, 4.200e-01, 1.723689323292090e-01, 7.999999999999998e-01, 3.447378646584180e-01,
|
|
|
|
6.0000e-01, 5.000e-01, 2.068427187950508e-01, 8.000000000000004e-01, 3.447378646584180e-01,
|
|
|
|
7.0000e-01, 8.125e-01, 2.413165052608926e-01, 3.125000000000001e+00, 3.447378646584180e-01,
|
|
|
|
8.4891e-01, 9.635e-01, 2.633797285990314e-01, 1.014035323349674e+00, 1.481648199458648e-01,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SOFN()
|
|
|
|
{
|
|
|
|
// Columns 1 and 3 from SGOF (using So = 1 - Sg in 2p
|
|
|
|
// system) + derivatives
|
|
|
|
return makeTable(3, {
|
|
|
|
1.510899999999999e-01, 0, 1.000000000000000e+20,
|
|
|
|
3.000000000000000e-01, 0, 0,
|
|
|
|
4.000000000000000e-01, 0, 0,
|
|
|
|
5.000000000000000e-01, 0, 0,
|
|
|
|
6.000000000000000e-01, 0, 0,
|
|
|
|
7.000000000000000e-01, 2.0e-02, 2.000000000000000e-01,
|
|
|
|
8.000000000000000e-01, 1.0e-01, 7.999999999999993e-01,
|
|
|
|
9.000000000000000e-01, 3.3e-01, 2.300000000000001e+00,
|
|
|
|
9.600000000000000e-01, 6.0e-01, 4.500000000000004e+00,
|
|
|
|
1.000000000000000e+00, 1.0e+00, 9.999999999999991e+00,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.0e+20, 1.000000000000000e+20,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} // GasOil
|
|
|
|
|
|
|
|
namespace OilWater {
|
|
|
|
Opm::EclipseState satfuncTables()
|
|
|
|
{
|
|
|
|
const auto* input = R"(
|
|
|
|
RUNSPEC
|
|
|
|
WATER
|
|
|
|
OIL
|
|
|
|
|
|
|
|
METRIC
|
|
|
|
|
|
|
|
DIMENS
|
|
|
|
1 1 1 /
|
|
|
|
|
|
|
|
TABDIMS
|
|
|
|
1 1 30 20 1 20 /
|
|
|
|
|
|
|
|
-- =======================================
|
|
|
|
GRID
|
|
|
|
|
|
|
|
DXV
|
|
|
|
1 /
|
|
|
|
|
|
|
|
DYV
|
|
|
|
1 /
|
|
|
|
|
|
|
|
DZV
|
|
|
|
0.1 /
|
|
|
|
|
|
|
|
DEPTHZ
|
|
|
|
4*2000.0 /
|
|
|
|
|
|
|
|
PERMX
|
|
|
|
100.0 /
|
|
|
|
|
|
|
|
COPY
|
|
|
|
'PERMX' 'PERMY' /
|
|
|
|
'PERMX' 'PERMZ' /
|
|
|
|
/
|
|
|
|
|
|
|
|
MULTIPLY
|
|
|
|
'PERMZ' 0.1 /
|
|
|
|
/
|
|
|
|
|
|
|
|
PORO
|
|
|
|
0.3 /
|
|
|
|
|
|
|
|
-- =======================================
|
|
|
|
PROPS
|
|
|
|
|
|
|
|
SWOF
|
|
|
|
-- SPE 9 Table
|
|
|
|
1.510900000000000e-01 0 1.000000000000000e+00 2.757902917267344e+01
|
|
|
|
1.512300000000000e-01 0 9.999700000000000e-01 2.476527872133143e+01
|
|
|
|
1.517400000000000e-01 0 9.999300000000000e-01 1.778295801053983e+01
|
|
|
|
1.524600000000000e-01 0 9.999100000000000e-01 1.284562231290197e+01
|
|
|
|
1.564700000000000e-01 0 9.995100000000000e-01 5.450995115978905e+00
|
|
|
|
1.658500000000000e-01 0 9.962900000000000e-01 2.758592392996661e+00
|
|
|
|
1.783500000000000e-01 0 9.915900000000000e-01 1.925705711981923e+00
|
|
|
|
2.033500000000000e-01 1.000000000000000e-05 9.788300000000000e-01 1.406530487806345e+00
|
|
|
|
2.533500000000000e-01 3.000000000000000e-05 9.437300000000000e-01 1.072134759087680e+00
|
|
|
|
3.500000000000000e-01 2.800000000000000e-04 8.302300000000000e-01 8.035839625187723e-01
|
|
|
|
3.520000000000000e-01 2.292000000000000e-03 8.042770000000000e-01 6.012228359642811e-01
|
|
|
|
3.540000000000000e-01 4.304000000000000e-03 7.783260000000000e-01 4.100312162247224e-01
|
|
|
|
3.560000000000000e-01 6.316000000000000e-03 7.523740000000000e-01 2.286990994143945e-01
|
|
|
|
3.580000000000000e-01 8.328000000000000e-03 7.264220000000000e-01 8.032392246541140e-02
|
|
|
|
3.600000000000000e-01 1.034000000000000e-02 7.004700000000000e-01 3.192272626736951e-02
|
|
|
|
3.643950000000000e-01 1.554800000000000e-02 6.422580000000000e-01 -3.440483889291011e-02
|
|
|
|
3.687900000000000e-01 2.075600000000000e-02 5.840460000000000e-01 -7.853128556918762e-02
|
|
|
|
3.700000000000000e-01 2.219000000000000e-02 5.680200000000000e-01 -8.232340208043021e-02
|
|
|
|
3.800000000000000e-01 3.589000000000000e-02 4.349800000000000e-01 -1.066618953253145e-01
|
|
|
|
4.000000000000000e-01 6.952999999999999e-02 1.714300000000000e-01 -1.105919069824205e-01
|
|
|
|
4.334500000000000e-01 8.790000000000001e-02 1.253100000000000e-01 -1.179003497131789e-01
|
|
|
|
4.613900000000000e-01 1.049100000000000e-01 9.497999999999999e-02 -1.227266798183968e-01
|
|
|
|
4.893200000000000e-01 1.232900000000000e-01 7.053000000000000e-02 -1.282424856529315e-01
|
|
|
|
5.172500000000000e-01 1.430300000000000e-01 5.113000000000000e-02 -1.330688157581493e-01
|
|
|
|
5.731200000000000e-01 1.865900000000000e-01 2.464000000000000e-02 -1.427214759685850e-01
|
|
|
|
6.010600000000000e-01 2.103800000000000e-01 1.619000000000000e-02 -1.468583303444861e-01
|
|
|
|
6.569300000000000e-01 2.619000000000000e-01 5.940000000000000e-03 -1.558215148256049e-01
|
|
|
|
7.128000000000000e-01 3.186500000000000e-01 1.590000000000000e-03 -1.640952235774069e-01
|
|
|
|
8.111100000000000e-01 4.309200000000000e-01 2.000000000000000e-05 -1.792636896223773e-01
|
|
|
|
8.814900000000000e-01 4.900000000000000e-01 0 -1.896058255621299e-01 /
|
|
|
|
|
|
|
|
DENSITY
|
|
|
|
853.0 1014.0 0.75 /
|
|
|
|
|
|
|
|
END
|
|
|
|
)";
|
|
|
|
|
|
|
|
const auto deck = Opm::Deck{
|
|
|
|
Opm::Parser{}.parseString(input, Opm::ParseContext{})
|
|
|
|
};
|
|
|
|
|
|
|
|
return {deck, Opm::ParseContext{}};
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SOFN()
|
|
|
|
{
|
|
|
|
return makeTable(3, {
|
|
|
|
1.185100000000000e-01, 0, 1.000000000000000e+20,
|
|
|
|
1.888900000000000e-01, 2.000000000000000e-05, 2.841716396703610e-04,
|
|
|
|
2.872000000000000e-01, 1.590000000000000e-03, 1.596989116061438e-02,
|
|
|
|
3.430700000000000e-01, 5.940000000000000e-03, 7.785931626991233e-02,
|
|
|
|
3.989400000000000e-01, 1.619000000000000e-02, 1.834616073026670e-01,
|
|
|
|
4.268800000000000e-01, 2.464000000000000e-02, 3.024337866857543e-01,
|
|
|
|
4.827500000000000e-01, 5.113000000000000e-02, 4.741363880436731e-01,
|
|
|
|
5.106800000000000e-01, 7.053000000000000e-02, 6.945936269244535e-01,
|
|
|
|
5.386100000000000e-01, 9.497999999999999e-02, 8.754027926960254e-01,
|
|
|
|
5.665500000000000e-01, 1.253100000000000e-01, 1.085540443808162e+00,
|
|
|
|
6.000000000000000e-01, 1.714300000000000e-01, 1.378774289985053e+00,
|
|
|
|
6.200000000000000e-01, 4.349800000000000e-01, 1.317749999999999e+01,
|
|
|
|
6.300000000000000e-01, 5.680200000000000e-01, 1.330399999999999e+01,
|
|
|
|
6.312100000000000e-01, 5.840460000000000e-01, 1.324462809917306e+01,
|
|
|
|
6.356050000000000e-01, 6.422580000000000e-01, 1.324505119453948e+01,
|
|
|
|
6.400000000000000e-01, 7.004700000000000e-01, 1.324505119453914e+01,
|
|
|
|
6.420000000000000e-01, 7.264220000000000e-01, 1.297599999999998e+01,
|
|
|
|
6.440000000000000e-01, 7.523740000000000e-01, 1.297599999999998e+01,
|
|
|
|
6.460000000000000e-01, 7.783260000000000e-01, 1.297599999999998e+01,
|
|
|
|
6.480000000000000e-01, 8.042770000000000e-01, 1.297550000000002e+01,
|
|
|
|
6.500000000000000e-01, 8.302300000000000e-01, 1.297649999999999e+01,
|
|
|
|
7.466500000000000e-01, 9.437300000000000e-01, 1.174340403517847e+00,
|
|
|
|
7.966500000000000e-01, 9.788300000000000e-01, 7.020000000000013e-01,
|
|
|
|
8.216500000000000e-01, 9.915900000000000e-01, 5.103999999999993e-01,
|
|
|
|
8.341499999999999e-01, 9.962900000000000e-01, 3.760000000000043e-01,
|
|
|
|
8.435300000000000e-01, 9.995100000000000e-01, 3.432835820895503e-01,
|
|
|
|
8.475400000000000e-01, 9.999100000000000e-01, 9.975062344138656e-02,
|
|
|
|
8.482600000000000e-01, 9.999300000000000e-01, 2.777777777780348e-02,
|
|
|
|
8.487700000000000e-01, 9.999700000000000e-01, 7.843137254909643e-02,
|
|
|
|
8.489100000000001e-01, 1.000000000000000e+00, 2.142857142854877e-01,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SWFN()
|
|
|
|
{
|
|
|
|
// Columns 1, 2, 4 (+ derivatives) of SWOF
|
|
|
|
return makeTable(5, {
|
|
|
|
1.51090e-01, 0, 2.757902917267344e+01, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.51230e-01, 0, 2.476527872133143e+01, 0, -2.009821750958577e+04,
|
|
|
|
1.51740e-01, 0, 1.778295801053983e+01, 0, -1.369082492312075e+04,
|
|
|
|
1.52460e-01, 0, 1.284562231290197e+01, 0, -6.857410691163744e+03,
|
|
|
|
1.56470e-01, 0, 5.450995115978905e+00, 0, -1.844046682524494e+03,
|
|
|
|
1.65850e-01, 0, 2.758592392996661e+00, 0, -2.870365376313702e+02,
|
|
|
|
1.78350e-01, 0, 1.925705711981923e+00, 0, -6.663093448117903e+01,
|
|
|
|
2.03350e-01, 1.000000000000000e-05, 1.406530487806345e+00, 4.000000000000000e-04, -2.076700896702310e+01,
|
|
|
|
2.53350e-01, 3.000000000000000e-05, 1.072134759087680e+00, 4.000000000000000e-04, -6.687914574373308e+00,
|
|
|
|
3.50000e-01, 2.800000000000000e-04, 8.035839625187723e-01, 2.586652871184700e-03, -2.778590756015570e+00,
|
|
|
|
3.52000e-01, 2.292000000000000e-03, 6.012228359642811e-01, 1.006000000000000e+00, -1.011805632772457e+02,
|
|
|
|
3.54000e-01, 4.304000000000000e-03, 4.100312162247224e-01, 1.006000000000000e+00, -9.559580986977932e+01,
|
|
|
|
3.56000e-01, 6.316000000000000e-03, 2.286990994143945e-01, 1.006000000000000e+00, -9.066605840516394e+01,
|
|
|
|
3.58000e-01, 8.328000000000000e-03, 8.032392246541140e-02, 1.006000000000000e+00, -7.418758847449155e+01,
|
|
|
|
3.60000e-01, 1.034000000000000e-02, 3.192272626736951e-02, 1.006000000000000e+00, -2.420059809902094e+01,
|
|
|
|
3.64395e-01, 1.554800000000000e-02, -3.440483889291011e-02, 1.184982935153600e+00, -1.509159616843634e+01,
|
|
|
|
3.68790e-01, 2.075600000000000e-02, -7.853128556918762e-02, 1.184982935153600e+00, -1.004014713908486e+01,
|
|
|
|
3.70000e-01, 2.219000000000000e-02, -8.232340208043021e-02, 1.185123966942200e+00, -3.133980587803838e+00,
|
|
|
|
3.80000e-01, 3.589000000000000e-02, -1.066618953253145e-01, 1.370000000000000e+00, -2.433849324488431e+00,
|
|
|
|
4.00000e-01, 6.952999999999999e-02, -1.105919069824205e-01, 1.682000000000000e+00, -1.965005828552983e-01,
|
|
|
|
4.33450e-01, 8.790000000000001e-02, -1.179003497131789e-01, 5.491778774290000e-01, -2.184885719210279e-01,
|
|
|
|
4.61390e-01, 1.049100000000000e-01, -1.227266798183968e-01, 6.088045812455301e-01, -1.727390875167428e-01,
|
|
|
|
4.89320e-01, 1.232900000000000e-01, -1.282424856529315e-01, 6.580737558181200e-01, -1.974867824752831e-01,
|
|
|
|
5.17250e-01, 1.430300000000000e-01, -1.330688157581493e-01, 7.067669172932300e-01, -1.728009346658736e-01,
|
|
|
|
5.73120e-01, 1.865900000000000e-01, -1.427214759685850e-01, 7.796670843028500e-01, -1.727700055563935e-01,
|
|
|
|
6.01060e-01, 2.103800000000000e-01, -1.468583303444861e-01, 8.514674302075900e-01, -1.480620750143510e-01,
|
|
|
|
6.56930e-01, 2.619000000000000e-01, -1.558215148256049e-01, 9.221406837300899e-01, -1.604292908737955e-01,
|
|
|
|
7.12800e-01, 3.186500000000000e-01, -1.640952235774069e-01, 1.015750850187900e+00, -1.480885761911974e-01,
|
|
|
|
8.11110e-01, 4.309200000000000e-01, -1.792636896223773e-01, 1.141999796561900e+00, -1.542921986061490e-01,
|
|
|
|
8.81490e-01, 4.900000000000000e-01, -1.896058255621299e-01, 8.394430235862500e-01, -1.469470863846619e-01,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} // OilWater
|
|
|
|
} // TwoPhase
|
|
|
|
|
|
|
|
namespace ThreePhase {
|
|
|
|
Opm::EclipseState satfuncTables()
|
|
|
|
{
|
|
|
|
const auto* input = R"(
|
|
|
|
RUNSPEC
|
|
|
|
WATER
|
|
|
|
OIL
|
|
|
|
GAS
|
|
|
|
|
|
|
|
METRIC
|
|
|
|
|
|
|
|
DIMENS
|
|
|
|
1 1 1 /
|
|
|
|
|
|
|
|
TABDIMS
|
|
|
|
1 1 30 20 1 20 /
|
|
|
|
|
|
|
|
-- =======================================
|
|
|
|
GRID
|
2016-11-16 09:12:59 -06:00
|
|
|
|
INIT File: Add Support for Writing Saturation Function Tables
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.
2017-11-16 09:34:05 -06:00
|
|
|
DXV
|
|
|
|
1 /
|
2016-11-16 09:12:59 -06:00
|
|
|
|
INIT File: Add Support for Writing Saturation Function Tables
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.
2017-11-16 09:34:05 -06:00
|
|
|
DYV
|
|
|
|
1 /
|
|
|
|
|
|
|
|
DZV
|
|
|
|
0.1 /
|
|
|
|
|
|
|
|
DEPTHZ
|
|
|
|
4*2000.0 /
|
|
|
|
|
|
|
|
PERMX
|
|
|
|
100.0 /
|
|
|
|
|
|
|
|
COPY
|
|
|
|
'PERMX' 'PERMY' /
|
|
|
|
'PERMX' 'PERMZ' /
|
|
|
|
/
|
|
|
|
|
|
|
|
MULTIPLY
|
|
|
|
'PERMZ' 0.1 /
|
|
|
|
/
|
|
|
|
|
|
|
|
PORO
|
|
|
|
0.3 /
|
|
|
|
|
|
|
|
-- =======================================
|
|
|
|
PROPS
|
|
|
|
|
|
|
|
SWOF
|
|
|
|
-- SPE 9 Table
|
|
|
|
1.510900000000000e-01 0 1.000000000000000e+00 2.757902917267344e+01
|
|
|
|
1.512300000000000e-01 0 9.999700000000000e-01 2.476527872133143e+01
|
|
|
|
1.517400000000000e-01 0 9.999300000000000e-01 1.778295801053983e+01
|
|
|
|
1.524600000000000e-01 0 9.999100000000000e-01 1.284562231290197e+01
|
|
|
|
1.564700000000000e-01 0 9.995100000000000e-01 5.450995115978905e+00
|
|
|
|
1.658500000000000e-01 0 9.962900000000000e-01 2.758592392996661e+00
|
|
|
|
1.783500000000000e-01 0 9.915900000000000e-01 1.925705711981923e+00
|
|
|
|
2.033500000000000e-01 1.000000000000000e-05 9.788300000000000e-01 1.406530487806345e+00
|
|
|
|
2.533500000000000e-01 3.000000000000000e-05 9.437300000000000e-01 1.072134759087680e+00
|
|
|
|
3.500000000000000e-01 2.800000000000000e-04 8.302300000000000e-01 8.035839625187723e-01
|
|
|
|
3.520000000000000e-01 2.292000000000000e-03 8.042770000000000e-01 6.012228359642811e-01
|
|
|
|
3.540000000000000e-01 4.304000000000000e-03 7.783260000000000e-01 4.100312162247224e-01
|
|
|
|
3.560000000000000e-01 6.316000000000000e-03 7.523740000000000e-01 2.286990994143945e-01
|
|
|
|
3.580000000000000e-01 8.328000000000000e-03 7.264220000000000e-01 8.032392246541140e-02
|
|
|
|
3.600000000000000e-01 1.034000000000000e-02 7.004700000000000e-01 3.192272626736951e-02
|
|
|
|
3.643950000000000e-01 1.554800000000000e-02 6.422580000000000e-01 -3.440483889291011e-02
|
|
|
|
3.687900000000000e-01 2.075600000000000e-02 5.840460000000000e-01 -7.853128556918762e-02
|
|
|
|
3.700000000000000e-01 2.219000000000000e-02 5.680200000000000e-01 -8.232340208043021e-02
|
|
|
|
3.800000000000000e-01 3.589000000000000e-02 4.349800000000000e-01 -1.066618953253145e-01
|
|
|
|
4.000000000000000e-01 6.952999999999999e-02 1.714300000000000e-01 -1.105919069824205e-01
|
|
|
|
4.334500000000000e-01 8.790000000000001e-02 1.253100000000000e-01 -1.179003497131789e-01
|
|
|
|
4.613900000000000e-01 1.049100000000000e-01 9.497999999999999e-02 -1.227266798183968e-01
|
|
|
|
4.893200000000000e-01 1.232900000000000e-01 7.053000000000000e-02 -1.282424856529315e-01
|
|
|
|
5.172500000000000e-01 1.430300000000000e-01 5.113000000000000e-02 -1.330688157581493e-01
|
|
|
|
5.731200000000000e-01 1.865900000000000e-01 2.464000000000000e-02 -1.427214759685850e-01
|
|
|
|
6.010600000000000e-01 2.103800000000000e-01 1.619000000000000e-02 -1.468583303444861e-01
|
|
|
|
6.569300000000000e-01 2.619000000000000e-01 5.940000000000000e-03 -1.558215148256049e-01
|
|
|
|
7.128000000000000e-01 3.186500000000000e-01 1.590000000000000e-03 -1.640952235774069e-01
|
|
|
|
8.111100000000000e-01 4.309200000000000e-01 2.000000000000000e-05 -1.792636896223773e-01
|
|
|
|
8.814900000000000e-01 4.900000000000000e-01 0 -1.896058255621299e-01 /
|
|
|
|
|
|
|
|
SGOF
|
|
|
|
-- SPE 9 Table
|
|
|
|
0 0 1.000000000000000e+00 0
|
|
|
|
4.000000000000000e-02 0 6.000000000000000e-01 1.378951458633672e-02
|
|
|
|
1.000000000000000e-01 2.200000000000000e-02 3.300000000000000e-01 3.447378646584180e-02
|
|
|
|
2.000000000000000e-01 1.000000000000000e-01 1.000000000000000e-01 6.894757293168360e-02
|
|
|
|
3.000000000000000e-01 2.400000000000000e-01 2.000000000000000e-02 1.034213593975254e-01
|
|
|
|
4.000000000000000e-01 3.400000000000000e-01 0 1.378951458633672e-01
|
|
|
|
5.000000000000000e-01 4.200000000000000e-01 0 1.723689323292090e-01
|
|
|
|
6.000000000000000e-01 5.000000000000000e-01 0 2.068427187950508e-01
|
|
|
|
7.000000000000000e-01 8.125000000000000e-01 0 2.413165052608926e-01
|
|
|
|
8.489100000000001e-01 9.635000000000000e-01 0 2.633797285990314e-01 /
|
|
|
|
|
|
|
|
DENSITY
|
|
|
|
853.0 1014.0 0.75 /
|
|
|
|
|
|
|
|
END
|
|
|
|
)";
|
|
|
|
|
|
|
|
const auto deck = Opm::Deck{
|
|
|
|
Opm::Parser{}.parseString(input, Opm::ParseContext{})
|
|
|
|
};
|
|
|
|
|
|
|
|
return {deck, Opm::ParseContext{}};
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SGFN()
|
|
|
|
{
|
|
|
|
// Columns 1, 2, 4 (+ derivatives) of SGOF
|
|
|
|
return makeTable(5, {
|
|
|
|
0, 0, 0, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
4.0000e-02, 0, 1.378951458633672e-02, 0, 3.447378646584180e-01,
|
|
|
|
1.0000e-01, 2.200e-02, 3.447378646584180e-02, 3.666666666666666e-01, 3.447378646584180e-01,
|
|
|
|
2.0000e-01, 1.000e-01, 6.894757293168360e-02, 7.800000000000001e-01, 3.447378646584180e-01,
|
|
|
|
3.0000e-01, 2.400e-01, 1.034213593975254e-01, 1.400000000000000e+00, 3.447378646584180e-01,
|
|
|
|
4.0000e-01, 3.400e-01, 1.378951458633672e-01, 1.000000000000000e+00, 3.447378646584179e-01,
|
|
|
|
5.0000e-01, 4.200e-01, 1.723689323292090e-01, 7.999999999999998e-01, 3.447378646584180e-01,
|
|
|
|
6.0000e-01, 5.000e-01, 2.068427187950508e-01, 8.000000000000004e-01, 3.447378646584180e-01,
|
|
|
|
7.0000e-01, 8.125e-01, 2.413165052608926e-01, 3.125000000000001e+00, 3.447378646584180e-01,
|
|
|
|
8.4891e-01, 9.635e-01, 2.633797285990314e-01, 1.014035323349674e+00, 1.481648199458648e-01,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.0000e+20, 1.000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SOFN()
|
|
|
|
{
|
|
|
|
// Column 1 from SGOF merged with column 1 from SWOF, Column 3 from
|
|
|
|
// SWOF (+ piecewise linear interp), Column 3 from SGOF (+piecewise
|
|
|
|
// linear interp) + derivatives of those.
|
|
|
|
return makeTable(5, {
|
|
|
|
0, 0, 0, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.185100000000000e-01, 0, 0, 0, 0,
|
|
|
|
1.489100000000001e-01, 8.638817845978999e-06, 0, 2.841716396703609e-04, 0,
|
|
|
|
1.888900000000000e-01, 2.000000000000000e-05, 0, 2.841716396703610e-04, 0,
|
|
|
|
2.489100000000001e-01, 9.785128674600764e-04, 0, 1.596989116061438e-02, 0,
|
|
|
|
2.872000000000000e-01, 1.590000000000000e-03, 0, 1.596989116061438e-02, 0,
|
|
|
|
3.430700000000000e-01, 5.940000000000000e-03, 0, 7.785931626991233e-02, 0,
|
|
|
|
3.489100000000001e-01, 7.011415786647587e-03, 0, 1.834616073026669e-01, 0,
|
|
|
|
3.989400000000000e-01, 1.619000000000000e-02, 0, 1.834616073026670e-01, 0,
|
|
|
|
4.268800000000000e-01, 2.464000000000000e-02, 0, 3.024337866857543e-01, 0,
|
|
|
|
4.489100000000000e-01, 3.508522462860211e-02, 0, 4.741363880436730e-01, 0,
|
|
|
|
4.827500000000000e-01, 5.113000000000000e-02, 6.767999999999998e-03, 4.741363880436731e-01, 2.000000000000000e-01,
|
|
|
|
5.106800000000000e-01, 7.053000000000000e-02, 1.235400000000000e-02, 6.945936269244535e-01, 2.000000000000000e-01,
|
|
|
|
5.386100000000000e-01, 9.497999999999999e-02, 1.794000000000000e-02, 8.754027926960254e-01, 2.000000000000001e-01,
|
|
|
|
5.489100000000000e-01, 1.061610665712240e-01, 2.000000000000000e-02, 1.085540443808162e+00, 2.000000000000001e-01,
|
|
|
|
5.665500000000000e-01, 1.253100000000000e-01, 3.411199999999998e-02, 1.085540443808162e+00, 7.999999999999990e-01,
|
|
|
|
6.000000000000000e-01, 1.714300000000000e-01, 6.087199999999994e-02, 1.378774289985053e+00, 7.999999999999994e-01,
|
|
|
|
6.200000000000000e-01, 4.349800000000000e-01, 7.687199999999994e-02, 1.317749999999999e+01, 7.999999999999993e-01,
|
|
|
|
6.300000000000000e-01, 5.680200000000000e-01, 8.487199999999995e-02, 1.330399999999999e+01, 8.000000000000000e-01,
|
|
|
|
6.312100000000000e-01, 5.840460000000000e-01, 8.583999999999999e-02, 1.324462809917306e+01, 8.000000000000023e-01,
|
|
|
|
6.356050000000000e-01, 6.422580000000000e-01, 8.935599999999992e-02, 1.324505119453948e+01, 7.999999999999987e-01,
|
|
|
|
6.400000000000000e-01, 7.004700000000000e-01, 9.287199999999994e-02, 1.324505119453914e+01, 7.999999999999975e-01,
|
|
|
|
6.420000000000000e-01, 7.264220000000000e-01, 9.447199999999994e-02, 1.297599999999998e+01, 8.000000000000014e-01,
|
|
|
|
6.440000000000000e-01, 7.523740000000000e-01, 9.607199999999995e-02, 1.297599999999998e+01, 8.000000000000014e-01,
|
|
|
|
6.460000000000000e-01, 7.783260000000000e-01, 9.767199999999995e-02, 1.297599999999998e+01, 8.000000000000014e-01,
|
|
|
|
6.480000000000000e-01, 8.042770000000000e-01, 9.927199999999994e-02, 1.297550000000002e+01, 7.999999999999945e-01,
|
|
|
|
6.489100000000001e-01, 8.160856150000010e-01, 1.000000000000000e-01, 1.297649999999996e+01, 8.000000000000000e-01,
|
|
|
|
6.500000000000000e-01, 8.302300000000000e-01, 1.025069999999998e-01, 1.297650000000002e+01, 2.300000000000002e+00,
|
|
|
|
7.466500000000000e-01, 9.437300000000000e-01, 3.248019999999999e-01, 1.174340403517847e+00, 2.300000000000000e+00,
|
|
|
|
7.489100000000001e-01, 9.453165200000000e-01, 3.300000000000000e-01, 7.020000000000034e-01, 2.300000000000000e+00,
|
|
|
|
7.966500000000000e-01, 9.788300000000000e-01, 5.448299999999997e-01, 7.020000000000013e-01, 4.500000000000004e+00,
|
|
|
|
8.089100000000000e-01, 9.850875040000000e-01, 6.000000000000000e-01, 5.104000000000000e-01, 4.500000000000004e+00,
|
|
|
|
8.216500000000000e-01, 9.915900000000000e-01, 7.273999999999996e-01, 5.103999999999986e-01, 9.999999999999991e+00,
|
|
|
|
8.341499999999999e-01, 9.962900000000000e-01, 8.523999999999990e-01, 3.760000000000043e-01, 9.999999999999991e+00,
|
|
|
|
8.435300000000000e-01, 9.995100000000000e-01, 9.461999999999995e-01, 3.432835820895503e-01, 9.999999999999988e+00,
|
|
|
|
8.475400000000000e-01, 9.999100000000000e-01, 9.862999999999991e-01, 9.975062344138656e-02, 1.000000000000000e+01,
|
|
|
|
8.482600000000000e-01, 9.999300000000000e-01, 9.934999999999996e-01, 2.777777777780348e-02, 1.000000000000000e+01,
|
|
|
|
8.487700000000000e-01, 9.999700000000000e-01, 9.985999999999997e-01, 7.843137254909643e-02, 1.000000000000000e+01,
|
|
|
|
8.489100000000001e-01, 1.000000000000000e+00, 1.000000000000000e+00, 2.142857142854877e-01, 1.000000000000000e+01,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> expect_SWFN()
|
|
|
|
{
|
|
|
|
// Columns 1, 2, 4 (+ derivatives) of SWOF
|
|
|
|
return makeTable(5, {
|
|
|
|
1.51090e-01, 0, 2.757902917267344e+01, 1.000000000000000e+20, 1.000000000000000e+20,
|
|
|
|
1.51230e-01, 0, 2.476527872133143e+01, 0, -2.009821750958577e+04,
|
|
|
|
1.51740e-01, 0, 1.778295801053983e+01, 0, -1.369082492312075e+04,
|
|
|
|
1.52460e-01, 0, 1.284562231290197e+01, 0, -6.857410691163744e+03,
|
|
|
|
1.56470e-01, 0, 5.450995115978905e+00, 0, -1.844046682524494e+03,
|
|
|
|
1.65850e-01, 0, 2.758592392996661e+00, 0, -2.870365376313702e+02,
|
|
|
|
1.78350e-01, 0, 1.925705711981923e+00, 0, -6.663093448117903e+01,
|
|
|
|
2.03350e-01, 1.000000000000000e-05, 1.406530487806345e+00, 4.000000000000000e-04, -2.076700896702310e+01,
|
|
|
|
2.53350e-01, 3.000000000000000e-05, 1.072134759087680e+00, 4.000000000000000e-04, -6.687914574373308e+00,
|
|
|
|
3.50000e-01, 2.800000000000000e-04, 8.035839625187723e-01, 2.586652871184700e-03, -2.778590756015570e+00,
|
|
|
|
3.52000e-01, 2.292000000000000e-03, 6.012228359642811e-01, 1.006000000000000e+00, -1.011805632772457e+02,
|
|
|
|
3.54000e-01, 4.304000000000000e-03, 4.100312162247224e-01, 1.006000000000000e+00, -9.559580986977932e+01,
|
|
|
|
3.56000e-01, 6.316000000000000e-03, 2.286990994143945e-01, 1.006000000000000e+00, -9.066605840516394e+01,
|
|
|
|
3.58000e-01, 8.328000000000000e-03, 8.032392246541140e-02, 1.006000000000000e+00, -7.418758847449155e+01,
|
|
|
|
3.60000e-01, 1.034000000000000e-02, 3.192272626736951e-02, 1.006000000000000e+00, -2.420059809902094e+01,
|
|
|
|
3.64395e-01, 1.554800000000000e-02, -3.440483889291011e-02, 1.184982935153600e+00, -1.509159616843634e+01,
|
|
|
|
3.68790e-01, 2.075600000000000e-02, -7.853128556918762e-02, 1.184982935153600e+00, -1.004014713908486e+01,
|
|
|
|
3.70000e-01, 2.219000000000000e-02, -8.232340208043021e-02, 1.185123966942200e+00, -3.133980587803838e+00,
|
|
|
|
3.80000e-01, 3.589000000000000e-02, -1.066618953253145e-01, 1.370000000000000e+00, -2.433849324488431e+00,
|
|
|
|
4.00000e-01, 6.952999999999999e-02, -1.105919069824205e-01, 1.682000000000000e+00, -1.965005828552983e-01,
|
|
|
|
4.33450e-01, 8.790000000000001e-02, -1.179003497131789e-01, 5.491778774290000e-01, -2.184885719210279e-01,
|
|
|
|
4.61390e-01, 1.049100000000000e-01, -1.227266798183968e-01, 6.088045812455301e-01, -1.727390875167428e-01,
|
|
|
|
4.89320e-01, 1.232900000000000e-01, -1.282424856529315e-01, 6.580737558181200e-01, -1.974867824752831e-01,
|
|
|
|
5.17250e-01, 1.430300000000000e-01, -1.330688157581493e-01, 7.067669172932300e-01, -1.728009346658736e-01,
|
|
|
|
5.73120e-01, 1.865900000000000e-01, -1.427214759685850e-01, 7.796670843028500e-01, -1.727700055563935e-01,
|
|
|
|
6.01060e-01, 2.103800000000000e-01, -1.468583303444861e-01, 8.514674302075900e-01, -1.480620750143510e-01,
|
|
|
|
6.56930e-01, 2.619000000000000e-01, -1.558215148256049e-01, 9.221406837300899e-01, -1.604292908737955e-01,
|
|
|
|
7.12800e-01, 3.186500000000000e-01, -1.640952235774069e-01, 1.015750850187900e+00, -1.480885761911974e-01,
|
|
|
|
8.11110e-01, 4.309200000000000e-01, -1.792636896223773e-01, 1.141999796561900e+00, -1.542921986061490e-01,
|
|
|
|
8.81490e-01, 4.900000000000000e-01, -1.896058255621299e-01, 8.394430235862500e-01, -1.469470863846619e-01,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} // ThreePhase
|
|
|
|
} // SPE9
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE (FileWrite_PVT)
|
2016-11-16 09:12:59 -06:00
|
|
|
|
2016-11-28 04:37:31 -06:00
|
|
|
BOOST_AUTO_TEST_CASE(Test_PVTX) {
|
2016-12-29 06:51:07 -06:00
|
|
|
setup cfg( "table_deck.DATA");
|
2016-11-16 09:12:59 -06:00
|
|
|
Tables tables( cfg.es.getUnits() );
|
|
|
|
|
|
|
|
tables.addPVTO( cfg.es.getTableManager().getPvtoTables() );
|
2016-11-28 04:37:31 -06:00
|
|
|
tables.addPVTG( cfg.es.getTableManager().getPvtgTables() );
|
2016-12-23 02:09:31 -06:00
|
|
|
tables.addPVTW( cfg.es.getTableManager().getPvtwTable() );
|
|
|
|
tables.addDensity( cfg.es.getTableManager().getDensityTable( ) );
|
2016-11-16 09:12:59 -06:00
|
|
|
{
|
|
|
|
ERT::FortIO f("TEST.INIT" , std::fstream::out);
|
2017-11-15 11:04:55 -06:00
|
|
|
fwrite(tables, f);
|
2016-11-16 09:12:59 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
ecl_file_type * f = ecl_file_open("TEST.INIT" , 0 );
|
2016-11-28 04:37:31 -06:00
|
|
|
const ecl_kw_type * tabdims = ecl_file_iget_named_kw( f , "TABDIMS" , 0 );
|
|
|
|
const ecl_kw_type * tab = ecl_file_iget_named_kw( f , "TAB" , 0 );
|
2016-11-16 09:12:59 -06:00
|
|
|
|
2016-12-23 02:09:31 -06:00
|
|
|
BOOST_CHECK_EQUAL( ecl_kw_get_size( tab ) , ecl_kw_iget_int( tabdims , TABDIMS_TAB_SIZE_ITEM ));
|
2016-11-28 04:37:31 -06:00
|
|
|
/* PVTO */
|
2016-11-16 09:12:59 -06:00
|
|
|
{
|
2017-10-15 20:55:08 -05:00
|
|
|
int offset = ecl_kw_iget_int( tabdims , TABDIMS_IBPVTO_OFFSET_ITEM ) - 1;
|
|
|
|
int rs_offset = ecl_kw_iget_int( tabdims , TABDIMS_JBPVTO_OFFSET_ITEM ) - 1;
|
2016-11-16 09:12:59 -06:00
|
|
|
int column_stride = ecl_kw_iget_int( tabdims , TABDIMS_NRPVTO_ITEM ) * ecl_kw_iget_int( tabdims , TABDIMS_NPPVTO_ITEM ) * ecl_kw_iget_int( tabdims , TABDIMS_NTPVTO_ITEM );
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL( 2, ecl_kw_iget_int( tabdims , TABDIMS_NRPVTO_ITEM ) );
|
|
|
|
BOOST_CHECK_EQUAL( 5, ecl_kw_iget_int( tabdims , TABDIMS_NPPVTO_ITEM ) );
|
|
|
|
BOOST_CHECK_EQUAL( 1, ecl_kw_iget_int( tabdims , TABDIMS_NTPVTO_ITEM ) );
|
|
|
|
|
|
|
|
BOOST_CHECK_CLOSE(50.0 , ecl_kw_iget_double( tab , offset ), 1e-6 );
|
|
|
|
BOOST_CHECK_CLOSE(1.0 / 1.10615 , ecl_kw_iget_double( tab , offset + column_stride), 1e-6 );
|
|
|
|
BOOST_CHECK_CLOSE(1.18 / 1.10615 , ecl_kw_iget_double( tab , offset + 2*column_stride ), 1e-6 );
|
|
|
|
|
|
|
|
BOOST_CHECK_CLOSE(150.0 , ecl_kw_iget_double( tab , 4 + offset ), 1e-6 );
|
|
|
|
BOOST_CHECK_CLOSE(1.0 / 1.08984 , ecl_kw_iget_double( tab , 4 + offset + column_stride), 1e-6 );
|
|
|
|
BOOST_CHECK_CLOSE(1.453 / 1.08984 , ecl_kw_iget_double( tab , 4 + offset + 2*column_stride ), 1e-6 );
|
|
|
|
|
|
|
|
BOOST_CHECK_CLOSE(20.59 , ecl_kw_iget_double( tab , rs_offset ), 1e-6 );
|
|
|
|
BOOST_CHECK_CLOSE(28.19 , ecl_kw_iget_double( tab , rs_offset + 1), 1e-6 );
|
|
|
|
}
|
2016-11-28 04:37:31 -06:00
|
|
|
|
2016-11-29 07:07:57 -06:00
|
|
|
|
2016-11-28 04:37:31 -06:00
|
|
|
/* PVTG */
|
|
|
|
{
|
2017-10-15 20:55:08 -05:00
|
|
|
int offset = ecl_kw_iget_int( tabdims , TABDIMS_IBPVTG_OFFSET_ITEM ) - 1;
|
|
|
|
int pg_offset = ecl_kw_iget_int( tabdims , TABDIMS_JBPVTG_OFFSET_ITEM ) - 1;
|
2016-11-28 04:37:31 -06:00
|
|
|
int column_stride = ecl_kw_iget_int( tabdims , TABDIMS_NRPVTG_ITEM ) * ecl_kw_iget_int( tabdims , TABDIMS_NPPVTG_ITEM ) * ecl_kw_iget_int( tabdims , TABDIMS_NTPVTG_ITEM );
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL( 2, ecl_kw_iget_int( tabdims , TABDIMS_NRPVTG_ITEM ) );
|
|
|
|
BOOST_CHECK_EQUAL( 3, ecl_kw_iget_int( tabdims , TABDIMS_NPPVTG_ITEM ) );
|
|
|
|
BOOST_CHECK_EQUAL( 1, ecl_kw_iget_int( tabdims , TABDIMS_NTPVTG_ITEM ) );
|
|
|
|
|
|
|
|
BOOST_CHECK_CLOSE(0.00002448 , ecl_kw_iget_double( tab , offset ), 1e-6 );
|
|
|
|
BOOST_CHECK_CLOSE(0.061895 , ecl_kw_iget_double( tab , offset + column_stride), 1e-6 );
|
|
|
|
BOOST_CHECK_CLOSE(0.01299 , ecl_kw_iget_double( tab , offset + 2*column_stride ), 1e-6 );
|
|
|
|
|
|
|
|
BOOST_CHECK_CLOSE(20.0 , ecl_kw_iget_double( tab , pg_offset ), 1e-6 );
|
|
|
|
BOOST_CHECK_CLOSE(40.0 , ecl_kw_iget_double( tab , pg_offset + 1), 1e-6 );
|
|
|
|
}
|
2016-11-29 07:07:57 -06:00
|
|
|
|
|
|
|
|
|
|
|
/* PVTW */
|
|
|
|
{
|
2017-10-15 20:55:08 -05:00
|
|
|
int offset = ecl_kw_iget_int( tabdims , TABDIMS_IBPVTW_OFFSET_ITEM ) - 1;
|
2016-11-29 07:07:57 -06:00
|
|
|
int column_stride = ecl_kw_iget_int( tabdims , TABDIMS_NTPVTW_ITEM );
|
2016-12-23 02:09:31 -06:00
|
|
|
BOOST_CHECK( ecl_kw_get_size( tab ) >= (offset + column_stride * 5 ));
|
|
|
|
|
|
|
|
BOOST_CHECK_CLOSE( 247.7 , ecl_kw_iget_double( tab , offset ) , 1e-6 );
|
|
|
|
BOOST_CHECK_CLOSE( 1.0 / 1.03665 , ecl_kw_iget_double( tab , offset + column_stride), 1e-6);
|
|
|
|
BOOST_CHECK_CLOSE( 0.41726E-04 , ecl_kw_iget_double( tab , offset + 2 * column_stride), 1e-6);
|
|
|
|
BOOST_CHECK_CLOSE( 1.03665 / 0.29120 , ecl_kw_iget_double( tab , offset + 3 * column_stride), 1e-6);
|
2016-11-29 07:07:57 -06:00
|
|
|
|
2016-12-23 02:09:31 -06:00
|
|
|
// For the last column - WATER_VISCOSIBILITY - there is
|
2016-11-29 07:07:57 -06:00
|
|
|
// clearly a transform involved; not really clear which
|
|
|
|
// transform this is. This column is therefor not tested.
|
2016-12-23 02:09:31 -06:00
|
|
|
|
|
|
|
// BOOST_CHECK_CLOSE( f(0.99835E-04) , ecl_kw_iget_double( tab , offset + 4 * column_stride), 1e-6);
|
2016-11-29 07:07:57 -06:00
|
|
|
}
|
2016-12-23 02:09:31 -06:00
|
|
|
|
|
|
|
// Density
|
|
|
|
{
|
2017-10-15 20:55:08 -05:00
|
|
|
int offset = ecl_kw_iget_int( tabdims , TABDIMS_IBDENS_OFFSET_ITEM ) - 1;
|
2016-12-23 02:09:31 -06:00
|
|
|
int column_stride = ecl_kw_iget_int( tabdims , TABDIMS_NTDENS_ITEM );
|
|
|
|
BOOST_CHECK( ecl_kw_get_size( tab ) >= (offset + column_stride * 3 ));
|
|
|
|
BOOST_CHECK_CLOSE( 859.5 , ecl_kw_iget_double( tab , offset ) , 1e-6 );
|
|
|
|
BOOST_CHECK_CLOSE( 1033 , ecl_kw_iget_double( tab , offset + 1 ) , 1e-6 );
|
|
|
|
BOOST_CHECK_CLOSE( 0.854 , ecl_kw_iget_double( tab , offset + 2) , 1e-6 );
|
|
|
|
}
|
|
|
|
|
2016-11-16 09:12:59 -06:00
|
|
|
ecl_file_close( f );
|
|
|
|
}
|
|
|
|
}
|
INIT File: Add Support for Writing Saturation Function Tables
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.
2017-11-16 09:34:05 -06:00
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE_END ()
|
|
|
|
|
|
|
|
// #####################################################################
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE (Two_Phase)
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE (Oil_Water_Family_One)
|
|
|
|
{
|
|
|
|
const auto es = SPE9::TwoPhase::OilWater::satfuncTables();
|
|
|
|
|
|
|
|
auto tables = Opm::Tables{ es.getUnits() };
|
|
|
|
tables.addSatFunc(es);
|
|
|
|
|
|
|
|
const auto& tabdims = tables.tabdims();
|
|
|
|
const auto& tab = tables.tab();
|
|
|
|
|
|
|
|
// SOFN
|
|
|
|
{
|
|
|
|
const auto ibsofn = tabdims[ TABDIMS_IBSOFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nssofn = tabdims[ TABDIMS_NSSOFN_ITEM ];
|
|
|
|
const auto ntsofn = tabdims[ TABDIMS_NTSOFN_ITEM ];
|
|
|
|
const auto ncol = 3;
|
|
|
|
|
|
|
|
const auto sofn = std::vector<double> {
|
|
|
|
&tab[ ibsofn ] + 0,
|
|
|
|
&tab[ ibsofn ] + ntsofn*nssofn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nssofn, 30);
|
|
|
|
BOOST_CHECK_EQUAL(ntsofn, 1);
|
|
|
|
|
|
|
|
check_is_close(sofn, SPE9::TwoPhase::OilWater::expect_SOFN());
|
|
|
|
}
|
|
|
|
|
|
|
|
// SWFN
|
|
|
|
{
|
|
|
|
const auto ibswfn = tabdims[ TABDIMS_IBSWFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nsswfn = tabdims[ TABDIMS_NSSWFN_ITEM ];
|
|
|
|
const auto ntswfn = tabdims[ TABDIMS_NTSWFN_ITEM ];
|
|
|
|
const auto ncol = 5;
|
|
|
|
|
|
|
|
const auto swfn = std::vector<double> {
|
|
|
|
&tab[ ibswfn ] + 0,
|
|
|
|
&tab[ ibswfn ] + ntswfn*nsswfn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nsswfn, 30);
|
|
|
|
BOOST_CHECK_EQUAL(ntswfn, 1);
|
|
|
|
|
|
|
|
check_is_close(swfn, SPE9::TwoPhase::OilWater::expect_SWFN());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE (Oil_Water_Family_Two)
|
|
|
|
{
|
|
|
|
const auto es = SPE1::TwoPhase::OilWater::satfuncTables();
|
|
|
|
|
|
|
|
auto tables = Opm::Tables{ es.getUnits() };
|
|
|
|
tables.addSatFunc(es);
|
|
|
|
|
|
|
|
const auto& tabdims = tables.tabdims();
|
|
|
|
const auto& tab = tables.tab();
|
|
|
|
|
|
|
|
// SOFN
|
|
|
|
{
|
|
|
|
const auto ibsofn = tabdims[ TABDIMS_IBSOFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nssofn = tabdims[ TABDIMS_NSSOFN_ITEM ];
|
|
|
|
const auto ntsofn = tabdims[ TABDIMS_NTSOFN_ITEM ];
|
|
|
|
const auto ncol = 3;
|
|
|
|
|
|
|
|
const auto sofn = std::vector<double> {
|
|
|
|
&tab[ ibsofn ] + 0,
|
|
|
|
&tab[ ibsofn ] + ntsofn*nssofn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nssofn, 20);
|
|
|
|
BOOST_CHECK_EQUAL(ntsofn, 1);
|
|
|
|
|
|
|
|
check_is_close(sofn, SPE1::TwoPhase::OilWater::expect_SOFN());
|
|
|
|
}
|
|
|
|
|
|
|
|
// SWFN
|
|
|
|
{
|
|
|
|
const auto ibswfn = tabdims[ TABDIMS_IBSWFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nsswfn = tabdims[ TABDIMS_NSSWFN_ITEM ];
|
|
|
|
const auto ntswfn = tabdims[ TABDIMS_NTSWFN_ITEM ];
|
|
|
|
const auto ncol = 5;
|
|
|
|
|
|
|
|
const auto swfn = std::vector<double> {
|
|
|
|
&tab[ ibswfn ] + 0,
|
|
|
|
&tab[ ibswfn ] + ntswfn*nsswfn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nsswfn, 20);
|
|
|
|
BOOST_CHECK_EQUAL(ntswfn, 1);
|
|
|
|
|
|
|
|
check_is_close(swfn, SPE1::TwoPhase::OilWater::expect_SWFN());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE (Gas_Oil_Familiy_One)
|
|
|
|
{
|
|
|
|
const auto es = SPE9::TwoPhase::GasOil::satfuncTables();
|
|
|
|
|
|
|
|
auto tables = Opm::Tables{ es.getUnits() };
|
|
|
|
tables.addSatFunc(es);
|
|
|
|
|
|
|
|
const auto& tabdims = tables.tabdims();
|
|
|
|
const auto& tab = tables.tab();
|
|
|
|
|
|
|
|
// SGFN
|
|
|
|
{
|
|
|
|
const auto ibsgfn = tabdims[ TABDIMS_IBSGFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nssgfn = tabdims[ TABDIMS_NSSGFN_ITEM ];
|
|
|
|
const auto ntsgfn = tabdims[ TABDIMS_NTSGFN_ITEM ];
|
|
|
|
const auto ncol = 5;
|
|
|
|
|
|
|
|
const auto sgfn = std::vector<double> {
|
|
|
|
&tab[ ibsgfn ] + 0,
|
|
|
|
&tab[ ibsgfn ] + ntsgfn*nssgfn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nssgfn, 30);
|
|
|
|
BOOST_CHECK_EQUAL(ntsgfn, 1);
|
|
|
|
|
|
|
|
check_is_close(sgfn, SPE9::TwoPhase::GasOil::expect_SGFN());
|
|
|
|
}
|
|
|
|
|
|
|
|
// SOFN
|
|
|
|
{
|
|
|
|
const auto ibsofn = tabdims[ TABDIMS_IBSOFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nssofn = tabdims[ TABDIMS_NSSOFN_ITEM ];
|
|
|
|
const auto ntsofn = tabdims[ TABDIMS_NTSOFN_ITEM ];
|
|
|
|
const auto ncol = 3;
|
|
|
|
|
|
|
|
const auto sofn = std::vector<double> {
|
|
|
|
&tab[ ibsofn ] + 0,
|
|
|
|
&tab[ ibsofn ] + ntsofn*nssofn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nssofn, 30);
|
|
|
|
BOOST_CHECK_EQUAL(ntsofn, 1);
|
|
|
|
|
|
|
|
check_is_close(sofn, SPE9::TwoPhase::GasOil::expect_SOFN());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE (Gas_Oil_Familiy_Two)
|
|
|
|
{
|
|
|
|
const auto es = SPE1::TwoPhase::GasOil::satfuncTables();
|
|
|
|
|
|
|
|
auto tables = Opm::Tables{ es.getUnits() };
|
|
|
|
tables.addSatFunc(es);
|
|
|
|
|
|
|
|
const auto& tabdims = tables.tabdims();
|
|
|
|
const auto& tab = tables.tab();
|
|
|
|
|
|
|
|
// SGFN
|
|
|
|
{
|
|
|
|
const auto ibsgfn = tabdims[ TABDIMS_IBSGFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nssgfn = tabdims[ TABDIMS_NSSGFN_ITEM ];
|
|
|
|
const auto ntsgfn = tabdims[ TABDIMS_NTSGFN_ITEM ];
|
|
|
|
const auto ncol = 5;
|
|
|
|
|
|
|
|
const auto sgfn = std::vector<double> {
|
|
|
|
&tab[ ibsgfn ] + 0,
|
|
|
|
&tab[ ibsgfn ] + ntsgfn*nssgfn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nssgfn, 20);
|
|
|
|
BOOST_CHECK_EQUAL(ntsgfn, 1);
|
|
|
|
|
|
|
|
check_is_close(sgfn, SPE1::TwoPhase::GasOil::expect_SGFN());
|
|
|
|
}
|
|
|
|
|
|
|
|
// SOFN
|
|
|
|
{
|
|
|
|
const auto ibsofn = tabdims[ TABDIMS_IBSOFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nssofn = tabdims[ TABDIMS_NSSOFN_ITEM ];
|
|
|
|
const auto ntsofn = tabdims[ TABDIMS_NTSOFN_ITEM ];
|
|
|
|
const auto ncol = 3;
|
|
|
|
|
|
|
|
const auto sofn = std::vector<double> {
|
|
|
|
&tab[ ibsofn ] + 0,
|
|
|
|
&tab[ ibsofn ] + ntsofn*nssofn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nssofn, 20);
|
|
|
|
BOOST_CHECK_EQUAL(ntsofn, 1);
|
|
|
|
|
|
|
|
check_is_close(sofn, SPE1::TwoPhase::GasOil::expect_SOFN());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE_END ()
|
|
|
|
|
|
|
|
// #####################################################################
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE (Three_Phase)
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE (Serialize_Family_One)
|
|
|
|
{
|
|
|
|
const auto es = SPE9::ThreePhase::satfuncTables();
|
|
|
|
|
|
|
|
auto tables = Opm::Tables{ es.getUnits() };
|
|
|
|
tables.addSatFunc(es);
|
|
|
|
|
|
|
|
const auto& tabdims = tables.tabdims();
|
|
|
|
const auto& tab = tables.tab();
|
|
|
|
|
|
|
|
// SGFN
|
|
|
|
{
|
|
|
|
const auto ibsgfn = tabdims[ TABDIMS_IBSGFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nssgfn = tabdims[ TABDIMS_NSSGFN_ITEM ];
|
|
|
|
const auto ntsgfn = tabdims[ TABDIMS_NTSGFN_ITEM ];
|
|
|
|
const auto ncol = 5;
|
|
|
|
|
|
|
|
const auto sgfn = std::vector<double> {
|
|
|
|
&tab[ ibsgfn ] + 0,
|
|
|
|
&tab[ ibsgfn ] + ntsgfn*nssgfn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nssgfn, 30);
|
|
|
|
BOOST_CHECK_EQUAL(ntsgfn, 1);
|
|
|
|
|
|
|
|
check_is_close(sgfn, SPE9::ThreePhase::expect_SGFN());
|
|
|
|
}
|
|
|
|
|
|
|
|
// SOFN
|
|
|
|
{
|
|
|
|
const auto ibsofn = tabdims[ TABDIMS_IBSOFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nssofn = tabdims[ TABDIMS_NSSOFN_ITEM ];
|
|
|
|
const auto ntsofn = tabdims[ TABDIMS_NTSOFN_ITEM ];
|
|
|
|
const auto ncol = 5;
|
|
|
|
|
|
|
|
const auto sofn = std::vector<double> {
|
|
|
|
&tab[ ibsofn ] + 0,
|
|
|
|
&tab[ ibsofn ] + ntsofn*nssofn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nssofn, 2 * 30);
|
|
|
|
BOOST_CHECK_EQUAL(ntsofn, 1);
|
|
|
|
|
|
|
|
check_is_close(sofn, SPE9::ThreePhase::expect_SOFN());
|
|
|
|
}
|
|
|
|
|
|
|
|
// SWFN
|
|
|
|
{
|
|
|
|
const auto ibswfn = tabdims[ TABDIMS_IBSWFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nsswfn = tabdims[ TABDIMS_NSSWFN_ITEM ];
|
|
|
|
const auto ntswfn = tabdims[ TABDIMS_NTSWFN_ITEM ];
|
|
|
|
const auto ncol = 5;
|
|
|
|
|
|
|
|
const auto swfn = std::vector<double> {
|
|
|
|
&tab[ ibswfn ] + 0,
|
|
|
|
&tab[ ibswfn ] + ntswfn*nsswfn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nsswfn, 30);
|
|
|
|
BOOST_CHECK_EQUAL(ntswfn, 1);
|
|
|
|
|
|
|
|
check_is_close(swfn, SPE9::ThreePhase::expect_SWFN());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE (Serialize_Family_Two)
|
|
|
|
{
|
|
|
|
const auto es = SPE1::ThreePhase::satfuncTables();
|
|
|
|
|
|
|
|
auto tables = Opm::Tables{ es.getUnits() };
|
|
|
|
tables.addSatFunc(es);
|
|
|
|
|
|
|
|
const auto& tabdims = tables.tabdims();
|
|
|
|
const auto& tab = tables.tab();
|
|
|
|
|
|
|
|
// SGFN
|
|
|
|
{
|
|
|
|
const auto ibsgfn = tabdims[ TABDIMS_IBSGFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nssgfn = tabdims[ TABDIMS_NSSGFN_ITEM ];
|
|
|
|
const auto ntsgfn = tabdims[ TABDIMS_NTSGFN_ITEM ];
|
|
|
|
const auto ncol = 5;
|
|
|
|
|
|
|
|
const auto sgfn = std::vector<double> {
|
|
|
|
&tab[ ibsgfn ] + 0,
|
|
|
|
&tab[ ibsgfn ] + ntsgfn*nssgfn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nssgfn, 20);
|
|
|
|
BOOST_CHECK_EQUAL(ntsgfn, 1);
|
|
|
|
|
|
|
|
check_is_close(sgfn, SPE1::ThreePhase::expect_SGFN());
|
|
|
|
}
|
|
|
|
|
|
|
|
// SOFN
|
|
|
|
{
|
|
|
|
const auto ibsofn = tabdims[ TABDIMS_IBSOFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nssofn = tabdims[ TABDIMS_NSSOFN_ITEM ];
|
|
|
|
const auto ntsofn = tabdims[ TABDIMS_NTSOFN_ITEM ];
|
|
|
|
const auto ncol = 5;
|
|
|
|
|
|
|
|
const auto sofn = std::vector<double> {
|
|
|
|
&tab[ ibsofn ] + 0,
|
|
|
|
&tab[ ibsofn ] + ntsofn*nssofn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nssofn, 20);
|
|
|
|
BOOST_CHECK_EQUAL(ntsofn, 1);
|
|
|
|
|
|
|
|
check_is_close(sofn, SPE1::ThreePhase::expect_SOFN());
|
|
|
|
}
|
|
|
|
|
|
|
|
// SWFN
|
|
|
|
{
|
|
|
|
const auto ibswfn = tabdims[ TABDIMS_IBSWFN_OFFSET_ITEM ] - 1;
|
|
|
|
const auto nsswfn = tabdims[ TABDIMS_NSSWFN_ITEM ];
|
|
|
|
const auto ntswfn = tabdims[ TABDIMS_NTSWFN_ITEM ];
|
|
|
|
const auto ncol = 5;
|
|
|
|
|
|
|
|
const auto swfn = std::vector<double> {
|
|
|
|
&tab[ ibswfn ] + 0,
|
|
|
|
&tab[ ibswfn ] + ntswfn*nsswfn*ncol
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(nsswfn, 20);
|
|
|
|
BOOST_CHECK_EQUAL(ntswfn, 1);
|
|
|
|
|
|
|
|
check_is_close(swfn, SPE1::ThreePhase::expect_SWFN());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE_END ()
|