diff --git a/opm/input/eclipse/EclipseState/Tables/PvtgTable.hpp b/opm/input/eclipse/EclipseState/Tables/PvtgTable.hpp
index 447f0ab7239..689441f9df4 100644
--- a/opm/input/eclipse/EclipseState/Tables/PvtgTable.hpp
+++ b/opm/input/eclipse/EclipseState/Tables/PvtgTable.hpp
@@ -15,25 +15,38 @@
You should have received a copy of the GNU General Public License
along with OPM. If not, see .
- */
+*/
+
#ifndef OPM_PARSER_PVTG_TABLE_HPP
-#define OPM_PARSER_PVTG_TABLE_HPP
+#define OPM_PARSER_PVTG_TABLE_HPP
#include
+#include
+
namespace Opm {
class DeckKeyword;
- class PvtgTable : public PvtxTable {
+} // namespace Opm
+
+namespace Opm {
+
+ class PvtgTable : public PvtxTable
+ {
public:
PvtgTable() = default;
- PvtgTable( const DeckKeyword& keyword, size_t tableIdx);
+ PvtgTable(const DeckKeyword& keyword, std::size_t tableIdx);
static PvtgTable serializationTestObject();
bool operator==(const PvtgTable& data) const;
+
+ private:
+ void makeScaledUSatTableCopy(const std::size_t src,
+ const std::size_t dest) override;
};
-}
-#endif
+} // namespace Opm
+
+#endif // OPM_PARSER_PVTG_TABLE_HPP
diff --git a/opm/input/eclipse/EclipseState/Tables/PvtgwTable.hpp b/opm/input/eclipse/EclipseState/Tables/PvtgwTable.hpp
index a891424dfb8..d1e84b1efe8 100644
--- a/opm/input/eclipse/EclipseState/Tables/PvtgwTable.hpp
+++ b/opm/input/eclipse/EclipseState/Tables/PvtgwTable.hpp
@@ -16,25 +16,38 @@
You should have received a copy of the GNU General Public License
along with OPM. If not, see .
- */
+*/
+
#ifndef OPM_PARSER_PVTGW_TABLE_HPP
-#define OPM_PARSER_PVTGW_TABLE_HPP
+#define OPM_PARSER_PVTGW_TABLE_HPP
#include
+#include
+
namespace Opm {
class DeckKeyword;
- class PvtgwTable : public PvtxTable {
+} // namespace Opm
+
+namespace Opm {
+
+ class PvtgwTable : public PvtxTable
+ {
public:
PvtgwTable() = default;
- PvtgwTable( const DeckKeyword& keyword, size_t tableIdx);
+ PvtgwTable(const DeckKeyword& keyword, const std::size_t tableIdx);
static PvtgwTable serializationTestObject();
bool operator==(const PvtgwTable& data) const;
+
+ private:
+ void makeScaledUSatTableCopy(const std::size_t src,
+ const std::size_t dest) override;
};
-}
-#endif
+} // namespace Opm
+
+#endif // OPM_PARSER_PVTGW_TABLE_HPP
diff --git a/opm/input/eclipse/EclipseState/Tables/PvtgwoTable.hpp b/opm/input/eclipse/EclipseState/Tables/PvtgwoTable.hpp
index faec0f58f04..a1448857fcd 100644
--- a/opm/input/eclipse/EclipseState/Tables/PvtgwoTable.hpp
+++ b/opm/input/eclipse/EclipseState/Tables/PvtgwoTable.hpp
@@ -16,25 +16,38 @@
You should have received a copy of the GNU General Public License
along with OPM. If not, see .
- */
+*/
+
#ifndef OPM_PARSER_PVTGWO_TABLE_HPP
-#define OPM_PARSER_PVTGWO_TABLE_HPP
+#define OPM_PARSER_PVTGWO_TABLE_HPP
#include
+#include
+
namespace Opm {
class DeckKeyword;
- class PvtgwoTable : public PvtxTable {
+} // namespaced Opm
+
+namespace Opm {
+
+ class PvtgwoTable : public PvtxTable
+ {
public:
PvtgwoTable() = default;
- PvtgwoTable( const DeckKeyword& keyword, size_t tableIdx);
+ PvtgwoTable(const DeckKeyword& keyword, const std::size_t tableIdx);
static PvtgwoTable serializationTestObject();
bool operator==(const PvtgwoTable& data) const;
+
+ private:
+ void makeScaledUSatTableCopy(const std::size_t src,
+ const std::size_t dest) override;
};
-}
-#endif
+} // namespace Opm
+
+#endif // OPM_PARSER_PVTGWO_TABLE_HPP
diff --git a/opm/input/eclipse/EclipseState/Tables/PvtoTable.hpp b/opm/input/eclipse/EclipseState/Tables/PvtoTable.hpp
index 2c85a69cf33..dff4fa00abf 100644
--- a/opm/input/eclipse/EclipseState/Tables/PvtoTable.hpp
+++ b/opm/input/eclipse/EclipseState/Tables/PvtoTable.hpp
@@ -15,7 +15,8 @@
You should have received a copy of the GNU General Public License
along with OPM. If not, see .
- */
+*/
+
#ifndef OPM_PARSER_PVTO_TABLE_HPP
#define OPM_PARSER_PVTO_TABLE_HPP
@@ -29,23 +30,34 @@ namespace Opm {
class DeckKeyword;
- class PvtoTable : public PvtxTable {
+} // namespace Opm
+
+namespace Opm {
+
+ class PvtoTable : public PvtxTable
+ {
public:
- struct FlippedFVF {
+ struct FlippedFVF
+ {
std::size_t i;
std::array Rs;
std::array Bo;
};
PvtoTable() = default;
- PvtoTable(const DeckKeyword& keyword, size_t tableIdx);
+ PvtoTable(const DeckKeyword& keyword, std::size_t tableIdx);
static PvtoTable serializationTestObject();
bool operator==(const PvtoTable& data) const;
std::vector nonMonotonicSaturatedFVF() const;
+
+ private:
+ void makeScaledUSatTableCopy(const std::size_t src,
+ const std::size_t dest) override;
};
-}
-#endif
+} // namespace Opm
+
+#endif // OPM_PARSER_PVTO_TABLE_HPP
diff --git a/opm/input/eclipse/EclipseState/Tables/PvtsolTable.hpp b/opm/input/eclipse/EclipseState/Tables/PvtsolTable.hpp
index a63d816b6c9..264dc7f2a56 100644
--- a/opm/input/eclipse/EclipseState/Tables/PvtsolTable.hpp
+++ b/opm/input/eclipse/EclipseState/Tables/PvtsolTable.hpp
@@ -15,23 +15,37 @@
You should have received a copy of the GNU General Public License
along with OPM. If not, see .
- */
+*/
+
#ifndef OPM_PARSER_PVTSOL_TABLE_HPP
-#define OPM_PARSER_PVTSOL_TABLE_HPP
+#define OPM_PARSER_PVTSOL_TABLE_HPP
#include
+#include
+
namespace Opm {
class DeckKeyword;
- class PvtsolTable : public PvtxTable {
+} // namespace Opm
+
+namespace Opm {
+
+ class PvtsolTable : public PvtxTable
+ {
public:
PvtsolTable() = default;
- PvtsolTable(const DeckKeyword& keyword, size_t tableIdx);
+ PvtsolTable(const DeckKeyword& keyword, const std::size_t tableIdx);
+
static PvtsolTable serializationTestObject();
bool operator==(const PvtsolTable& data) const;
+
+ private:
+ void makeScaledUSatTableCopy(const std::size_t src,
+ const std::size_t dest) override;
};
-}
-#endif
+} // namespace Opm
+
+#endif // OPM_PARSER_PVTSOL_TABLE_HPP
diff --git a/opm/input/eclipse/EclipseState/Tables/PvtxTable.cpp b/opm/input/eclipse/EclipseState/Tables/PvtxTable.cpp
index 57a6cdae852..ed13fbe3e4b 100644
--- a/opm/input/eclipse/EclipseState/Tables/PvtxTable.cpp
+++ b/opm/input/eclipse/EclipseState/Tables/PvtxTable.cpp
@@ -197,6 +197,7 @@ namespace Opm {
ranges[*tableIdx].first,
ranges[*tableIdx].second);
+ this->populateMissingUndersaturatedStates();
this->populateSaturatedTable(keyword.name());
}
@@ -240,4 +241,53 @@ namespace Opm {
}
}
+ void PvtxTable::populateMissingUndersaturatedStates()
+ {
+ for (const auto& [src, dest] : this->missingUSatTables()) {
+ this->makeScaledUSatTableCopy(src, dest);
+ }
+ }
+
+ std::vector>
+ PvtxTable::missingUSatTables() const
+ {
+ auto missing = std::vector>{};
+
+ if (this->m_underSaturatedTables.empty()) {
+ return missing;
+ }
+
+ auto src = this->m_underSaturatedTables.size() - 1;
+
+ for (auto destIx = src + 1; destIx > 0; --destIx) {
+ const auto dest = destIx - 1;
+
+ if (this->m_underSaturatedTables[dest].numRows() > 1) {
+ // There are undersaturated states in 'dest'. This is the
+ // new 'src'.
+ src = dest;
+ }
+ else {
+ // There are no undersaturated states in 'dest'. Schedule
+ // generation of a scaled copy of 'src's undersaturated
+ // states in 'dest'.
+ missing.emplace_back(src, dest);
+ }
+ }
+
+ return missing;
+ }
+
+ void PvtxTable::makeScaledUSatTableCopy([[maybe_unused]] const std::size_t src,
+ [[maybe_unused]] const std::size_t dest)
+ {
+ // Implemented only because we need to be able to create objects of
+ // type 'PvtxTable' for serialisation purposes. Ideally, this would
+ // be a pure virtual function.
+
+ throw std::runtime_error {
+ "Derived type does not implement makeScaledUSatTableCopy()"
+ };
+ }
+
} // namespace Opm
diff --git a/opm/input/eclipse/EclipseState/Tables/PvtxTable.hpp b/opm/input/eclipse/EclipseState/Tables/PvtxTable.hpp
index 8b47c361502..c24e6eea90f 100644
--- a/opm/input/eclipse/EclipseState/Tables/PvtxTable.hpp
+++ b/opm/input/eclipse/EclipseState/Tables/PvtxTable.hpp
@@ -297,6 +297,39 @@ namespace Opm {
/// \param[in] tableName Name of table/keyword we're internalising.
/// Typically \code "PVTO" \endcode or \code "PVTG" \endcode.
void populateSaturatedTable(const std::string& tableName);
+
+ /// Fill in any missing under-saturated states.
+ ///
+ /// Takes scaled copies of under-saturated curves at higher
+ /// composition/pressure nodes. Amends m_underSaturatedTables.
+ void populateMissingUndersaturatedStates();
+
+ /// Identify missing under-saturated states in
+ /// m_underSaturatedTables.
+ ///
+ /// \return Pairs of source/destination indices. The
+ /// under-saturated destination entries in m_underSaturatedTables
+ /// will be scaled copies of the under-saturated source entries in
+ /// m_underSaturatedTables.
+ std::vector>
+ missingUSatTables() const;
+
+ /// Generate scaled copies of under-saturated state curves.
+ ///
+ /// Intended to amend a specific entry in m_underSaturatedTables
+ /// based on source values in another specific entry in
+ /// m_underSaturatedTables.
+ ///
+ /// Virtual function in order to call back into the derived type for
+ /// type-specific copying.
+ ///
+ /// \param[in] src Index of source table with full set of
+ /// under-saturated states.
+ ///
+ /// \param[in] dest Index of destination table with no
+ /// under-saturated states.
+ virtual void makeScaledUSatTableCopy(const std::size_t src,
+ const std::size_t dest);
};
} // namespace Opm
diff --git a/opm/input/eclipse/EclipseState/Tables/RwgsaltTable.hpp b/opm/input/eclipse/EclipseState/Tables/RwgsaltTable.hpp
index 8acde25a1de..043256767d3 100644
--- a/opm/input/eclipse/EclipseState/Tables/RwgsaltTable.hpp
+++ b/opm/input/eclipse/EclipseState/Tables/RwgsaltTable.hpp
@@ -16,25 +16,38 @@
You should have received a copy of the GNU General Public License
along with OPM. If not, see .
- */
+*/
+
#ifndef OPM_PARSER_RWGSALT_TABLE_HPP
-#define OPM_PARSER_RWGSALT_TABLE_HPP
+#define OPM_PARSER_RWGSALT_TABLE_HPP
#include
+#include
+
namespace Opm {
class DeckKeyword;
-class RwgsaltTable : public PvtxTable {
+} // namespace Opm
+
+namespace Opm {
+
+class RwgsaltTable : public PvtxTable
+{
public:
RwgsaltTable() = default;
- RwgsaltTable( const DeckKeyword& keyword, size_t tableIdx);
+ RwgsaltTable(const DeckKeyword& keyword, std::size_t tableIdx);
static RwgsaltTable serializationTestObject();
bool operator==(const RwgsaltTable& data) const;
+
+private:
+ void makeScaledUSatTableCopy(const std::size_t src,
+ const std::size_t dest) override;
};
-}
-#endif
+} // namespace Opm
+
+#endif // OPM_PARSER_RWGSALT_TABLE_HPP
diff --git a/opm/input/eclipse/EclipseState/Tables/Tables.cpp b/opm/input/eclipse/EclipseState/Tables/Tables.cpp
index ef57f03c3a4..bf9df764300 100644
--- a/opm/input/eclipse/EclipseState/Tables/Tables.cpp
+++ b/opm/input/eclipse/EclipseState/Tables/Tables.cpp
@@ -109,6 +109,7 @@
#include
#include
+#include
#include
#include
#include
@@ -404,6 +405,48 @@ namespace {
return this->satTable_.get().getColumn(1)[row];
}
+ void makeScaledUSatTableCopy(const std::string& tableName,
+ const Opm::SimpleTable& src,
+ Opm::SimpleTable& dst)
+ {
+ const auto ncol = dst.numColumns();
+
+ assert (src.numColumns() == ncol);
+
+ auto rows = std::array {
+ // Current row values and row values being prepared for next
+ // addRow() call. Role switches between the two, thus enabling
+ // the "next" row to become the current row in the subsequent
+ // iteration. This means we compute each row's values exactly
+ // once.
+ std::vector(ncol),
+ std::vector(ncol)
+ };
+
+ auto curr = 0*rows.size();
+
+ for (auto col = 0*ncol; col < ncol; ++col) {
+ rows[curr][col] = dst.get(col, 0);
+ }
+
+ for (auto row = 1 + 0*src.numRows(); row < src.numRows(); ++row) {
+ const auto next = 1 - curr; // => 1, 0, 1, 0, 1, ...
+
+ // Primary variable. Linear.
+ rows[next][0] = rows[curr][0] + src.get(0, row) - src.get(0, row - 1);
+
+ // FVF, viscosity &c. Scaled copy.
+ for (auto col = 1 + 0*ncol; col < ncol; ++col) {
+ const auto scale = rows[curr][col] / src.get(col, row - 1);
+ rows[next][col] = scale * src.get(col, row);
+ }
+
+ dst.addRow(rows[next], tableName);
+
+ curr = next;
+ }
+ }
+
} // Anonymous namespace
namespace Opm
@@ -562,7 +605,18 @@ PvtgTable::operator==(const PvtgTable& data) const
return static_cast(*this) == static_cast(data);
}
-PvtgwTable::PvtgwTable(const DeckKeyword& keyword, size_t tableIdx)
+void PvtgTable::makeScaledUSatTableCopy(const std::size_t src,
+ const std::size_t dest)
+{
+ assert (dest < src);
+ assert (this->m_underSaturatedTables[dest].numRows() == 1);
+
+ ::makeScaledUSatTableCopy("PVTG",
+ this->m_underSaturatedTables[src],
+ this->m_underSaturatedTables[dest]);
+}
+
+PvtgwTable::PvtgwTable(const DeckKeyword& keyword, const std::size_t tableIdx)
: PvtxTable("P")
{
m_underSaturatedSchema.addColumn(ColumnSchema("RW", Table::STRICTLY_DECREASING, Table::DEFAULT_NONE));
@@ -592,7 +646,11 @@ PvtgwTable::operator==(const PvtgwTable& data) const
return static_cast(*this) == static_cast(data);
}
-PvtgwoTable::PvtgwoTable(const DeckKeyword& keyword, size_t tableIdx)
+void PvtgwTable::makeScaledUSatTableCopy([[maybe_unused]] const std::size_t src,
+ [[maybe_unused]] const std::size_t dest)
+{}
+
+PvtgwoTable::PvtgwoTable(const DeckKeyword& keyword, const std::size_t tableIdx)
: PvtxTable("P")
{
@@ -625,7 +683,11 @@ PvtgwoTable::operator==(const PvtgwoTable& data) const
return static_cast(*this) == static_cast(data);
}
-PvtoTable::PvtoTable(const DeckKeyword& keyword, size_t tableIdx)
+void PvtgwoTable::makeScaledUSatTableCopy([[maybe_unused]] const std::size_t src,
+ [[maybe_unused]] const std::size_t dest)
+{}
+
+PvtoTable::PvtoTable(const DeckKeyword& keyword, const std::size_t tableIdx)
: PvtxTable("RS")
{
m_underSaturatedSchema.addColumn(ColumnSchema("P", Table::STRICTLY_INCREASING, Table::DEFAULT_NONE));
@@ -682,7 +744,18 @@ PvtoTable::nonMonotonicSaturatedFVF() const
return nonmonoFVF;
}
-PvtsolTable::PvtsolTable(const DeckKeyword& keyword, size_t tableIdx)
+void PvtoTable::makeScaledUSatTableCopy(const std::size_t src,
+ const std::size_t dest)
+{
+ assert (dest < src);
+ assert (this->m_underSaturatedTables[dest].numRows() == 1);
+
+ ::makeScaledUSatTableCopy("PVTO",
+ this->m_underSaturatedTables[src],
+ this->m_underSaturatedTables[dest]);
+}
+
+PvtsolTable::PvtsolTable(const DeckKeyword& keyword, const std::size_t tableIdx)
: PvtxTable("ZCO2")
{
m_underSaturatedSchema.addColumn(ColumnSchema("P", Table::STRICTLY_INCREASING, Table::DEFAULT_NONE));
@@ -724,10 +797,13 @@ PvtsolTable::operator==(const PvtsolTable& data) const
return static_cast(*this) == static_cast(data);
}
+void PvtsolTable::makeScaledUSatTableCopy([[maybe_unused]] const std::size_t src,
+ [[maybe_unused]] const std::size_t dest)
+{}
+
RwgsaltTable::RwgsaltTable(const DeckKeyword& keyword, size_t tableIdx)
: PvtxTable("P")
{
-
m_underSaturatedSchema.addColumn(ColumnSchema("C_SALT", Table::INCREASING, Table::DEFAULT_NONE));
m_underSaturatedSchema.addColumn(ColumnSchema("RVW", Table::RANDOM, Table::DEFAULT_LINEAR));
@@ -753,6 +829,10 @@ RwgsaltTable::operator==(const RwgsaltTable& data) const
return static_cast(*this) == static_cast(data);
}
+void RwgsaltTable::makeScaledUSatTableCopy([[maybe_unused]] const std::size_t src,
+ [[maybe_unused]] const std::size_t dest)
+{}
+
SpecheatTable::SpecheatTable(const DeckItem& item, const int tableID)
{
m_schema.addColumn(ColumnSchema("TEMPERATURE", Table::STRICTLY_INCREASING, Table::DEFAULT_NONE));
diff --git a/tests/parser/TableManagerTests.cpp b/tests/parser/TableManagerTests.cpp
index 345ee7fbdf6..d268a1e9d41 100644
--- a/tests/parser/TableManagerTests.cpp
+++ b/tests/parser/TableManagerTests.cpp
@@ -1009,6 +1009,108 @@ END
}
}
+BOOST_AUTO_TEST_CASE(PvtoTable_Tests_PopulateUSat) {
+ // PVT tables from opm-tests/model5/include/pvt_live_oil_dgas.ecl .
+ const auto deck = Opm::Parser{}.parseString(R"(RUNSPEC
+OIL
+GAS
+TABDIMS
+1 1 /
+PROPS
+DENSITY
+ 924.1 1026.0 1.03446 /
+PVTO
+-- Table number: 1
+ 3.9140 10.000 1.102358 2.8625 /
+
+ 7.0500 15.000 1.112540 2.6589
+ 25.000 1.111313 2.7221
+ 45.000 1.108952 2.8374 /
+/
+END
+)");
+
+ const auto tmgr = Opm::TableManager { deck };
+ const auto& pvto = tmgr.getPvtoTables();
+ BOOST_REQUIRE_EQUAL(pvto.size(), std::size_t{1});
+
+ {
+ const auto& t1 = pvto[0];
+
+ BOOST_REQUIRE_EQUAL(t1.size(), std::size_t{2});
+
+ const auto& satTbl = t1.getSaturatedTable();
+ {
+ BOOST_REQUIRE_EQUAL(satTbl.numRows(), std::size_t{2});
+ BOOST_REQUIRE_EQUAL(satTbl.numColumns(), std::size_t{4});
+
+ const auto& rs = satTbl.getColumn(0);
+ BOOST_CHECK_CLOSE(rs[0], 3.914, 1.0e-8);
+ BOOST_CHECK_CLOSE(rs[1], 7.05, 1.0e-8);
+
+ const auto& p = satTbl.getColumn(1);
+ BOOST_CHECK_CLOSE(p[0], 1.0e6, 1.0e-8);
+ BOOST_CHECK_CLOSE(p[1], 1.5e6, 1.0e-8);
+
+ const auto& B = satTbl.getColumn(2);
+ BOOST_CHECK_CLOSE(B[0], 1.102358, 1.0e-8);
+ BOOST_CHECK_CLOSE(B[1], 1.11254, 1.0e-8);
+
+ const auto& mu = satTbl.getColumn(3);
+ BOOST_CHECK_CLOSE(mu[0], 2.8625e-3, 1.0e-8);
+ BOOST_CHECK_CLOSE(mu[1], 2.6589e-3, 1.0e-8);
+ }
+
+ {
+ const auto& u1 = t1.getUnderSaturatedTable(0);
+ BOOST_REQUIRE_EQUAL(u1.numRows(), std::size_t{3});
+ BOOST_REQUIRE_EQUAL(u1.numColumns(), std::size_t{3});
+
+ const auto& p = u1.getColumn(0);
+ BOOST_REQUIRE_EQUAL(p.size(), std::size_t{3});
+ BOOST_CHECK_CLOSE(p[0], 1.0e6, 1.0e-8);
+ BOOST_CHECK_CLOSE(p[1], 2.0e6, 1.0e-8);
+ BOOST_CHECK_CLOSE(p[2], 4.0e6, 1.0e-8);
+
+ const auto& B = u1.getColumn(1);
+ BOOST_REQUIRE_EQUAL(B.size(), std::size_t{3});
+ BOOST_CHECK_CLOSE(B[0], 1.102358, 1.0e-8);
+ BOOST_CHECK_CLOSE(B[1], 1.101142, 3.0e-5);
+ BOOST_CHECK_CLOSE(B[2], 1.098803, 2.0e-5);
+
+ const auto& mu = u1.getColumn(2);
+ BOOST_REQUIRE_EQUAL(mu.size(), std::size_t{3});
+ BOOST_CHECK_CLOSE(mu[0], 2.8625e-3, 1.0e-8);
+ BOOST_CHECK_CLOSE(mu[1], 2.9305e-3, 1.4e-3);
+ BOOST_CHECK_CLOSE(mu[2], 3.0547e-3, 1.1e-3);
+ }
+
+ {
+ const auto& u2 = t1.getUnderSaturatedTable(1);
+ BOOST_REQUIRE_EQUAL(u2.numRows(), std::size_t{3});
+ BOOST_REQUIRE_EQUAL(u2.numColumns(), std::size_t{3});
+
+ const auto& p = u2.getColumn(0);
+ BOOST_REQUIRE_EQUAL(p.size(), std::size_t{3});
+ BOOST_CHECK_CLOSE(p[0], 1.5e6, 1.0e-8);
+ BOOST_CHECK_CLOSE(p[1], 2.5e6, 1.0e-8);
+ BOOST_CHECK_CLOSE(p[2], 4.5e6, 1.0e-8);
+
+ const auto& B = u2.getColumn(1);
+ BOOST_REQUIRE_EQUAL(B.size(), std::size_t{3});
+ BOOST_CHECK_CLOSE(B[0], 1.112540, 1.0e-8);
+ BOOST_CHECK_CLOSE(B[1], 1.111313, 1.0e-8);
+ BOOST_CHECK_CLOSE(B[2], 1.108952, 1.0e-8);
+
+ const auto& mu = u2.getColumn(2);
+ BOOST_REQUIRE_EQUAL(mu.size(), std::size_t{3});
+ BOOST_CHECK_CLOSE(mu[0], 2.6589e-3, 1.0e-8);
+ BOOST_CHECK_CLOSE(mu[1], 2.7221e-3, 1.0e-8);
+ BOOST_CHECK_CLOSE(mu[2], 2.8374e-3, 1.0e-8);
+ }
+ }
+}
+
BOOST_AUTO_TEST_CASE(PvtgTable_Tests) {
// PVT tables from opm-tests/norne/INCLUDE/PVT/PVT-WET-GAS.INC .
const auto deck = Opm::Parser{}.parseString(R"(RUNSPEC
@@ -1045,8 +1147,9 @@ END
// bar, and one for p=pLim=3.002 bar.
BOOST_REQUIRE_EQUAL(t1.size(), std::size_t{4});
- const auto& satTbl = t1.getSaturatedTable();
{
+ const auto& satTbl = t1.getSaturatedTable();
+
BOOST_REQUIRE_EQUAL(satTbl.numRows(), std::size_t{4});
BOOST_REQUIRE_EQUAL(satTbl.numColumns(), std::size_t{4});
@@ -1078,40 +1181,52 @@ END
{
const auto& u1 = t1.getUnderSaturatedTable(0);
- BOOST_REQUIRE_EQUAL(u1.numRows(), std::size_t{1});
+ BOOST_REQUIRE_EQUAL(u1.numRows(), std::size_t{3});
BOOST_REQUIRE_EQUAL(u1.numColumns(), std::size_t{3});
const auto& rv = u1.getColumn(0);
- BOOST_REQUIRE_EQUAL(rv.size(), std::size_t{1});
- BOOST_CHECK_CLOSE(rv[0], 4.406029e-06, 2.0e-7);
+ BOOST_REQUIRE_EQUAL(rv.size(), std::size_t{3});
+ BOOST_CHECK_CLOSE(rv[0], 4.406029e-06, 2.0e-7);
+ BOOST_CHECK_CLOSE(rv[1], 1.916029e-06, 5.0e-7);
+ BOOST_CHECK_CLOSE(rv[2], -5.639710e-07, 2.0e-6); // <-- Note: Negative
const auto& B = u1.getColumn(1);
- BOOST_REQUIRE_EQUAL(B.size(), std::size_t{1});
+ BOOST_REQUIRE_EQUAL(B.size(), std::size_t{3});
BOOST_CHECK_CLOSE(B[0], 1.1, 1.0e-8);
+ BOOST_CHECK_CLOSE(B[1], 1.1, 1.0e-8);
+ BOOST_CHECK_CLOSE(B[2], 1.1, 1.0e-8);
const auto& mu = u1.getColumn(2);
constexpr auto cP = prefix::centi*unit::Poise;
- BOOST_REQUIRE_EQUAL(mu.size(), std::size_t{1});
+ BOOST_REQUIRE_EQUAL(mu.size(), std::size_t{3});
BOOST_CHECK_CLOSE(mu[0], 2.63557694e-3*cP, 2.0e-8);
+ BOOST_CHECK_CLOSE(mu[1], 2.63374795e-3*cP, 1.0e-7);
+ BOOST_CHECK_CLOSE(mu[2], 2.63374795e-3*cP, 1.0e-7);
}
{
const auto& u2 = t1.getUnderSaturatedTable(1);
- BOOST_REQUIRE_EQUAL(u2.numRows(), std::size_t{1});
+ BOOST_REQUIRE_EQUAL(u2.numRows(), std::size_t{3});
BOOST_REQUIRE_EQUAL(u2.numColumns(), std::size_t{3});
const auto& rv = u2.getColumn(0);
- BOOST_REQUIRE_EQUAL(rv.size(), std::size_t{1});
- BOOST_CHECK_CLOSE(rv[0], 4.406029e-06, 2.0e-7);
+ BOOST_REQUIRE_EQUAL(rv.size(), std::size_t{3});
+ BOOST_CHECK_CLOSE(rv[0], 4.406029e-06, 2.0e-7);
+ BOOST_CHECK_CLOSE(rv[1], 1.916029e-06, 5.0e-7);
+ BOOST_CHECK_CLOSE(rv[2], -5.639710e-07, 2.0e-6); // <-- Note: Negative
const auto& B = u2.getColumn(1);
- BOOST_REQUIRE_EQUAL(B.size(), std::size_t{1});
+ BOOST_REQUIRE_EQUAL(B.size(), std::size_t{3});
BOOST_CHECK_CLOSE(B[0], 1.0, 1.0e-8);
+ BOOST_CHECK_CLOSE(B[1], 1.0, 1.0e-8);
+ BOOST_CHECK_CLOSE(B[2], 1.0, 1.0e-8);
const auto& mu = u2.getColumn(2);
constexpr auto cP = prefix::centi*unit::Poise;
- BOOST_REQUIRE_EQUAL(mu.size(), std::size_t{1});
+ BOOST_REQUIRE_EQUAL(mu.size(), std::size_t{3});
BOOST_CHECK_CLOSE(mu[0], 2.63557694e-3*cP, 2.0e-8);
+ BOOST_CHECK_CLOSE(mu[1], 2.63374795e-3*cP, 1.0e-7);
+ BOOST_CHECK_CLOSE(mu[2], 2.63374795e-3*cP, 1.0e-7);
}
{
@@ -1170,8 +1285,9 @@ END
// bar, and one for p=pLim=3.002 bar.
BOOST_REQUIRE_EQUAL(t2.size(), std::size_t{4});
- const auto& satTbl = t2.getSaturatedTable();
{
+ const auto& satTbl = t2.getSaturatedTable();
+
BOOST_REQUIRE_EQUAL(satTbl.numRows(), std::size_t{4});
BOOST_REQUIRE_EQUAL(satTbl.numColumns(), std::size_t{4});
@@ -1203,40 +1319,52 @@ END
{
const auto& u1 = t2.getUnderSaturatedTable(0);
- BOOST_REQUIRE_EQUAL(u1.numRows(), std::size_t{1});
+ BOOST_REQUIRE_EQUAL(u1.numRows(), std::size_t{3});
BOOST_REQUIRE_EQUAL(u1.numColumns(), std::size_t{3});
const auto& rv = u1.getColumn(0);
- BOOST_REQUIRE_EQUAL(rv.size(), std::size_t{1});
- BOOST_CHECK_CLOSE(rv[0], 4.406029e-06, 2.0e-7);
+ BOOST_REQUIRE_EQUAL(rv.size(), std::size_t{3});
+ BOOST_CHECK_CLOSE(rv[0], 4.406029e-06, 2.0e-7);
+ BOOST_CHECK_CLOSE(rv[1], 1.916029e-06, 5.0e-7);
+ BOOST_CHECK_CLOSE(rv[2], -5.639710e-07, 2.0e-6); // <-- Note: Negative
const auto& B = u1.getColumn(1);
- BOOST_REQUIRE_EQUAL(B.size(), std::size_t{1});
+ BOOST_REQUIRE_EQUAL(B.size(), std::size_t{3});
BOOST_CHECK_CLOSE(B[0], 1.1, 1.0e-8);
+ BOOST_CHECK_CLOSE(B[1], 1.1, 1.0e-8);
+ BOOST_CHECK_CLOSE(B[2], 1.1, 1.0e-8);
const auto& mu = u1.getColumn(2);
constexpr auto cP = prefix::centi*unit::Poise;
- BOOST_REQUIRE_EQUAL(mu.size(), std::size_t{1});
+ BOOST_REQUIRE_EQUAL(mu.size(), std::size_t{3});
BOOST_CHECK_CLOSE(mu[0], 2.63557694e-3*cP, 2.0e-8);
+ BOOST_CHECK_CLOSE(mu[1], 2.63374795e-3*cP, 1.0e-7);
+ BOOST_CHECK_CLOSE(mu[2], 2.63374795e-3*cP, 1.0e-7);
}
{
const auto& u2 = t2.getUnderSaturatedTable(1);
- BOOST_REQUIRE_EQUAL(u2.numRows(), std::size_t{1});
+ BOOST_REQUIRE_EQUAL(u2.numRows(), std::size_t{3});
BOOST_REQUIRE_EQUAL(u2.numColumns(), std::size_t{3});
const auto& rv = u2.getColumn(0);
- BOOST_REQUIRE_EQUAL(rv.size(), std::size_t{1});
- BOOST_CHECK_CLOSE(rv[0], 4.406029e-06, 2.0e-7);
+ BOOST_REQUIRE_EQUAL(rv.size(), std::size_t{3});
+ BOOST_CHECK_CLOSE(rv[0], 4.406029e-06, 2.0e-7);
+ BOOST_CHECK_CLOSE(rv[1], 1.916029e-06, 5.0e-7);
+ BOOST_CHECK_CLOSE(rv[2], -5.639710e-07, 2.0e-6); // <-- Note: Negative
const auto& B = u2.getColumn(1);
- BOOST_REQUIRE_EQUAL(B.size(), std::size_t{1});
+ BOOST_REQUIRE_EQUAL(B.size(), std::size_t{3});
BOOST_CHECK_CLOSE(B[0], 1.0, 1.0e-8);
+ BOOST_CHECK_CLOSE(B[1], 1.0, 1.0e-8);
+ BOOST_CHECK_CLOSE(B[2], 1.0, 1.0e-8);
const auto& mu = u2.getColumn(2);
constexpr auto cP = prefix::centi*unit::Poise;
- BOOST_REQUIRE_EQUAL(mu.size(), std::size_t{1});
+ BOOST_REQUIRE_EQUAL(mu.size(), std::size_t{3});
BOOST_CHECK_CLOSE(mu[0], 2.63557694e-3*cP, 2.0e-8);
+ BOOST_CHECK_CLOSE(mu[1], 2.63374795e-3*cP, 1.0e-7);
+ BOOST_CHECK_CLOSE(mu[2], 2.63374795e-3*cP, 1.0e-7);
}
{
diff --git a/tests/test_Tables.cpp b/tests/test_Tables.cpp
index 06a79e330c6..c55e3f608fa 100644
--- a/tests/test_Tables.cpp
+++ b/tests/test_Tables.cpp
@@ -2187,12 +2187,12 @@ PVTG
//
// Table 1 (Pg 1, 1 barsa, padding value)
1.463987928388746e-04, 0.90909090909090906 , 1.061101444733158e+02, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ 6.398792838874646e-06, 0.91258070144826386 , 1.047272673828073e+02, -2.492708826682003e+01, 9.877693503632658e+03,
// Table 1 (Pg 2, pLim, padding value) ---------------------------------------------------------------------------------------
1.463987928388746e-04, 1.0 , 1.167211589206474e+02, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ 6.398792838874646e-06, 1.0038387715930901 , 1.151999941210880e+02, -2.741979709350069e+01, 1.086546285399603e+04,
// Table 1 (Pg 3) ------------------------------------------------------------------------------------------------------------
@@ -2233,42 +2233,42 @@ PVTG
// Table 2 (Pg 1, 1 barsa, padding value)
1.463987928388746e-04, 0.90909090909090906 , 1.061101444733159e+02, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ -4.536012071611531e-04, 0.89898989898989889 , 1.148689112733881e+02, 1.683501683501694e+01, -1.459794466678704e+04,
// Table 2 (Pg 2, pLim, padding value) ---------------------------------------------------------------------------------------
1.463987928388746e-04, 1.0 , 1.167211589206474e+02, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ -4.536012071611253e-04, 0.98888888888888882 , 1.263558024007269e+02, 1.851851851851864e+01, -1.605773913346575e+04,
// Table 2 (Pg 3) ------------------------------------------------------------------------------------------------------------
1.400000000000000e-04, 1.912045889101339e+01, 8.171136278210848e+02, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ -4.600000000000000e-04, 1.890800934777990e+01, 8.845615400896962e+02, 3.540825720558042e+02, -1.124131871143523e+05,
// Table 2 (Pg 4) ------------------------------------------------------------------------------------------------------------
1.200000000000000e-04, 7.575757575757576e+01, 3.006253006253006e+03, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ -4.800000000000000e-04, 7.491582491582491e+01, 3.254401467029136e+03, 1.402918069584753e+03, -4.135807679602166e+05,
// Table 2 (Pg 5) ------------------------------------------------------------------------------------------------------------
1.500000000000000e-04, 1.140250855188141e+02, 4.057832224868830e+03, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ -4.500000000000000e-04, 1.127581401241606e+02, 4.392782350022811e+03, 2.111575657755841e+03, -5.582502085899691e+05,
// Table 2 (Pg 6) ------------------------------------------------------------------------------------------------------------
1.900000000000000e-04, 1.805054151624549e+02, 5.676270917058329e+03, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ -4.100000000000000e-04, 1.784997994384276e+02, 6.144813613926002e+03, 3.342692873378847e+03, -7.809044947794550e+05,
// Table 2 (Pg 7) ------------------------------------------------------------------------------------------------------------
2.900000000000000e-04, 2.398081534772182e+02, 6.755159252879387e+03, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ -3.100000000000000e-04, 2.371436184385825e+02, 7.312757820735446e+03, 4.440891731059603e+03, -9.293309464267653e+05,
// Table 2 (Pg 8) ------------------------------------------------------------------------------------------------------------
4.900000000000000e-04, 2.801120448179272e+02, 7.145715429028755e+03, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ -1.100000000000000e-04, 2.769996887643947e+02, 7.735552106503829e+03, 5.187260089220918e+03, -9.830611291251233e+05,
// Table 2 (Pg 9) ------------------------------------------------------------------------------------------------------------
@@ -2363,24 +2363,24 @@ PVTG
// Table 1 (Pg 1, 1 barsa, padding value)
4.406028992878809e-06, 0.90909090909090906 , 3.449305141722682e+02, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ 1.916028992878809e-06, 0.90909090909090906 , 3.451700492515545e+02, 0.0 , -9.619882702262125e+04,
+ -5.639710071211913e-07, 0.90909090909090906 , 3.451700492515545e+02, 0.0 , 0.0 ,
-2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
-2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
// Table 1 (Pg 2, pLim, padding value) ---------------------------------------------------------------------------------------
4.406028992878809e-06, 1.0 , 3.794235655894950e+02, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ 1.916028992878809e-06, 1.0 , 3.796870541767099e+02, 0.0 , -1.058187097248628e+05,
+ -5.639710071211913e-07, 1.0 , 3.796870541767099e+02, 0.0 , 0.0 ,
-2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
-2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
// Table 1 (Pg 3) ------------------------------------------------------------------------------------------------------------
4.970000000000000e-06, 4.006731308598445e+01, 2.780521380012800e+03, -2.000000000000000e+20, -2.000000000000000e+20,
- 2.480000000000000e-06, 4.006731308598445e+01, 2.782452297637809e+03, 0, -7.754689257064208e+05,
- 0, 4.006731308598445e+01, 2.782452297637809e+03, 0, 0,
+ 2.480000000000000e-06, 4.006731308598445e+01, 2.782452297637809e+03, 0.0 , -7.754689257064208e+05,
+ 0, 4.006731308598445e+01, 2.782452297637809e+03, 0.0 , 0.0 ,
-2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
-2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
@@ -2512,20 +2512,20 @@ PVTG
// Table 1 (Pg 1, p=1 barsa, padding value)
4.406028992878809e-06, 0.90909090909090906 , 3.449305141722682e+02, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ 1.916028992878809e-06, 0.90909090909090906 , 3.451700492515545e+02, 0.0 , -9.619882702262125e+04,
+ -5.639710071211913e-07, 0.90909090909090906 , 3.451700492515545e+02, 0.0 , 0.0 ,
// Table 1 (Pg 2, p=pLim, padding value) -------------------------------------------------------------------------------------
4.406028992878809e-06, 1.0 , 3.794235655894950e+02, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
- -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20, -2.000000000000000e+20,
+ 1.916028992878809e-06, 1.0 , 3.796870541767099e+02, 0.0 , -1.058187097248628e+05,
+ -5.639710071211913e-07, 1.0 , 3.796870541767099e+02, 0.0 , 0.0 ,
// Table 1 (Pg 3) ------------------------------------------------------------------------------------------------------------
4.970000000000000e-06, 4.006731308598445e+01, 2.780521380012800e+03, -2.000000000000000e+20, -2.000000000000000e+20,
- 2.480000000000000e-06, 4.006731308598445e+01, 2.782452297637809e+03, 0, -7.754689257064208e+05,
- 0, 4.006731308598445e+01, 2.782452297637809e+03, 0, 0,
+ 2.480000000000000e-06, 4.006731308598445e+01, 2.782452297637809e+03, 0.0 , -7.754689257064208e+05,
+ 0, 4.006731308598445e+01, 2.782452297637809e+03, 0.0 , 0.0 ,
// Table 1 (Pg 4) ------------------------------------------------------------------------------------------------------------
@@ -2957,14 +2957,14 @@ PVTO
//
// Table 1 (Comp 1)
1.014700000000000e+03, 7.722007722007722e-01, 9.303623761455088e-01, 2.000000000000000e+20, 2.000000000000000e+20,
- 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
+ 5.014700000000000e+03, 8.122111749054753e-01, 6.963183654412739e-01, 1.000260067617578e-05, -5.851100267605872e-05,
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
// Table 1 (Comp 2) ----------------------------------------------------------------------------------------------------------
3.014700000000000e+03, 6.389776357827476e-01, 1.075719925560181e+00, 2.000000000000000e+20, 2.000000000000000e+20,
- 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
+ 7.014700000000000e+03, 6.720852853051696e-01, 8.051094492255388e-01, 8.276912380605518e-06, -6.765261908366062e-05,
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
@@ -2979,7 +2979,7 @@ PVTO
// Table 2 (Comp 1)
1.470000000000000e+01, 9.416195856873822e-01, 9.054034477763291e-01, 2.000000000000000e+20, 2.000000000000000e+20,
- 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
+ 5.014700000000000e+03, 1.010794932071003 , 6.698355189139958e-01, 1.383506927672406e-05, -4.711358577246664e-05,
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
@@ -3282,10 +3282,10 @@ PVTO
// Table 1 (Comp 2) ----------------------------------------------------------------------------------------------------------
7.000000000000000e+01, 8.887150957146157e-01, 8.336914593945738e-01, 2.000000000000000e+20, 2.000000000000000e+20,
- 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
- 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
- 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
- 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20, 2.000000000000000e+20,
+ 9.500000000000000e+01, 8.927172462556416e-01, 7.975674495270629e-01, 1.600860216410370e-04, -1.444960394700433e-03,
+ 1.200000000000000e+02, 8.964836919960728e-01, 7.645264301518615e-01, 1.506578296172467e-04, -1.321640775008057e-03,
+ 1.450000000000000e+02, 9.000314821716637e-01, 7.341801796000192e-01, 1.419116070236371e-04, -1.213850022073691e-03,
+ 1.700000000000000e+02, 9.033786969516677e-01, 7.062059857345745e-01, 1.338885912001597e-04, -1.118967754617790e-03,
// Table 1 (Comp 3) ----------------------------------------------------------------------------------------------------------