void EclipseState::initPhases(DeckConstPtr deck) { if (deck->hasKeyword("OIL")) phases.insert(Phase::PhaseEnum::OIL); if (deck->hasKeyword("GAS")) phases.insert(Phase::PhaseEnum::GAS); if (deck->hasKeyword("WATER")) phases.insert(Phase::PhaseEnum::WATER); }
/*! * \brief Initialize the parameters for water using an ECL deck. * * This method assumes that the deck features valid DENSITY and PVDG keywords. */ void initFromDeck(DeckConstPtr deck, EclipseStateConstPtr eclState) { if (enableThermal && (deck->hasKeyword("WATDENT") || deck->hasKeyword("VISCREF"))) setApproach(ThermalWaterPvt); else if (deck->hasKeyword("PVTW")) setApproach(ConstantCompressibilityWaterPvt); OPM_WATER_PVT_MULTIPLEXER_CALL(pvtImpl.initFromDeck(deck, eclState)); }
/*! * \brief Implement the temperature part of the water PVT properties. */ void initFromDeck(DeckConstPtr deck, EclipseStateConstPtr eclState) { ////// // initialize the isothermal part ////// isothermalPvt_ = new IsothermalPvt; isothermalPvt_->initFromDeck(deck, eclState); ////// // initialize the thermal part ////// auto tables = eclState->getTableManager(); enableThermalDensity_ = deck->hasKeyword("WATDENT"); enableThermalViscosity_ = deck->hasKeyword("VISCREF"); unsigned numRegions = isothermalPvt_->numRegions(); setNumRegions(numRegions); if (enableThermalDensity_) { const auto& watdentKeyword = deck->getKeyword("WATDENT"); assert(watdentKeyword.size() == numRegions); for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const auto& watdentRecord = watdentKeyword.getRecord(regionIdx); watdentRefTemp_[regionIdx] = watdentRecord.getItem("REFERENCE_TEMPERATURE").getSIDouble(0); watdentCT1_[regionIdx] = watdentRecord.getItem("EXPANSION_COEFF_LINEAR").getSIDouble(0); watdentCT2_[regionIdx] = watdentRecord.getItem("EXPANSION_COEFF_QUADRATIC").getSIDouble(0); } } if (enableThermalViscosity_) { const auto& viscrefKeyword = deck->getKeyword("VISCREF"); const auto& watvisctTables = tables->getWatvisctTables(); assert(watvisctTables.size() == numRegions); assert(viscrefKeyword.size() == numRegions); for (unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) { const auto& T = watvisctTables[regionIdx].getColumn("Temperature").vectorCopy(); const auto& mu = watvisctTables[regionIdx].getColumn("Viscosity").vectorCopy(); watvisctCurves_[regionIdx].setXYContainers(T, mu); const auto& viscrefRecord = viscrefKeyword.getRecord(regionIdx); viscrefPress_[regionIdx] = viscrefRecord.getItem("REFERENCE_PRESSURE").getSIDouble(0); } } }
void EclipseState::initTitle(DeckConstPtr deck){ if (deck->hasKeyword("TITLE")) { DeckKeywordConstPtr titleKeyword = deck->getKeyword("TITLE"); DeckRecordConstPtr record = titleKeyword->getRecord(0); DeckItemPtr item = record->getItem(0); std::vector<std::string> itemValue = item->getStringData(); m_title = boost::algorithm::join(itemValue, " "); } }
/*! * \brief Implement the temperature part of the gas PVT properties. */ void initFromDeck(DeckConstPtr deck, EclipseStateConstPtr eclState) { ////// // initialize the isothermal part ////// isothermalPvt_ = new IsothermalPvt; isothermalPvt_->initFromDeck(deck, eclState); ////// // initialize the thermal part ////// auto tables = eclState->getTableManager(); enableThermalDensity_ = deck->hasKeyword("TREF"); enableThermalViscosity_ = deck->hasKeyword("GASVISCT"); unsigned numRegions = isothermalPvt_->numRegions(); setNumRegions(numRegions); // viscosity if (enableThermalViscosity_) { const auto& gasvisctTables = tables->getGasvisctTables(); Opm::DeckKeywordConstPtr viscrefKeyword = deck->getKeyword("VISCREF"); int gasCompIdx = deck->getKeyword("GCOMPIDX")->getRecord(0)->getItem("GAS_COMPONENT_INDEX")->getInt(0) - 1; std::string gasvisctColumnName = "Viscosity"+std::to_string(static_cast<long long>(gasCompIdx)); for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const auto& T = gasvisctTables[regionIdx].getColumn("Temperature").vectorCopy(); const auto& mu = gasvisctTables[regionIdx].getColumn(gasvisctColumnName).vectorCopy(); gasvisctCurves_[regionIdx].setXYContainers(T, mu); } } // quantities required for density. note that we just always use the values // for the first EOS. (since EOS != PVT region.) refTemp_ = 0.0; if (enableThermalDensity_) { refTemp_ = deck->getKeyword("TREF")->getRecord(0)->getItem("TEMPERATURE")->getSIDouble(0); } }
/*! * \brief Implement the temperature part of the oil PVT properties. */ void initFromDeck(DeckConstPtr deck, EclipseStateConstPtr eclState) { ////// // initialize the isothermal part ////// isothermalPvt_ = new IsothermalPvt; isothermalPvt_->initFromDeck(deck, eclState); ////// // initialize the thermal part ////// auto tables = eclState->getTableManager(); enableThermalDensity_ = deck->hasKeyword("THERMEX1"); enableThermalViscosity_ = deck->hasKeyword("VISCREF"); unsigned numRegions = isothermalPvt_->numRegions(); setNumRegions(numRegions); // viscosity if (deck->hasKeyword("VISCREF")) { const auto& oilvisctTables = tables->getOilvisctTables(); Opm::DeckKeywordConstPtr viscrefKeyword = deck->getKeyword("VISCREF"); assert(oilvisctTables.size() == numRegions); assert(viscrefKeyword->size() == numRegions); for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const auto& TCol = oilvisctTables[regionIdx].getColumn("Temperature").vectorCopy(); const auto& muCol = oilvisctTables[regionIdx].getColumn("Viscosity").vectorCopy(); oilvisctCurves_[regionIdx].setXYContainers(TCol, muCol); DeckRecordConstPtr 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... Scalar Tref = 273.15 + 20; // compute the reference viscosity using the isothermal PVT object. viscRef_[regionIdx] = isothermalPvt_->viscosity(regionIdx, Tref, viscrefPress_[regionIdx], viscrefRs_[regionIdx]); } } // quantities required for density. note that we just always use the values // for the first EOS. (since EOS != PVT region.) refTemp_ = 0.0; if (deck->hasKeyword("THERMEX1")) { int oilCompIdx = deck->getKeyword("OCOMPIDX")->getRecord(0)->getItem("OIL_COMPONENT_INDEX")->getInt(0) - 1; // always use the values of the first EOS refTemp_ = deck->getKeyword("TREF")->getRecord(0)->getItem("TEMPERATURE")->getSIDouble(oilCompIdx); refPress_ = deck->getKeyword("PREF")->getRecord(0)->getItem("PRESSURE")->getSIDouble(oilCompIdx); refC_ = deck->getKeyword("CREF")->getRecord(0)->getItem("COMPRESSIBILITY")->getSIDouble(oilCompIdx); thermex1_ = deck->getKeyword("THERMEX1")->getRecord(0)->getItem("EXPANSION_COEFF")->getSIDouble(oilCompIdx); } }
void RelpermDiagnostics::scaledEndPointsCheck_(DeckConstPtr deck, EclipseStateConstPtr eclState, const GridT& grid) { const int nc = Opm::UgGridHelpers::numCells(grid); const auto& global_cell = Opm::UgGridHelpers::globalCell(grid); const auto dims = Opm::UgGridHelpers::cartDims(grid); const auto& compressedToCartesianIdx = Opm::compressedToCartesian(nc, global_cell); scaledEpsInfo_.resize(nc); EclEpsGridProperties epsGridProperties; epsGridProperties.initFromDeck(deck, eclState, /*imbibition=*/false); const auto& satnum = eclState->get3DProperties().getIntGridProperty("SATNUM"); const std::string tag = "Scaled endpoints"; for (int c = 0; c < nc; ++c) { const int cartIdx = compressedToCartesianIdx[c]; const std::string satnumIdx = std::to_string(satnum.iget(cartIdx)); std::array<int, 3> ijk; ijk[0] = cartIdx % dims[0]; ijk[1] = (cartIdx / dims[0]) % dims[1]; ijk[2] = cartIdx / dims[0] / dims[1]; const std::string cellIdx = "(" + std::to_string(ijk[0]) + ", " + std::to_string(ijk[1]) + ", " + std::to_string(ijk[2]) + ")"; scaledEpsInfo_[c].extractScaled(epsGridProperties, cartIdx); // SGU <= 1.0 - SWL if (scaledEpsInfo_[c].Sgu > (1.0 - scaledEpsInfo_[c].Swl)) { const std::string msg = "For scaled endpoints input, cell" + cellIdx + " SATNUM = " + satnumIdx + ", SGU exceed 1.0 - SWL"; OpmLog::warning(tag, msg); } // SGL <= 1.0 - SWU if (scaledEpsInfo_[c].Sgl > (1.0 - scaledEpsInfo_[c].Swu)) { const std::string msg = "For scaled endpoints input, cell" + cellIdx + " SATNUM = " + satnumIdx + ", SGL exceed 1.0 - SWU"; OpmLog::warning(tag, msg); } if (deck->hasKeyword("SCALECRS") && fluidSystem_ == FluidSystem::BlackOil) { // Mobilility check. if ((scaledEpsInfo_[c].Sowcr + scaledEpsInfo_[c].Swcr) >= 1.0) { const std::string msg = "For scaled endpoints input, cell" + cellIdx + " SATNUM = " + satnumIdx + ", SOWCR + SWCR exceed 1.0"; OpmLog::warning(tag, msg); } if ((scaledEpsInfo_[c].Sogcr + scaledEpsInfo_[c].Sgcr + scaledEpsInfo_[c].Swl) >= 1.0) { const std::string msg = "For scaled endpoints input, cell" + cellIdx + " SATNUM = " + satnumIdx + ", SOGCR + SGCR + SWL exceed 1.0"; OpmLog::warning(tag, msg); } } ///Following rules come from NEXUS. if (fluidSystem_ != FluidSystem::WaterGas) { if (scaledEpsInfo_[c].Swl > scaledEpsInfo_[c].Swcr) { const std::string msg = "For scaled endpoints input, cell" + cellIdx + " SATNUM = " + satnumIdx + ", SWL > SWCR"; OpmLog::warning(tag, msg); } if (scaledEpsInfo_[c].Swcr > scaledEpsInfo_[c].Sowcr) { const std::string msg = "For scaled endpoints input, cell" + cellIdx + " SATNUM = " + satnumIdx + ", SWCR > SOWCR"; OpmLog::warning(tag, msg); } if (scaledEpsInfo_[c].Sowcr > scaledEpsInfo_[c].Swu) { const std::string msg = "For scaled endpoints input, cell" + cellIdx + " SATNUM = " + satnumIdx + ", SOWCR > SWU"; OpmLog::warning(tag, msg); } } if (fluidSystem_ != FluidSystem::OilWater) { if (scaledEpsInfo_[c].Sgl > scaledEpsInfo_[c].Sgcr) { const std::string msg = "For scaled endpoints input, cell" + cellIdx + " SATNUM = " + satnumIdx + ", SGL > SGCR"; OpmLog::warning(tag, msg); } } if (fluidSystem_ != FluidSystem::BlackOil) { if (scaledEpsInfo_[c].Sgcr > scaledEpsInfo_[c].Sogcr) { const std::string msg = "For scaled endpoints input, cell" + cellIdx + " SATNUM = " + satnumIdx + ", SGCR > SOGCR"; OpmLog::warning(tag, msg); } if (scaledEpsInfo_[c].Sogcr > scaledEpsInfo_[c].Sgu) { const std::string msg = "For scaled endpoints input, cell" + cellIdx + " SATNUM = " + satnumIdx + ", SOGCR > SGU"; OpmLog::warning(tag, msg); } } } }
SolventPropsAdFromDeck::SolventPropsAdFromDeck(DeckConstPtr deck, EclipseStateConstPtr eclState, const int number_of_cells, const int* global_cell) { if (deck->hasKeyword("SOLVENT")) { // retrieve the cell specific PVT table index from the deck // and using the grid... extractPvtTableIndex(cellPvtRegionIdx_, eclState, number_of_cells, global_cell); extractTableIndex("SATNUM", eclState, number_of_cells, global_cell, cellSatNumRegionIdx_); // surface densities if (deck->hasKeyword("SDENSITY")) { const auto& densityKeyword = deck->getKeyword("SDENSITY"); int numRegions = densityKeyword.size(); solvent_surface_densities_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { solvent_surface_densities_[regionIdx] = densityKeyword.getRecord(regionIdx).getItem("SOLVENT_DENSITY").getSIDouble(0); } } else { OPM_THROW(std::runtime_error, "SDENSITY must be specified in SOLVENT runs\n"); } auto tables = eclState->getTableManager(); // pvt const TableContainer& pvdsTables = tables->getPvdsTables(); if (!pvdsTables.empty()) { int numRegions = pvdsTables.size(); // resize the attributes of the object b_.resize(numRegions); viscosity_.resize(numRegions); inverseBmu_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const Opm::PvdsTable& pvdsTable = pvdsTables.getTable<PvdsTable>(regionIdx); const auto& press = pvdsTable.getPressureColumn(); const auto& b = pvdsTable.getFormationFactorColumn(); const auto& visc = pvdsTable.getViscosityColumn(); const int sz = b.size(); std::vector<double> inverseBmu(sz); std::vector<double> inverseB(sz); for (int i = 0; i < sz; ++i) { inverseB[i] = 1.0 / b[i]; inverseBmu[i] = 1.0 / (b[i] * visc[i]); } b_[regionIdx] = NonuniformTableLinear<double>(press, inverseB); viscosity_[regionIdx] = NonuniformTableLinear<double>(press, visc); inverseBmu_[regionIdx] = NonuniformTableLinear<double>(press, inverseBmu); } } else { OPM_THROW(std::runtime_error, "PVDS must be specified in SOLVENT runs\n"); } const TableContainer& ssfnTables = tables->getSsfnTables(); // relative permeabilty multiplier if (!ssfnTables.empty()) { int numRegions = ssfnTables.size(); // resize the attributes of the object krg_.resize(numRegions); krs_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const Opm::SsfnTable& ssfnTable = ssfnTables.getTable<SsfnTable>(regionIdx); // Copy data const auto& solventFraction = ssfnTable.getSolventFractionColumn(); const auto& krg = ssfnTable.getGasRelPermMultiplierColumn(); const auto& krs = ssfnTable.getSolventRelPermMultiplierColumn(); krg_[regionIdx] = NonuniformTableLinear<double>(solventFraction, krg); krs_[regionIdx] = NonuniformTableLinear<double>(solventFraction, krs); } } else { OPM_THROW(std::runtime_error, "SSFN must be specified in SOLVENT runs\n"); } if (deck->hasKeyword("MISCIBLE") ) { // retrieve the cell specific Misc table index from the deck // and using the grid... extractTableIndex("MISCNUM", eclState, number_of_cells, global_cell, cellMiscRegionIdx_); // misicible hydrocabon relative permeability wrt water const TableContainer& sof2Tables = tables->getSof2Tables(); if (!sof2Tables.empty()) { int numRegions = sof2Tables.size(); // resize the attributes of the object krn_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const Opm::Sof2Table& sof2Table = sof2Tables.getTable<Sof2Table>(regionIdx); // Copy data // Sn = So + Sg + Ss; const auto& sn = sof2Table.getSoColumn(); const auto& krn = sof2Table.getKroColumn(); krn_[regionIdx] = NonuniformTableLinear<double>(sn, krn); } } else { OPM_THROW(std::runtime_error, "SOF2 must be specified in MISCIBLE (SOLVENT) runs\n"); } const TableContainer& miscTables = tables->getMiscTables(); if (!miscTables.empty()) { int numRegions = miscTables.size(); // resize the attributes of the object misc_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const Opm::MiscTable& miscTable = miscTables.getTable<MiscTable>(regionIdx); // Copy data // solventFraction = Ss / (Ss + Sg); const auto& solventFraction = miscTable.getSolventFractionColumn(); const auto& misc = miscTable.getMiscibilityColumn(); misc_[regionIdx] = NonuniformTableLinear<double>(solventFraction, misc); } } else { OPM_THROW(std::runtime_error, "MISC must be specified in MISCIBLE (SOLVENT) runs\n"); } const TableContainer& pmiscTables = tables->getPmiscTables(); if (!pmiscTables.empty()) { int numRegions = pmiscTables.size(); // resize the attributes of the object pmisc_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const Opm::PmiscTable& pmiscTable = pmiscTables.getTable<PmiscTable>(regionIdx); // Copy data const auto& po = pmiscTable.getOilPhasePressureColumn(); const auto& pmisc = pmiscTable.getMiscibilityColumn(); pmisc_[regionIdx] = NonuniformTableLinear<double>(po, pmisc); } } // miscible relative permeability multipleiers const TableContainer& msfnTables = tables->getMsfnTables(); if (!msfnTables.empty()) { int numRegions = msfnTables.size(); // resize the attributes of the object mkrsg_.resize(numRegions); mkro_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const Opm::MsfnTable& msfnTable = msfnTables.getTable<MsfnTable>(regionIdx); // Copy data // Ssg = Ss + Sg; const auto& Ssg = msfnTable.getGasPhaseFractionColumn(); const auto& krsg = msfnTable.getGasSolventRelpermMultiplierColumn(); const auto& kro = msfnTable.getOilRelpermMultiplierColumn(); mkrsg_[regionIdx] = NonuniformTableLinear<double>(Ssg, krsg); mkro_[regionIdx] = NonuniformTableLinear<double>(Ssg, kro); } } const TableContainer& sorwmisTables = tables->getSorwmisTables(); if (!sorwmisTables.empty()) { int numRegions = sorwmisTables.size(); // resize the attributes of the object sorwmis_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const Opm::SorwmisTable& sorwmisTable = sorwmisTables.getTable<SorwmisTable>(regionIdx); // Copy data const auto& sw = sorwmisTable.getWaterSaturationColumn(); const auto& sorwmis = sorwmisTable.getMiscibleResidualOilColumn(); sorwmis_[regionIdx] = NonuniformTableLinear<double>(sw, sorwmis); } } const TableContainer& sgcwmisTables = tables->getSgcwmisTables(); if (!sgcwmisTables.empty()) { int numRegions = sgcwmisTables.size(); // resize the attributes of the object sgcwmis_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const Opm::SgcwmisTable& sgcwmisTable = sgcwmisTables.getTable<SgcwmisTable>(regionIdx); // Copy data const auto& sw = sgcwmisTable.getWaterSaturationColumn(); const auto& sgcwmis = sgcwmisTable.getMiscibleResidualGasColumn(); sgcwmis_[regionIdx] = NonuniformTableLinear<double>(sw, sgcwmis); } } if (deck->hasKeyword("TLMIXPAR")) { const int numRegions = deck->getKeyword("TLMIXPAR").size(); // resize the attributes of the object mix_param_viscosity_.resize(numRegions); mix_param_density_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const auto& tlmixparRecord = deck->getKeyword("TLMIXPAR").getRecord(regionIdx); const auto& mix_params_viscosity = tlmixparRecord.getItem("TL_VISCOSITY_PARAMETER").getSIDoubleData(); mix_param_viscosity_[regionIdx] = mix_params_viscosity[0]; const auto& mix_params_density = tlmixparRecord.getItem("TL_DENSITY_PARAMETER").getSIDoubleData(); const int numDensityItems = mix_params_density.size(); if (numDensityItems == 0) { mix_param_density_[regionIdx] = mix_param_viscosity_[regionIdx]; } else if (numDensityItems == 1) { mix_param_density_[regionIdx] = mix_params_density[0]; } else { OPM_THROW(std::runtime_error, "Only one value can be entered for the TL parameter pr MISC region."); } } } } } }