static void check_parser(ParserPtr parser) { DeckPtr deck = parser->parseString(pvtoData, ParseMode()); DeckKeywordConstPtr kw1 = deck->getKeyword("PVTO" , 0); BOOST_CHECK_EQUAL(5U , kw1->size()); DeckRecordConstPtr record0 = kw1->getRecord(0); DeckRecordConstPtr record1 = kw1->getRecord(1); DeckRecordConstPtr record2 = kw1->getRecord(2); DeckRecordConstPtr record3 = kw1->getRecord(3); DeckRecordConstPtr record4 = kw1->getRecord(4); DeckItemConstPtr item0_0 = record0->getItem("RS"); DeckItemConstPtr item0_1 = record0->getItem("DATA"); BOOST_CHECK_EQUAL(1U , item0_0->size()); BOOST_CHECK_EQUAL(9U , item0_1->size()); BOOST_CHECK_EQUAL(2U , record0->size()); DeckItemConstPtr item1_0 = record1->getItem("RS"); DeckItemConstPtr item1_1 = record1->getItem("DATA"); BOOST_CHECK_EQUAL(1U , item1_0->size()); BOOST_CHECK_EQUAL(9U , item1_1->size()); BOOST_CHECK_EQUAL(2U , record1->size()); DeckItemConstPtr item2_0 = record2->getItem("RS"); DeckItemConstPtr item2_1 = record2->getItem("DATA"); BOOST_CHECK(item2_0->defaultApplied(0)); BOOST_CHECK_EQUAL(0U , item2_1->size()); BOOST_CHECK_EQUAL(2U , record2->size()); DeckItemConstPtr item3_0 = record3->getItem("RS"); DeckItemConstPtr item3_1 = record3->getItem("DATA"); BOOST_CHECK_EQUAL(1U , item3_0->size()); BOOST_CHECK_EQUAL(9U , item3_1->size()); BOOST_CHECK_EQUAL(2U , record3->size()); DeckItemConstPtr item4_0 = record4->getItem("RS"); DeckItemConstPtr item4_1 = record4->getItem("DATA"); BOOST_CHECK_EQUAL(1U , item4_0->size()); BOOST_CHECK_EQUAL(9U , item4_1->size()); BOOST_CHECK_EQUAL(2U , record4->size()); Opm::PvtoTable pvtoTable; pvtoTable.initFORUNITTESTONLY(kw1, /*tableIdx=*/0); const auto &outerTable = *pvtoTable.getOuterTable(); const auto &innerTable0 = *pvtoTable.getInnerTable(0); BOOST_CHECK_EQUAL(2, outerTable.numRows()); BOOST_CHECK_EQUAL(4, outerTable.numColumns()); BOOST_CHECK_EQUAL(3, innerTable0.numRows()); BOOST_CHECK_EQUAL(3, innerTable0.numColumns()); BOOST_CHECK_EQUAL(1e-3, outerTable.getGasSolubilityColumn()[0]); BOOST_CHECK_EQUAL(1.0e5, outerTable.getPressureColumn()[0]); BOOST_CHECK_EQUAL(outerTable.getPressureColumn()[0], innerTable0.getPressureColumn()[0]); BOOST_CHECK_EQUAL(1.01, outerTable.getOilFormationFactorColumn()[0]); BOOST_CHECK_EQUAL(outerTable.getOilFormationFactorColumn()[0], innerTable0.getOilFormationFactorColumn()[0]); BOOST_CHECK_EQUAL(1.02e-3, outerTable.getOilViscosityColumn()[0]); BOOST_CHECK_EQUAL(outerTable.getOilViscosityColumn()[0], innerTable0.getOilViscosityColumn()[0]); }
SinglePvtLiveOil::SinglePvtLiveOil(const Opm::PvtoTable &pvtoTable) { const auto saturatedPvto = pvtoTable.getOuterTable(); // OIL, PVTO saturated_oil_table_.resize(4); const int sz = saturatedPvto->numRows(); for (int k=0; k<4; ++k) { saturated_oil_table_[k].resize(sz); } for (int i=0; i<sz; ++i) { saturated_oil_table_[0][i] = saturatedPvto->getPressureColumn()[i]; // p saturated_oil_table_[1][i] = 1.0/saturatedPvto->getOilFormationFactorColumn()[i]; // 1/Bo saturated_oil_table_[2][i] = saturatedPvto->getOilViscosityColumn()[i]; // mu_o saturated_oil_table_[3][i] = saturatedPvto->getGasSolubilityColumn()[i]; // Rs } undersat_oil_tables_.resize(sz); for (int i=0; i<sz; ++i) { const auto undersaturatedPvto = pvtoTable.getInnerTable(i); undersat_oil_tables_[i].resize(3); int tsize = undersaturatedPvto->numRows(); undersat_oil_tables_[i][0].resize(tsize); undersat_oil_tables_[i][1].resize(tsize); undersat_oil_tables_[i][2].resize(tsize); for (int j=0; j<tsize; ++j) { undersat_oil_tables_[i][0][j] = undersaturatedPvto->getPressureColumn()[j]; // p undersat_oil_tables_[i][1][j] = 1.0/undersaturatedPvto->getOilFormationFactorColumn()[j]; // 1/Bo undersat_oil_tables_[i][2][j] = undersaturatedPvto->getOilViscosityColumn()[j]; // mu_o } } // Complete undersaturated tables by extrapolating from existing data // as is done in Eclipse and Mrst int iNext = -1; for (int i=0; i<sz; ++i) { // Skip records already containing undersaturated data if (undersat_oil_tables_[i][0].size() > 1) { continue; } // Look ahead for next record containing undersaturated data if (iNext < i) { iNext = i+1; while (iNext<sz && undersat_oil_tables_[iNext][0].size() < 2) { ++iNext; } if (iNext == sz) OPM_THROW(std::runtime_error,"Unable to complete undersaturated table."); } // Add undersaturated data to current record while maintaining compressibility and viscosibility typedef std::vector<std::vector<std::vector<double> > >::size_type sz_t; for (sz_t j=1; j<undersat_oil_tables_[iNext][0].size(); ++j) { double diffPressure = undersat_oil_tables_[iNext][0][j]-undersat_oil_tables_[iNext][0][j-1]; double pressure = undersat_oil_tables_[i][0].back()+diffPressure; undersat_oil_tables_[i][0].push_back(pressure); double compr = (1.0/undersat_oil_tables_[iNext][1][j]-1.0/undersat_oil_tables_[iNext][1][j-1]) / (0.5*(1.0/undersat_oil_tables_[iNext][1][j]+1.0/undersat_oil_tables_[iNext][1][j-1])); double B = (1.0/undersat_oil_tables_[i][1].back())*(1.0+0.5*compr)/(1.0-0.5*compr); undersat_oil_tables_[i][1].push_back(1.0/B); double visc = (undersat_oil_tables_[iNext][2][j]-undersat_oil_tables_[iNext][2][j-1]) / (0.5*(undersat_oil_tables_[iNext][2][j]+undersat_oil_tables_[iNext][2][j-1])); double mu = (undersat_oil_tables_[i][2].back())*(1.0+0.5*visc)/(1.0-0.5*visc); undersat_oil_tables_[i][2].push_back(mu); } } }