#7350 PVT curves : Use PVTNUM value to get PVT curve data

This commit is contained in:
Magne Sjaastad 2021-02-10 15:05:20 +01:00
parent bcdba1bb8f
commit 6ebf3aaaca
5 changed files with 142 additions and 169 deletions

View File

@ -764,7 +764,7 @@ std::vector<RigFlowDiagSolverInterface::RelPermCurve>
///
//--------------------------------------------------------------------------------------------------
std::vector<RigFlowDiagSolverInterface::PvtCurve>
RigFlowDiagSolverInterface::calculatePvtCurves( PvtCurveType pvtCurveType, size_t activeCellIndex )
RigFlowDiagSolverInterface::calculatePvtCurves( PvtCurveType pvtCurveType, int pvtNum )
{
std::vector<PvtCurve> retCurveArr;
@ -789,7 +789,7 @@ std::vector<RigFlowDiagSolverInterface::PvtCurve>
std::vector<Opm::ECLPVT::PVTGraph> graphArr =
m_opmFlowDiagStaticData->m_eclPvtCurveCollection->getPvtCurve( Opm::ECLPVT::RawCurve::FVF,
Opm::ECLPhaseIndex::Liquid,
static_cast<int>( activeCellIndex ) );
pvtNum );
for ( Opm::ECLPVT::PVTGraph srcGraph : graphArr )
{
if ( srcGraph.press.size() > 0 )
@ -805,7 +805,7 @@ std::vector<RigFlowDiagSolverInterface::PvtCurve>
std::vector<Opm::ECLPVT::PVTGraph> graphArr =
m_opmFlowDiagStaticData->m_eclPvtCurveCollection->getPvtCurve( Opm::ECLPVT::RawCurve::FVF,
Opm::ECLPhaseIndex::Vapour,
static_cast<int>( activeCellIndex ) );
pvtNum );
for ( Opm::ECLPVT::PVTGraph srcGraph : graphArr )
{
if ( srcGraph.press.size() > 0 )
@ -824,7 +824,7 @@ std::vector<RigFlowDiagSolverInterface::PvtCurve>
std::vector<Opm::ECLPVT::PVTGraph> graphArr =
m_opmFlowDiagStaticData->m_eclPvtCurveCollection->getPvtCurve( Opm::ECLPVT::RawCurve::Viscosity,
Opm::ECLPhaseIndex::Liquid,
static_cast<int>( activeCellIndex ) );
pvtNum );
for ( Opm::ECLPVT::PVTGraph srcGraph : graphArr )
{
if ( srcGraph.press.size() > 0 )
@ -840,7 +840,7 @@ std::vector<RigFlowDiagSolverInterface::PvtCurve>
std::vector<Opm::ECLPVT::PVTGraph> graphArr =
m_opmFlowDiagStaticData->m_eclPvtCurveCollection->getPvtCurve( Opm::ECLPVT::RawCurve::Viscosity,
Opm::ECLPhaseIndex::Vapour,
static_cast<int>( activeCellIndex ) );
pvtNum );
for ( Opm::ECLPVT::PVTGraph srcGraph : graphArr )
{
if ( srcGraph.press.size() > 0 )
@ -864,7 +864,7 @@ std::vector<RigFlowDiagSolverInterface::PvtCurve>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFlowDiagSolverInterface::calculatePvtDynamicPropertiesFvf( size_t activeCellIndex,
bool RigFlowDiagSolverInterface::calculatePvtDynamicPropertiesFvf( int pvtNum,
double pressure,
double rs,
double rv,
@ -894,8 +894,7 @@ bool RigFlowDiagSolverInterface::calculatePvtDynamicPropertiesFvf( size_t activ
std::vector<double> valArr =
m_opmFlowDiagStaticData->m_eclPvtCurveCollection->getDynamicPropertyNative( Opm::ECLPVT::RawCurve::FVF,
Opm::ECLPhaseIndex::Liquid,
static_cast<int>(
activeCellIndex ),
pvtNum,
phasePress,
mixRatio );
if ( valArr.size() > 0 )
@ -911,8 +910,7 @@ bool RigFlowDiagSolverInterface::calculatePvtDynamicPropertiesFvf( size_t activ
std::vector<double> valArr =
m_opmFlowDiagStaticData->m_eclPvtCurveCollection->getDynamicPropertyNative( Opm::ECLPVT::RawCurve::FVF,
Opm::ECLPhaseIndex::Vapour,
static_cast<int>(
activeCellIndex ),
pvtNum,
phasePress,
mixRatio );
if ( valArr.size() > 0 )
@ -933,7 +931,7 @@ bool RigFlowDiagSolverInterface::calculatePvtDynamicPropertiesFvf( size_t activ
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFlowDiagSolverInterface::calculatePvtDynamicPropertiesViscosity( size_t activeCellIndex,
bool RigFlowDiagSolverInterface::calculatePvtDynamicPropertiesViscosity( int pvtNum,
double pressure,
double rs,
double rv,
@ -960,10 +958,10 @@ bool RigFlowDiagSolverInterface::calculatePvtDynamicPropertiesViscosity( size_t
{
std::vector<double> phasePress = { pressure };
std::vector<double> mixRatio = { rs };
std::vector<double> valArr = m_opmFlowDiagStaticData->m_eclPvtCurveCollection
->getDynamicPropertyNative( Opm::ECLPVT::RawCurve::Viscosity,
std::vector<double> valArr =
m_opmFlowDiagStaticData->m_eclPvtCurveCollection->getDynamicPropertyNative( Opm::ECLPVT::RawCurve::Viscosity,
Opm::ECLPhaseIndex::Liquid,
static_cast<int>( activeCellIndex ),
pvtNum,
phasePress,
mixRatio );
if ( valArr.size() > 0 )
@ -976,10 +974,10 @@ bool RigFlowDiagSolverInterface::calculatePvtDynamicPropertiesViscosity( size_t
{
std::vector<double> phasePress = { pressure };
std::vector<double> mixRatio = { rv };
std::vector<double> valArr = m_opmFlowDiagStaticData->m_eclPvtCurveCollection
->getDynamicPropertyNative( Opm::ECLPVT::RawCurve::Viscosity,
std::vector<double> valArr =
m_opmFlowDiagStaticData->m_eclPvtCurveCollection->getDynamicPropertyNative( Opm::ECLPVT::RawCurve::Viscosity,
Opm::ECLPhaseIndex::Vapour,
static_cast<int>( activeCellIndex ),
pvtNum,
phasePress,
mixRatio );
if ( valArr.size() > 0 )

View File

@ -147,14 +147,10 @@ public:
double max_pv_fraction );
std::vector<RelPermCurve> calculateRelPermCurves( size_t activeCellIndex );
std::vector<PvtCurve> calculatePvtCurves( PvtCurveType pvtCurveType, size_t activeCellIndex );
bool calculatePvtDynamicPropertiesFvf( size_t activeCellIndex, double pressure, double rs, double rv, double* bo, double* bg );
bool calculatePvtDynamicPropertiesViscosity( size_t activeCellIndex,
double pressure,
double rs,
double rv,
double* mu_o,
double* mu_g );
std::vector<PvtCurve> calculatePvtCurves( PvtCurveType pvtCurveType, int pvtNum );
bool calculatePvtDynamicPropertiesFvf( int pvtNum, double pressure, double rs, double rv, double* bo, double* bg );
bool calculatePvtDynamicPropertiesViscosity( int pvtNum, double pressure, double rs, double rv, double* mu_o, double* mu_g );
private:
std::wstring getInitFileName() const;

View File

@ -150,23 +150,15 @@ bool RiuPvtPlotUpdater::queryDataAndUpdatePlot( const RimEclipseResultDefinition
RimEclipseResultCase* eclipseResultCase = dynamic_cast<RimEclipseResultCase*>( eclipseResDef->eclipseCase() );
RigEclipseCaseData* eclipseCaseData = eclipseResultCase ? eclipseResultCase->eclipseCaseData() : nullptr;
RiaDefines::PorosityModelType porosityModel = eclipseResDef->porosityModel();
if ( eclipseResultCase && eclipseCaseData && eclipseResultCase->flowDiagSolverInterface() )
{
size_t activeCellIndex = CellLookupHelper::mapToActiveCellIndex( eclipseCaseData, gridIndex, gridLocalCellIndex );
if ( activeCellIndex != cvf::UNDEFINED_SIZE_T )
{
// cvf::Trace::show("Update PVT plot for active cell index: %d", static_cast<int>(activeCellIndex));
std::vector<RigFlowDiagSolverInterface::PvtCurve> fvfCurveArr =
eclipseResultCase->flowDiagSolverInterface()->calculatePvtCurves( RigFlowDiagSolverInterface::PVT_CT_FVF,
activeCellIndex );
std::vector<RigFlowDiagSolverInterface::PvtCurve> viscosityCurveArr =
eclipseResultCase->flowDiagSolverInterface()->calculatePvtCurves( RigFlowDiagSolverInterface::PVT_CT_VISCOSITY,
activeCellIndex );
// The following calls will read results from file in preparation for the queries below
RigCaseCellResultsData* cellResultsData =
eclipseCaseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
RigCaseCellResultsData* cellResultsData = eclipseCaseData->results( porosityModel );
cellResultsData->ensureKnownResultLoaded(
RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "RS" ) );
cellResultsData->ensureKnownResultLoaded(
@ -179,28 +171,28 @@ bool RiuPvtPlotUpdater::queryDataAndUpdatePlot( const RimEclipseResultDefinition
cvf::ref<RigResultAccessor> rsAccessor =
RigResultAccessorFactory::createFromResultAddress( eclipseCaseData,
gridIndex,
RiaDefines::PorosityModelType::MATRIX_MODEL,
porosityModel,
timeStepIndex,
RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE,
"RS" ) );
cvf::ref<RigResultAccessor> rvAccessor =
RigResultAccessorFactory::createFromResultAddress( eclipseCaseData,
gridIndex,
RiaDefines::PorosityModelType::MATRIX_MODEL,
porosityModel,
timeStepIndex,
RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE,
"RV" ) );
cvf::ref<RigResultAccessor> pressureAccessor =
RigResultAccessorFactory::createFromResultAddress( eclipseCaseData,
gridIndex,
RiaDefines::PorosityModelType::MATRIX_MODEL,
porosityModel,
timeStepIndex,
RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE,
"PRESSURE" ) );
cvf::ref<RigResultAccessor> pvtnumAccessor =
RigResultAccessorFactory::createFromResultAddress( eclipseCaseData,
gridIndex,
RiaDefines::PorosityModelType::MATRIX_MODEL,
porosityModel,
timeStepIndex,
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE,
"PVTNUM" ) );
@ -208,14 +200,23 @@ bool RiuPvtPlotUpdater::queryDataAndUpdatePlot( const RimEclipseResultDefinition
RiuPvtPlotPanel::CellValues cellValues;
cellValues.rs = rsAccessor.notNull() ? rsAccessor->cellScalar( gridLocalCellIndex ) : HUGE_VAL;
cellValues.rv = rvAccessor.notNull() ? rvAccessor->cellScalar( gridLocalCellIndex ) : HUGE_VAL;
cellValues.pressure = pressureAccessor.notNull() ? pressureAccessor->cellScalar( gridLocalCellIndex )
cellValues.pressure = pressureAccessor.notNull() ? pressureAccessor->cellScalar( gridLocalCellIndex ) : HUGE_VAL;
const double cellPvtNumDouble = pvtnumAccessor.notNull() ? pvtnumAccessor->cellScalar( gridLocalCellIndex )
: HUGE_VAL;
const double cellPVTNUM = pvtnumAccessor.notNull() ? pvtnumAccessor->cellScalar( gridLocalCellIndex )
: HUGE_VAL;
const int cellPvtNum = ( cellPvtNumDouble != HUGE_VAL ) ? static_cast<int>( cellPvtNumDouble )
: std::numeric_limits<int>::max();
std::vector<RigFlowDiagSolverInterface::PvtCurve> fvfCurveArr =
eclipseResultCase->flowDiagSolverInterface()->calculatePvtCurves( RigFlowDiagSolverInterface::PVT_CT_FVF,
cellPvtNum );
std::vector<RigFlowDiagSolverInterface::PvtCurve> viscosityCurveArr =
eclipseResultCase->flowDiagSolverInterface()->calculatePvtCurves( RigFlowDiagSolverInterface::PVT_CT_VISCOSITY,
cellPvtNum );
RiuPvtPlotPanel::FvfDynProps fvfDynProps;
eclipseResultCase->flowDiagSolverInterface()->calculatePvtDynamicPropertiesFvf( activeCellIndex,
eclipseResultCase->flowDiagSolverInterface()->calculatePvtDynamicPropertiesFvf( cellPvtNum,
cellValues.pressure,
cellValues.rs,
cellValues.rv,
@ -223,7 +224,7 @@ bool RiuPvtPlotUpdater::queryDataAndUpdatePlot( const RimEclipseResultDefinition
&fvfDynProps.bg );
RiuPvtPlotPanel::ViscosityDynProps viscosityDynProps;
eclipseResultCase->flowDiagSolverInterface()->calculatePvtDynamicPropertiesViscosity( activeCellIndex,
eclipseResultCase->flowDiagSolverInterface()->calculatePvtDynamicPropertiesViscosity( cellPvtNum,
cellValues.pressure,
cellValues.rs,
cellValues.rv,
@ -234,7 +235,7 @@ bool RiuPvtPlotUpdater::queryDataAndUpdatePlot( const RimEclipseResultDefinition
gridIndex,
gridLocalCellIndex,
"PVTNUM",
cellPVTNUM );
cellPvtNumDouble );
plotPanel->setPlotData( eclipseCaseData->unitsType(),
fvfCurveArr,
@ -246,7 +247,6 @@ bool RiuPvtPlotUpdater::queryDataAndUpdatePlot( const RimEclipseResultDefinition
return true;
}
}
return false;
}

View File

@ -29,20 +29,6 @@
#include <ert/ecl/ecl_kw_magic.h>
namespace {
std::vector<int>
pvtnumVector(const ::Opm::ECLGraph& G,
const ::Opm::ECLInitFileData& init)
{
auto pvtnum = G.rawLinearisedCellData<int>(init, "PVTNUM");
if (pvtnum.empty()) {
// PVTNUM missing in one or more of the grids managed by 'G'.
// Put all cells in PVTNUM region 1.
pvtnum.assign(G.numCells(), 1);
}
return pvtnum;
}
template <class PVTInterp>
std::vector<Opm::ECLPVT::PVTGraph>
@ -252,8 +238,7 @@ namespace {
Opm::ECLPVT::ECLPvtCurveCollection::
ECLPvtCurveCollection(const ECLGraph& G,
const ECLInitFileData& init)
: pvtnum_ (pvtnumVector(G, init))
, gas_ (CreateGasPVTInterpolant::fromECLOutput(init))
: gas_ (CreateGasPVTInterpolant::fromECLOutput(init))
, oil_ (CreateOilPVTInterpolant::fromECLOutput(init))
, usys_native_ (ECLUnits::serialisedUnitConventions(init))
, usys_internal_(ECLUnits::internalUnitConventions())
@ -270,22 +255,22 @@ std::vector<Opm::ECLPVT::PVTGraph>
Opm::ECLPVT::ECLPvtCurveCollection::
getPvtCurve(const RawCurve curve,
const ECLPhaseIndex phase,
const int activeCell) const
const int pvtRegionID) const
{
if (! this->isValidRequest(phase, activeCell)) {
if (! this->isValidRequest(phase, pvtRegionID)) {
// Not a supported phase or cell index out of bounds. Not a valid
// request so return empty.
return {};
}
// PVTNUM is traditional one-based region identifier. Subtract one to
// pvtRegionID is traditional one-based region identifier. Subtract one to
// form valid index into std::vector<>s.
const auto regID = this->pvtnum_[activeCell] - 1;
const auto zeroBasedPvtIndex = pvtRegionID - 1;
if (phase == ECLPhaseIndex::Liquid) {
// Caller requests oil properties.
return this->convertToOutputUnits(
rawPvtCurve(this->oil_.get(), curve, regID), curve, phase);
rawPvtCurve(this->oil_.get(), curve, zeroBasedPvtIndex), curve, phase);
}
// Caller requests gas properties.
@ -293,18 +278,18 @@ getPvtCurve(const RawCurve curve,
"Internal Logic Error Identifying Supported Phases");
return this->convertToOutputUnits(
rawPvtCurve(this->gas_.get(), curve, regID), curve, phase);
rawPvtCurve(this->gas_.get(), curve, zeroBasedPvtIndex), curve, phase);
}
std::vector<double>
Opm::ECLPVT::ECLPvtCurveCollection::
getDynamicPropertySI(const RawCurve property,
const ECLPhaseIndex phase,
const int activeCell,
const int pvtRegionID,
const std::vector<double>& phasePress,
const std::vector<double>& mixRatio) const
{
if (! this->isValidRequest(phase, activeCell) ||
if (! this->isValidRequest(phase, pvtRegionID) ||
(property == RawCurve::SaturatedState))
{
// Not a supported phase, cell index out of bounds, or caller
@ -313,14 +298,14 @@ getDynamicPropertySI(const RawCurve property,
return {};
}
// PVTNUM is traditional one-based region identifier. Subtract one to
// pvtRegionID is traditional one-based region identifier. Subtract one to
// form valid index into std::vector<>s.
const auto regID = this->pvtnum_[activeCell] - 1;
const auto zeroBasedPvtIndex = pvtRegionID - 1;
if (phase == ECLPhaseIndex::Liquid) {
// Caller requests oil properties.
return oilProperty(this->oil_.get(), property,
regID, phasePress, mixRatio);
zeroBasedPvtIndex, phasePress, mixRatio);
}
// Caller requests gas properties.
@ -328,18 +313,18 @@ getDynamicPropertySI(const RawCurve property,
"Internal Logic Error Identifying Supported Phases");
return gasProperty(this->gas_.get(), property,
regID, phasePress, mixRatio);
zeroBasedPvtIndex, phasePress, mixRatio);
}
std::vector<double>
Opm::ECLPVT::ECLPvtCurveCollection::
getDynamicPropertyNative(const RawCurve property,
const ECLPhaseIndex phase,
const int activeCell,
const int pvtRegionID,
std::vector<double> phasePress,
std::vector<double> mixRatio) const
{
if (! this->isValidRequest(phase, activeCell) ||
if (! this->isValidRequest(phase, pvtRegionID) ||
(property == RawCurve::SaturatedState))
{
// Not a supported phase, cell index out of bounds, or caller
@ -370,7 +355,7 @@ getDynamicPropertyNative(const RawCurve property,
}
// 2) Evaluate requested property in strict SI units.
auto prop = this->getDynamicPropertySI(property, phase, activeCell,
auto prop = this->getDynamicPropertySI(property, phase, pvtRegionID,
phasePress, mixRatio);
// 3) Convert property values to user's requested system of units.
@ -412,8 +397,7 @@ getDynamicPropertyNative(const RawCurve property,
bool
Opm::ECLPVT::ECLPvtCurveCollection::
isValidRequest(const ECLPhaseIndex phase,
const int activeCell) const
isValidRequest(const ECLPhaseIndex phase, const int pvtRegionID) const
{
if (! ((phase == ECLPhaseIndex::Liquid) ||
(phase == ECLPhaseIndex::Vapour)))
@ -422,9 +406,7 @@ isValidRequest(const ECLPhaseIndex phase,
return false;
}
// Check if cell index is within bounds.
return static_cast<decltype(this->pvtnum_.size())>(activeCell)
< this->pvtnum_.size();
return pvtRegionID >= 1;
}
std::vector<Opm::ECLPVT::PVTGraph>

View File

@ -81,11 +81,11 @@ namespace Opm { namespace ECLPVT {
/// \param[in] phase Phase for which to compute extract graph
/// representation of PVT property function.
///
/// \param[in] activeCell Index of particular active cell in model.
/// \param[in] pvtRegionID Value of pvtRegionID (1-based region value)
///
/// \return Collection of 2D graphs for PVT property curve
/// identified by requests represented by \p curve, \p phase and
/// \p activeCell. One curve (vector element) for each tabulated
/// \p pvtRegionID. One curve (vector element) for each tabulated
/// node of the primary look-up key. Single curve (i.e., a
/// single element vector) in the case of dry gas (no vaporised
/// oil) or dead oil (no dissolved gas). Return values provided
@ -96,17 +96,17 @@ namespace Opm { namespace ECLPVT {
/// (i.e., keyword 'PVCDO' in the input deck).
///
/// Example: Retrieve collection of gas viscosity curves pertaining
/// to model's active cell 31415.
/// to PVT region 1.
///
/// \code
/// const auto curves =
/// pvtCC.getPvtCurve(ECLPVT::RawCurve::Viscosity,
/// ECLPhaseIndex::Vapour, 31415);
/// ECLPhaseIndex::Vapour, 1);
/// \endcode
std::vector<PVTGraph>
getPvtCurve(const RawCurve curve,
const ECLPhaseIndex phase,
const int activeCell) const;
const int pvtRegionID) const;
/// Compute a single dynamic property in a single active cell for a
/// collection of cell states.
@ -124,7 +124,7 @@ namespace Opm { namespace ECLPVT {
/// ECLPhaseIndex::Liquid \endcode. All other values return an
/// empty result.
///
/// \param[in] activeCell Index of particular active cell in model.
/// \param[in] pvtRegionID Value of pvtRegionID (1-based region value)
///
/// \param[in] phasePress Sequence of phase pressure values
/// pertaining to \p activeCell. Could, for instance, be the
@ -139,8 +139,8 @@ namespace Opm { namespace ECLPVT {
/// typically appropriate only for dry gas or dead oil cases.
///
/// \return Sequence of dynamic property values corresponding to the
/// requested property name of the identified phase in the
/// particular active cell. Empty for invalid requests, number
/// requested property name of the identified phase for the
/// current PVT region. Empty for invalid requests, number
/// of elements equal to \code phasePress.size() \endcode
/// otherwise. Return values are in strict SI units of
/// measure--i.e., rm^3/sm^3 for the formation volume factors and
@ -148,7 +148,7 @@ namespace Opm { namespace ECLPVT {
std::vector<double>
getDynamicPropertySI(const RawCurve property,
const ECLPhaseIndex phase,
const int activeCell,
const int pvtRegionID,
const std::vector<double>& phasePress,
const std::vector<double>& mixRatio
= std::vector<double>()) const;
@ -172,7 +172,7 @@ namespace Opm { namespace ECLPVT {
/// ECLPhaseIndex::Liquid \endcode. All other values return an
/// empty result.
///
/// \param[in] activeCell Index of particular active cell in model.
/// \param[in] pvtRegionID Value of pvtRegionID (1-based region value)
///
/// \param[in] phasePress Sequence of phase pressure values
/// pertaining to \p activeCell. Could, for instance, be the
@ -207,15 +207,12 @@ namespace Opm { namespace ECLPVT {
std::vector<double>
getDynamicPropertyNative(const RawCurve property,
const ECLPhaseIndex phase,
const int activeCell,
const int pvtRegionID,
std::vector<double> phasePress, // Mutable copy
std::vector<double> mixRatio // Mutable copy
= std::vector<double>()) const;
private:
/// Forward map: Cell -> PVT Region ID
std::vector<int> pvtnum_;
/// Gas PVT property evaluator.
std::shared_ptr<Gas> gas_; // shared => default special member funcs.
@ -239,12 +236,12 @@ namespace Opm { namespace ECLPVT {
///
/// \param[in] phase Phase for which to compute a property.
///
/// \param[in] activeCell Index of particular active cell in model.
/// \param[in] pvtRegionID Value of pvtRegionID (1-based region value)
///
/// \return True if \p phase is supported and \p activeCell is
/// within range of the currently defined model. False otherwise.
bool isValidRequest(const ECLPhaseIndex phase,
const int activeCell) const;
const int pvtRegionID) const;
/// Convert a sequence of 2D graphs to user-defined system of units.
///