void BlackoilPVT::init(Opm::DeckConstPtr deck) { const auto eclipseState = std::make_shared<EclipseState>(deck); region_number_ = 0; // Surface densities. Accounting for different orders in eclipse and our code. if (deck->hasKeyword("DENSITY")) { Opm::DeckRecordConstPtr densityRecord = deck->getKeyword("DENSITY")->getRecord(/*regionIdx=*/0); densities_[Aqua] = densityRecord->getItem("WATER")->getSIDouble(0); densities_[Vapour] = densityRecord->getItem("GAS")->getSIDouble(0); densities_[Liquid] = densityRecord->getItem("OIL")->getSIDouble(0); } else { OPM_THROW(std::runtime_error, "Input is missing DENSITY\n"); } // Water PVT if (deck->hasKeyword("PVTW")) { water_props_.reset(new MiscibilityWater(deck->getKeyword("PVTW"))); } else { water_props_.reset(new MiscibilityWater(0.5*Opm::prefix::centi*Opm::unit::Poise)); // Eclipse 100 default } // Oil PVT const auto& pvdoTables = eclipseState->getPvdoTables(); const auto& pvtoTables = eclipseState->getPvtoTables(); if (!pvdoTables.empty()) { oil_props_.reset(new MiscibilityDead(pvdoTables[0])); } else if (pvtoTables.empty()) { oil_props_.reset(new MiscibilityLiveOil(pvtoTables[0])); } else if (deck->hasKeyword("PVCDO")) { auto *misc_water = new MiscibilityWater(0); misc_water->initFromPvcdo(deck->getKeyword("PVCDO")); oil_props_.reset(misc_water); } else { OPM_THROW(std::runtime_error, "Input is missing PVDO and PVTO\n"); } // Gas PVT const auto& pvdgTables = eclipseState->getPvdgTables(); const auto& pvtgTables = eclipseState->getPvtgTables(); if (!pvdgTables.empty()) { gas_props_.reset(new MiscibilityDead(pvdgTables[0])); } else if (pvtgTables.empty()) { gas_props_.reset(new MiscibilityLiveGas(pvtgTables[0])); } else { OPM_THROW(std::runtime_error, "Input is missing PVDG and PVTG\n"); } }
void BlackoilPvtProperties::init(Opm::DeckConstPtr deck, Opm::EclipseStateConstPtr eclipseState, int numSamples) { phase_usage_ = phaseUsageFromDeck(deck); // Surface densities. Accounting for different orders in eclipse and our code. Opm::DeckKeywordConstPtr densityKeyword = deck->getKeyword("DENSITY"); int numRegions = densityKeyword->size(); densities_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { if (phase_usage_.phase_used[Liquid]) { densities_[regionIdx][phase_usage_.phase_pos[Liquid]] = densityKeyword->getRecord(regionIdx)->getItem("OIL")->getSIDouble(0); } if (phase_usage_.phase_used[Aqua]) { densities_[regionIdx][phase_usage_.phase_pos[Aqua]] = densityKeyword->getRecord(regionIdx)->getItem("WATER")->getSIDouble(0); } if (phase_usage_.phase_used[Vapour]) { densities_[regionIdx][phase_usage_.phase_pos[Vapour]] = densityKeyword->getRecord(regionIdx)->getItem("GAS")->getSIDouble(0); } } // Resize the property objects container props_.resize(phase_usage_.num_phases); // Water PVT if (phase_usage_.phase_used[Aqua]) { // if water is used, we require the presence of the "PVTW" // keyword for now... std::shared_ptr<PvtConstCompr> pvtw(new PvtConstCompr); pvtw->initFromWater(deck->getKeyword("PVTW")); props_[phase_usage_.phase_pos[Aqua]] = pvtw; } { auto tables = eclipseState->getTableManager(); // Oil PVT if (phase_usage_.phase_used[Liquid]) { // for oil, we support the "PVDO", "PVTO" and "PVCDO" // keywords... const auto &pvdoTables = tables->getPvdoTables(); const auto &pvtoTables = tables->getPvtoTables(); if (pvdoTables.size() > 0) { if (numSamples > 0) { auto splinePvt = std::shared_ptr<PvtDeadSpline>(new PvtDeadSpline); splinePvt->initFromOil(pvdoTables, numSamples); props_[phase_usage_.phase_pos[Liquid]] = splinePvt; } else { auto deadPvt = std::shared_ptr<PvtDead>(new PvtDead); deadPvt->initFromOil(pvdoTables); props_[phase_usage_.phase_pos[Liquid]] = deadPvt; } } else if (pvtoTables.size() > 0) { props_[phase_usage_.phase_pos[Liquid]].reset(new PvtLiveOil(pvtoTables)); } else if (deck->hasKeyword("PVCDO")) { std::shared_ptr<PvtConstCompr> pvcdo(new PvtConstCompr); pvcdo->initFromOil(deck->getKeyword("PVCDO")); props_[phase_usage_.phase_pos[Liquid]] = pvcdo; } else { OPM_THROW(std::runtime_error, "Input is missing PVDO, PVCDO or PVTO\n"); } } // Gas PVT if (phase_usage_.phase_used[Vapour]) { // gas can be specified using the "PVDG" or "PVTG" keywords... const auto &pvdgTables = tables->getPvdgTables(); const auto &pvtgTables = tables->getPvtgTables(); if (pvdgTables.size() > 0) { if (numSamples > 0) { std::shared_ptr<PvtDeadSpline> splinePvt(new PvtDeadSpline); splinePvt->initFromGas(pvdgTables, numSamples); props_[phase_usage_.phase_pos[Vapour]] = splinePvt; } else { std::shared_ptr<PvtDead> deadPvt(new PvtDead); deadPvt->initFromGas(pvdgTables); props_[phase_usage_.phase_pos[Vapour]] = deadPvt; } } else if (pvtgTables.size() > 0) { props_[phase_usage_.phase_pos[Vapour]].reset(new PvtLiveGas(pvtgTables)); } else { OPM_THROW(std::runtime_error, "Input is missing PVDG or PVTG\n"); } } } }
/// set the tables which specify the temperature dependence of the oil viscosity void initFromDeck(std::shared_ptr<const PvtInterface> isothermalPvt, const Opm::Deck& deck, const Opm::EclipseState& eclipseState) { isothermalPvt_ = isothermalPvt; int numRegions; auto tables = eclipseState->getTableManager(); if (deck->hasKeyword("PVTO")) numRegions = tables->getPvtoTables().size(); else if (deck->hasKeyword("PVDO")) numRegions = tables->getPvdoTables().size(); else if (deck->hasKeyword("PVCDO")) numRegions = deck->getKeyword("PVCDO").size(); else OPM_THROW(std::runtime_error, "Oil phase was not initialized using a known way"); // viscosity if (deck->hasKeyword("VISCREF")) { oilvisctTables_ = &tables->getOilvisctTables(); const auto& viscrefKeyword = deck->getKeyword("VISCREF"); assert(int(oilvisctTables_->size()) == numRegions); assert(int(viscrefKeyword.size()) == numRegions); viscrefPress_.resize(numRegions); viscrefRs_.resize(numRegions); muRef_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const auto& viscrefRecord = viscrefKeyword.getRecord(regionIdx); viscrefPress_[regionIdx] = viscrefRecord.getItem("REFERENCE_PRESSURE").getSIDouble(0); viscrefRs_[regionIdx] = viscrefRecord.getItem("REFERENCE_RS").getSIDouble(0); // temperature used to calculate the reference viscosity [K]. the // value does not really matter if the underlying PVT object really // is isothermal... double Tref = 273.15 + 20; // compute the reference viscosity using the isothermal PVT object. double tmp1, tmp2; isothermalPvt_->mu(1, ®ionIdx, &viscrefPress_[regionIdx], &Tref, &viscrefRs_[regionIdx], &muRef_[regionIdx], &tmp1, &tmp2); } } // quantities required for density. note that we just always use the values // for the first EOS. (since EOS != PVT region.) tref_ = 0.0; if (deck->hasKeyword("THERMEX1")) { oilCompIdx_ = deck->getKeyword("OCOMPIDX").getRecord(0).getItem("OIL_COMPONENT_INDEX").get< int >(0) - 1; // always use the values of the first EOS tref_ = deck->getKeyword("TREF").getRecord(0).getItem("TEMPERATURE").getSIDouble(oilCompIdx_); pref_ = deck->getKeyword("PREF").getRecord(0).getItem("PRESSURE").getSIDouble(oilCompIdx_); cref_ = deck->getKeyword("CREF").getRecord(0).getItem("COMPRESSIBILITY").getSIDouble(oilCompIdx_); thermex1_ = deck->getKeyword("THERMEX1").getRecord(0).getItem("EXPANSION_COEFF").getSIDouble(oilCompIdx_); } }