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) ----------------------------------------------------------------------------------------------------------