#13269 Add support for display of field units in VFP plots

Updates the VFP table display to support different unit systems, specifically metric and field units. Introduces unit system awareness to the display of pressure and flow rate values, ensuring values are shown in the correct units based on the configured unit system.
This commit is contained in:
Magne Sjaastad authored and GitHub committed 2025-12-03 09:52:38 +01:00
1 parent 88b0094dc8
commit df293bed37
4 files changed
+14612 -22

No files matched your search

@@ -30,7 +30,7 @@
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
VfpPlotData RigVfpTables::populatePlotData( const Opm::VFPInjTable& table, VfpPlotData RigVfpTables::populatePlotData( const Opm::VFPInjTable& table,
RimVfpDefines::InterpolatedVariableType interpolatedVariable, RimVfpDefines::InterpolatedVariableType interpolatedVariable,
RimVfpDefines::FlowingPhaseType flowingPhase ) RimVfpDefines::FlowingPhaseType flowingPhase ) const
{ {
VfpPlotData plotData; VfpPlotData plotData;
@@ -411,7 +411,7 @@ std::vector<int> RigVfpTables::uniqueClosestIndices( const std::vector<double>&
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QString RigVfpTables::axisTitle( RimVfpDefines::ProductionVariableType variableType, RimVfpDefines::FlowingPhaseType flowingPhase ) QString RigVfpTables::axisTitle( RimVfpDefines::ProductionVariableType variableType, RimVfpDefines::FlowingPhaseType flowingPhase ) const
{ {
QString title; QString title;
@@ -432,11 +432,27 @@ QString RigVfpTables::axisTitle( RimVfpDefines::ProductionVariableType variableT
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QString RigVfpTables::getDisplayUnit( RimVfpDefines::ProductionVariableType variableType ) QString RigVfpTables::getDisplayUnit( RimVfpDefines::ProductionVariableType variableType ) const
{ {
if ( variableType == RimVfpDefines::ProductionVariableType::THP ) return "Bar"; return getDisplayUnit( variableType, m_unitSystem );
}
if ( variableType == RimVfpDefines::ProductionVariableType::FLOW_RATE ) return "Sm3/day"; //--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RigVfpTables::getDisplayUnit( RimVfpDefines::ProductionVariableType variableType, const Opm::UnitSystem& unitSystem )
{
bool isFieldUnits = ( unitSystem.getType() == Opm::UnitSystem::UnitType::UNIT_TYPE_FIELD );
if ( variableType == RimVfpDefines::ProductionVariableType::THP )
{
return isFieldUnits ? "psia" : "Bar";
}
if ( variableType == RimVfpDefines::ProductionVariableType::FLOW_RATE )
{
return isFieldUnits ? "stb/day" : "Sm3/day";
}
return ""; return "";
} }
@@ -444,9 +460,17 @@ QString RigVfpTables::getDisplayUnit( RimVfpDefines::ProductionVariableType vari
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QString RigVfpTables::getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType variableType ) QString RigVfpTables::getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType variableType ) const
{ {
QString unit = getDisplayUnit( variableType ); return getDisplayUnitWithBracket( variableType, m_unitSystem );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RigVfpTables::getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType variableType, const Opm::UnitSystem& unitSystem )
{
QString unit = getDisplayUnit( variableType, unitSystem );
if ( !unit.isEmpty() ) return QString( "[%1]" ).arg( unit ); if ( !unit.isEmpty() ) return QString( "[%1]" ).arg( unit );
return {}; return {};
@@ -455,17 +479,37 @@ QString RigVfpTables::getDisplayUnitWithBracket( RimVfpDefines::ProductionVariab
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
double RigVfpTables::convertToDisplayUnit( double value, RimVfpDefines::ProductionVariableType variableType ) double RigVfpTables::convertToDisplayUnit( double value, RimVfpDefines::ProductionVariableType variableType ) const
{ {
return convertToDisplayUnit( value, variableType, m_unitSystem );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigVfpTables::convertToDisplayUnit( double value, RimVfpDefines::ProductionVariableType variableType, const Opm::UnitSystem& unitSystem )
{
bool isFieldUnits = ( unitSystem.getType() == Opm::UnitSystem::UnitType::UNIT_TYPE_FIELD );
if ( variableType == RimVfpDefines::ProductionVariableType::THP ) if ( variableType == RimVfpDefines::ProductionVariableType::THP )
{ {
return RiaEclipseUnitTools::pascalToBar( value ); if ( isFieldUnits )
{
// Convert from psi (field) to psia - no conversion needed, already in correct units
return value;
}
else
{
// Convert Pascal (SI) to Bar (metric)
return RiaEclipseUnitTools::pascalToBar( value );
}
} }
if ( variableType == RimVfpDefines::ProductionVariableType::FLOW_RATE ) if ( variableType == RimVfpDefines::ProductionVariableType::FLOW_RATE )
{ {
// Convert to m3/sec to m3/day // Convert from per-second to per-day for both unit systems
return value * static_cast<double>( 24 * 60 * 60 ); const double secToDay = 24.0 * 60.0 * 60.0;
return value * secToDay;
} }
return value; return value;
@@ -474,10 +518,20 @@ double RigVfpTables::convertToDisplayUnit( double value, RimVfpDefines::Producti
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RigVfpTables::convertToDisplayUnit( std::vector<double>& values, RimVfpDefines::ProductionVariableType variableType ) void RigVfpTables::convertToDisplayUnit( std::vector<double>& values, RimVfpDefines::ProductionVariableType variableType ) const
{
convertToDisplayUnit( values, variableType, m_unitSystem );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigVfpTables::convertToDisplayUnit( std::vector<double>& values,
RimVfpDefines::ProductionVariableType variableType,
const Opm::UnitSystem& unitSystem )
{ {
for ( double& value : values ) for ( double& value : values )
value = convertToDisplayUnit( value, variableType ); value = convertToDisplayUnit( value, variableType, unitSystem );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -138,10 +138,18 @@ public:
// match. A index value is only returned once. // match. A index value is only returned once.
static std::vector<int> uniqueClosestIndices( const std::vector<double>& sourceValues, const std::vector<double>& valuesToMatch ); static std::vector<int> uniqueClosestIndices( const std::vector<double>& sourceValues, const std::vector<double>& valuesToMatch );
// Static versions of display and conversion functions that take unit system parameter
static QString getDisplayUnit( RimVfpDefines::ProductionVariableType variableType, const Opm::UnitSystem& unitSystem );
static QString getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType variableType, const Opm::UnitSystem& unitSystem );
static double convertToDisplayUnit( double value, RimVfpDefines::ProductionVariableType variableType, const Opm::UnitSystem& unitSystem );
static void convertToDisplayUnit( std::vector<double>& values,
RimVfpDefines::ProductionVariableType variableType,
const Opm::UnitSystem& unitSystem );
private: private:
static VfpPlotData populatePlotData( const Opm::VFPInjTable& table, VfpPlotData populatePlotData( const Opm::VFPInjTable& table,
RimVfpDefines::InterpolatedVariableType interpolatedVariable, RimVfpDefines::InterpolatedVariableType interpolatedVariable,
RimVfpDefines::FlowingPhaseType flowingPhase ); RimVfpDefines::FlowingPhaseType flowingPhase ) const;
VfpPlotData populatePlotData( const Opm::VFPProdTable& table, VfpPlotData populatePlotData( const Opm::VFPProdTable& table,
RimVfpDefines::ProductionVariableType primaryVariable, RimVfpDefines::ProductionVariableType primaryVariable,
@@ -157,12 +165,11 @@ private:
RimVfpDefines::FlowingPhaseType flowingPhase, RimVfpDefines::FlowingPhaseType flowingPhase,
const VfpValueSelection& valueSelection ) const; const VfpValueSelection& valueSelection ) const;
static QString axisTitle( RimVfpDefines::ProductionVariableType variableType, RimVfpDefines::FlowingPhaseType flowingPhase ); QString axisTitle( RimVfpDefines::ProductionVariableType variableType, RimVfpDefines::FlowingPhaseType flowingPhase ) const;
static QString getDisplayUnit( RimVfpDefines::ProductionVariableType variableType ); QString getDisplayUnit( RimVfpDefines::ProductionVariableType variableType ) const;
static QString getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType variableType ); QString getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType variableType ) const;
double convertToDisplayUnit( double value, RimVfpDefines::ProductionVariableType variableType ) const;
static double convertToDisplayUnit( double value, RimVfpDefines::ProductionVariableType variableType ); void convertToDisplayUnit( std::vector<double>& values, RimVfpDefines::ProductionVariableType variableType ) const;
static void convertToDisplayUnit( std::vector<double>& values, RimVfpDefines::ProductionVariableType variableType );
static QString textForPlotData( const VfpPlotData& plotData ); static QString textForPlotData( const VfpPlotData& plotData );
@@ -18,8 +18,11 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "ProjectDataModel/VerticalFlowPerformance/RimVfpDefines.h"
#include "RigVfpTables.h" #include "RigVfpTables.h"
#include "opm/input/eclipse/Units/UnitSystem.hpp"
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -81,3 +84,101 @@ TEST( RigVfpTables, SingleValue )
EXPECT_EQ( 0, closestIndices[1] ); EXPECT_EQ( 0, closestIndices[1] );
EXPECT_EQ( -1, closestIndices[2] ); EXPECT_EQ( -1, closestIndices[2] );
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( RigVfpTables, FieldUnitDisplayUnits )
{
// Test field unit system
Opm::UnitSystem fieldUnitSystem = Opm::UnitSystem::newFIELD();
QString thpUnit = RigVfpTables::getDisplayUnit( RimVfpDefines::ProductionVariableType::THP, fieldUnitSystem );
EXPECT_EQ( "psia", thpUnit.toStdString() );
QString flowRateUnit = RigVfpTables::getDisplayUnit( RimVfpDefines::ProductionVariableType::FLOW_RATE, fieldUnitSystem );
EXPECT_EQ( "stb/day", flowRateUnit.toStdString() );
QString thpUnitBracket = RigVfpTables::getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType::THP, fieldUnitSystem );
EXPECT_EQ( "[psia]", thpUnitBracket.toStdString() );
QString flowRateUnitBracket = RigVfpTables::getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType::FLOW_RATE, fieldUnitSystem );
EXPECT_EQ( "[stb/day]", flowRateUnitBracket.toStdString() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( RigVfpTables, MetricUnitDisplayUnits )
{
// Test metric unit system
Opm::UnitSystem metricUnitSystem = Opm::UnitSystem::newMETRIC();
QString thpUnit = RigVfpTables::getDisplayUnit( RimVfpDefines::ProductionVariableType::THP, metricUnitSystem );
EXPECT_EQ( "Bar", thpUnit.toStdString() );
QString flowRateUnit = RigVfpTables::getDisplayUnit( RimVfpDefines::ProductionVariableType::FLOW_RATE, metricUnitSystem );
EXPECT_EQ( "Sm3/day", flowRateUnit.toStdString() );
QString thpUnitBracket = RigVfpTables::getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType::THP, metricUnitSystem );
EXPECT_EQ( "[Bar]", thpUnitBracket.toStdString() );
QString flowRateUnitBracket = RigVfpTables::getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType::FLOW_RATE, metricUnitSystem );
EXPECT_EQ( "[Sm3/day]", flowRateUnitBracket.toStdString() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( RigVfpTables, FieldUnitConversion )
{
// Test field unit conversions
Opm::UnitSystem fieldUnitSystem = Opm::UnitSystem::newFIELD();
// Test THP conversion for field units (no conversion should be done, data already in psi)
double thpValue = 100.0; // psi
double convertedThp = RigVfpTables::convertToDisplayUnit( thpValue, RimVfpDefines::ProductionVariableType::THP, fieldUnitSystem );
EXPECT_DOUBLE_EQ( 100.0, convertedThp ); // Should remain unchanged
// Test flow rate conversion for field units (convert from stb/sec to stb/day)
double flowRateValue = 1.0; // stb/sec
double convertedFlowRate =
RigVfpTables::convertToDisplayUnit( flowRateValue, RimVfpDefines::ProductionVariableType::FLOW_RATE, fieldUnitSystem );
EXPECT_DOUBLE_EQ( 86400.0, convertedFlowRate ); // 1 * 24 * 60 * 60 = 86400 stb/day
// Test vector conversion
std::vector<double> flowRateValues = { 1.0, 2.0, 0.5 }; // stb/sec
RigVfpTables::convertToDisplayUnit( flowRateValues, RimVfpDefines::ProductionVariableType::FLOW_RATE, fieldUnitSystem );
EXPECT_DOUBLE_EQ( 86400.0, flowRateValues[0] ); // 86400 stb/day
EXPECT_DOUBLE_EQ( 172800.0, flowRateValues[1] ); // 172800 stb/day
EXPECT_DOUBLE_EQ( 43200.0, flowRateValues[2] ); // 43200 stb/day
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( RigVfpTables, MetricUnitConversion )
{
// Test metric unit conversions
Opm::UnitSystem metricUnitSystem = Opm::UnitSystem::newMETRIC();
// Test THP conversion for metric units (Pascal to Bar)
double thpValue = 100000.0; // Pascal
double convertedThp = RigVfpTables::convertToDisplayUnit( thpValue, RimVfpDefines::ProductionVariableType::THP, metricUnitSystem );
EXPECT_DOUBLE_EQ( 1.0, convertedThp ); // 100000 Pa = 1 Bar
// Test flow rate conversion for metric units (m3/sec to m3/day)
double flowRateValue = 1.0; // m3/sec
double convertedFlowRate =
RigVfpTables::convertToDisplayUnit( flowRateValue, RimVfpDefines::ProductionVariableType::FLOW_RATE, metricUnitSystem );
EXPECT_DOUBLE_EQ( 86400.0, convertedFlowRate ); // 1 * 24 * 60 * 60 = 86400 m3/day
// Test vector conversion
std::vector<double> thpValues = { 100000.0, 200000.0, 50000.0 }; // Pascal
RigVfpTables::convertToDisplayUnit( thpValues, RimVfpDefines::ProductionVariableType::THP, metricUnitSystem );
EXPECT_DOUBLE_EQ( 1.0, thpValues[0] ); // 1 Bar
EXPECT_DOUBLE_EQ( 2.0, thpValues[1] ); // 2 Bar
EXPECT_DOUBLE_EQ( 0.5, thpValues[2] ); // 0.5 Bar
}