2024-05-13 08:54:40 +02:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Copyright (C) 2024 Equinor ASA
|
|
|
|
|
//
|
|
|
|
|
// ResInsight is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
//
|
|
|
|
|
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
|
|
|
|
// for more details.
|
|
|
|
|
//
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#include "RigVfpTables.h"
|
|
|
|
|
|
|
|
|
|
#include "RiaEclipseUnitTools.h"
|
|
|
|
|
|
|
|
|
|
#include "cafAppEnum.h"
|
|
|
|
|
|
|
|
|
|
#include "opm/input/eclipse/Schedule/VFPInjTable.hpp"
|
|
|
|
|
#include "opm/input/eclipse/Schedule/VFPProdTable.hpp"
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
VfpPlotData RigVfpTables::populatePlotData( const Opm::VFPInjTable& table,
|
|
|
|
|
RimVfpDefines::InterpolatedVariableType interpolatedVariable,
|
|
|
|
|
RimVfpDefines::FlowingPhaseType flowingPhase )
|
|
|
|
|
{
|
|
|
|
|
VfpPlotData plotData;
|
|
|
|
|
|
|
|
|
|
QString xAxisTitle = axisTitle( RimVfpDefines::ProductionVariableType::FLOW_RATE, flowingPhase );
|
|
|
|
|
plotData.setXAxisTitle( xAxisTitle );
|
|
|
|
|
|
|
|
|
|
QString yAxisTitle = QString( "%1 %2" ).arg( caf::AppEnum<RimVfpDefines::InterpolatedVariableType>::uiText( interpolatedVariable ),
|
|
|
|
|
getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType::THP ) );
|
|
|
|
|
plotData.setYAxisTitle( yAxisTitle );
|
|
|
|
|
|
|
|
|
|
std::vector<double> thpValues = table.getTHPAxis();
|
|
|
|
|
|
|
|
|
|
for ( size_t thp = 0; thp < thpValues.size(); thp++ )
|
|
|
|
|
{
|
|
|
|
|
size_t numValues = table.getFloAxis().size();
|
|
|
|
|
std::vector<double> xVals = table.getFloAxis();
|
|
|
|
|
std::vector<double> yVals( numValues, 0.0 );
|
|
|
|
|
for ( size_t y = 0; y < numValues; y++ )
|
|
|
|
|
{
|
|
|
|
|
yVals[y] = table( thp, y );
|
|
|
|
|
if ( interpolatedVariable == RimVfpDefines::InterpolatedVariableType::BHP_THP_DIFF )
|
|
|
|
|
{
|
|
|
|
|
yVals[y] -= thpValues[thp];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double value = convertToDisplayUnit( thpValues[thp], RimVfpDefines::ProductionVariableType::THP );
|
|
|
|
|
QString unit = getDisplayUnit( RimVfpDefines::ProductionVariableType::THP );
|
|
|
|
|
QString title = QString( "%1 [%2]: %3" )
|
|
|
|
|
.arg( caf::AppEnum<RimVfpDefines::ProductionVariableType>::uiText( RimVfpDefines::ProductionVariableType::THP ) )
|
|
|
|
|
.arg( unit )
|
|
|
|
|
.arg( value );
|
|
|
|
|
|
|
|
|
|
convertToDisplayUnit( yVals, RimVfpDefines::ProductionVariableType::THP );
|
|
|
|
|
convertToDisplayUnit( xVals, RimVfpDefines::ProductionVariableType::FLOW_RATE );
|
|
|
|
|
|
|
|
|
|
plotData.appendCurve( title, xVals, yVals );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return plotData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
VfpPlotData RigVfpTables::populatePlotData( const Opm::VFPProdTable& table,
|
|
|
|
|
RimVfpDefines::ProductionVariableType primaryVariable,
|
|
|
|
|
RimVfpDefines::ProductionVariableType familyVariable,
|
|
|
|
|
RimVfpDefines::InterpolatedVariableType interpolatedVariable,
|
|
|
|
|
RimVfpDefines::FlowingPhaseType flowingPhase,
|
|
|
|
|
const VfpTableSelection& tableSelection )
|
|
|
|
|
{
|
|
|
|
|
VfpPlotData plotData;
|
|
|
|
|
|
|
|
|
|
QString xAxisTitle = axisTitle( primaryVariable, flowingPhase );
|
|
|
|
|
plotData.setXAxisTitle( xAxisTitle );
|
|
|
|
|
|
|
|
|
|
QString yAxisTitle = QString( "%1 %2" ).arg( caf::AppEnum<RimVfpDefines::InterpolatedVariableType>::uiText( interpolatedVariable ),
|
|
|
|
|
getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType::THP ) );
|
|
|
|
|
plotData.setYAxisTitle( yAxisTitle );
|
|
|
|
|
|
|
|
|
|
size_t numFamilyValues = getProductionTableData( table, familyVariable ).size();
|
|
|
|
|
for ( size_t familyIdx = 0; familyIdx < numFamilyValues; familyIdx++ )
|
|
|
|
|
{
|
|
|
|
|
std::vector<double> primaryAxisValues = getProductionTableData( table, primaryVariable );
|
|
|
|
|
std::vector<double> familyVariableValues = getProductionTableData( table, familyVariable );
|
|
|
|
|
std::vector<double> thpValues = getProductionTableData( table, RimVfpDefines::ProductionVariableType::THP );
|
|
|
|
|
|
|
|
|
|
size_t numValues = primaryAxisValues.size();
|
|
|
|
|
std::vector<double> yVals( numValues, 0.0 );
|
|
|
|
|
|
|
|
|
|
for ( size_t y = 0; y < numValues; y++ )
|
|
|
|
|
{
|
|
|
|
|
size_t wfr_idx =
|
|
|
|
|
getVariableIndex( table, RimVfpDefines::ProductionVariableType::WATER_CUT, primaryVariable, y, familyVariable, familyIdx, tableSelection );
|
|
|
|
|
size_t gfr_idx = getVariableIndex( table,
|
|
|
|
|
RimVfpDefines::ProductionVariableType::GAS_LIQUID_RATIO,
|
|
|
|
|
primaryVariable,
|
|
|
|
|
y,
|
|
|
|
|
familyVariable,
|
|
|
|
|
familyIdx,
|
|
|
|
|
tableSelection );
|
|
|
|
|
size_t alq_idx = getVariableIndex( table,
|
|
|
|
|
RimVfpDefines::ProductionVariableType::ARTIFICIAL_LIFT_QUANTITY,
|
|
|
|
|
primaryVariable,
|
|
|
|
|
y,
|
|
|
|
|
familyVariable,
|
|
|
|
|
familyIdx,
|
|
|
|
|
tableSelection );
|
|
|
|
|
size_t flo_idx =
|
|
|
|
|
getVariableIndex( table, RimVfpDefines::ProductionVariableType::FLOW_RATE, primaryVariable, y, familyVariable, familyIdx, tableSelection );
|
|
|
|
|
size_t thp_idx =
|
|
|
|
|
getVariableIndex( table, RimVfpDefines::ProductionVariableType::THP, primaryVariable, y, familyVariable, familyIdx, tableSelection );
|
|
|
|
|
|
|
|
|
|
yVals[y] = table( thp_idx, wfr_idx, gfr_idx, alq_idx, flo_idx );
|
|
|
|
|
if ( interpolatedVariable == RimVfpDefines::InterpolatedVariableType::BHP_THP_DIFF )
|
|
|
|
|
{
|
|
|
|
|
yVals[y] -= thpValues[thp_idx];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double familyValue = convertToDisplayUnit( familyVariableValues[familyIdx], familyVariable );
|
|
|
|
|
QString familyUnit = getDisplayUnit( familyVariable );
|
|
|
|
|
QString familyTitle = QString( "%1: %2 %3" )
|
|
|
|
|
.arg( caf::AppEnum<RimVfpDefines::ProductionVariableType>::uiText( familyVariable ) )
|
|
|
|
|
.arg( familyValue )
|
|
|
|
|
.arg( familyUnit );
|
|
|
|
|
|
|
|
|
|
convertToDisplayUnit( yVals, RimVfpDefines::ProductionVariableType::THP );
|
|
|
|
|
convertToDisplayUnit( primaryAxisValues, primaryVariable );
|
|
|
|
|
|
|
|
|
|
plotData.appendCurve( familyTitle, primaryAxisValues, yVals );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return plotData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
VfpPlotData RigVfpTables::populatePlotData( int tableIndex,
|
|
|
|
|
RimVfpDefines::ProductionVariableType primaryVariable,
|
|
|
|
|
RimVfpDefines::ProductionVariableType familyVariable,
|
|
|
|
|
RimVfpDefines::InterpolatedVariableType interpolatedVariable,
|
|
|
|
|
RimVfpDefines::FlowingPhaseType flowingPhase,
|
|
|
|
|
const VfpTableSelection& tableSelection ) const
|
|
|
|
|
{
|
|
|
|
|
auto prodTable = productionTable( tableIndex );
|
|
|
|
|
if ( prodTable.has_value() )
|
|
|
|
|
{
|
|
|
|
|
return populatePlotData( *prodTable, primaryVariable, familyVariable, interpolatedVariable, flowingPhase, tableSelection );
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
auto injContainer = injectionTable( tableIndex );
|
|
|
|
|
if ( injContainer.has_value() )
|
|
|
|
|
{
|
|
|
|
|
return populatePlotData( *injContainer, interpolatedVariable, flowingPhase );
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-29 12:55:45 +02:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
VfpPlotData RigVfpTables::populatePlotData( int tableIndex,
|
|
|
|
|
RimVfpDefines::ProductionVariableType primaryVariable,
|
|
|
|
|
RimVfpDefines::ProductionVariableType familyVariable,
|
|
|
|
|
RimVfpDefines::InterpolatedVariableType interpolatedVariable,
|
|
|
|
|
RimVfpDefines::FlowingPhaseType flowingPhase,
|
|
|
|
|
const VfpValueSelection& valueSelection ) const
|
|
|
|
|
{
|
|
|
|
|
auto prodTable = productionTable( tableIndex );
|
|
|
|
|
if ( prodTable.has_value() )
|
|
|
|
|
{
|
|
|
|
|
return populatePlotData( *prodTable, primaryVariable, familyVariable, interpolatedVariable, flowingPhase, valueSelection );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto injContainer = injectionTable( tableIndex );
|
|
|
|
|
if ( injContainer.has_value() )
|
|
|
|
|
{
|
|
|
|
|
return populatePlotData( *injContainer, interpolatedVariable, flowingPhase );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
VfpPlotData RigVfpTables::populatePlotData( const Opm::VFPProdTable& table,
|
|
|
|
|
RimVfpDefines::ProductionVariableType primaryVariable,
|
|
|
|
|
RimVfpDefines::ProductionVariableType familyVariable,
|
|
|
|
|
RimVfpDefines::InterpolatedVariableType interpolatedVariable,
|
|
|
|
|
RimVfpDefines::FlowingPhaseType flowingPhase,
|
|
|
|
|
const VfpValueSelection& valueSelection )
|
|
|
|
|
{
|
|
|
|
|
VfpPlotData plotData;
|
|
|
|
|
|
|
|
|
|
QString xAxisTitle = axisTitle( primaryVariable, flowingPhase );
|
|
|
|
|
plotData.setXAxisTitle( xAxisTitle );
|
|
|
|
|
|
|
|
|
|
QString yAxisTitle = QString( "%1 %2" ).arg( caf::AppEnum<RimVfpDefines::InterpolatedVariableType>::uiText( interpolatedVariable ),
|
|
|
|
|
getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType::THP ) );
|
|
|
|
|
plotData.setYAxisTitle( yAxisTitle );
|
|
|
|
|
|
|
|
|
|
std::vector<double> familyFilterValues = valueSelection.familyValues;
|
|
|
|
|
|
|
|
|
|
size_t numFamilyValues = getProductionTableData( table, familyVariable ).size();
|
|
|
|
|
for ( size_t familyIdx = 0; familyIdx < numFamilyValues; familyIdx++ )
|
|
|
|
|
{
|
|
|
|
|
std::vector<double> primaryAxisValues = getProductionTableData( table, primaryVariable );
|
|
|
|
|
std::vector<double> familyVariableValues = getProductionTableData( table, familyVariable );
|
|
|
|
|
std::vector<double> thpValues = getProductionTableData( table, RimVfpDefines::ProductionVariableType::THP );
|
|
|
|
|
|
|
|
|
|
// Skip if the family value is not in the filter
|
|
|
|
|
auto currentFamilyValue = familyVariableValues[familyIdx];
|
|
|
|
|
auto it = std::find( familyFilterValues.begin(), familyFilterValues.end(), currentFamilyValue );
|
|
|
|
|
if ( it == familyFilterValues.end() ) continue;
|
|
|
|
|
|
|
|
|
|
size_t numValues = primaryAxisValues.size();
|
|
|
|
|
std::vector<double> yVals( numValues, 0.0 );
|
|
|
|
|
|
|
|
|
|
for ( size_t y = 0; y < numValues; y++ )
|
|
|
|
|
{
|
|
|
|
|
auto currentPrimaryValue = primaryAxisValues[y];
|
|
|
|
|
|
|
|
|
|
size_t wfr_idx = getVariableIndexForValue( table,
|
|
|
|
|
RimVfpDefines::ProductionVariableType::WATER_CUT,
|
|
|
|
|
primaryVariable,
|
|
|
|
|
currentPrimaryValue,
|
|
|
|
|
familyVariable,
|
|
|
|
|
currentFamilyValue,
|
|
|
|
|
valueSelection );
|
|
|
|
|
size_t gfr_idx = getVariableIndexForValue( table,
|
|
|
|
|
RimVfpDefines::ProductionVariableType::GAS_LIQUID_RATIO,
|
|
|
|
|
primaryVariable,
|
|
|
|
|
currentPrimaryValue,
|
|
|
|
|
familyVariable,
|
|
|
|
|
currentFamilyValue,
|
|
|
|
|
valueSelection );
|
|
|
|
|
size_t alq_idx = getVariableIndexForValue( table,
|
|
|
|
|
RimVfpDefines::ProductionVariableType::ARTIFICIAL_LIFT_QUANTITY,
|
|
|
|
|
primaryVariable,
|
|
|
|
|
currentPrimaryValue,
|
|
|
|
|
familyVariable,
|
|
|
|
|
currentFamilyValue,
|
|
|
|
|
valueSelection );
|
|
|
|
|
size_t flo_idx = getVariableIndexForValue( table,
|
|
|
|
|
RimVfpDefines::ProductionVariableType::FLOW_RATE,
|
|
|
|
|
primaryVariable,
|
|
|
|
|
currentPrimaryValue,
|
|
|
|
|
familyVariable,
|
|
|
|
|
currentFamilyValue,
|
|
|
|
|
valueSelection );
|
|
|
|
|
size_t thp_idx = getVariableIndexForValue( table,
|
|
|
|
|
RimVfpDefines::ProductionVariableType::THP,
|
|
|
|
|
primaryVariable,
|
|
|
|
|
currentPrimaryValue,
|
|
|
|
|
familyVariable,
|
|
|
|
|
currentFamilyValue,
|
|
|
|
|
valueSelection );
|
|
|
|
|
|
|
|
|
|
yVals[y] = table( thp_idx, wfr_idx, gfr_idx, alq_idx, flo_idx );
|
|
|
|
|
if ( interpolatedVariable == RimVfpDefines::InterpolatedVariableType::BHP_THP_DIFF )
|
|
|
|
|
{
|
|
|
|
|
yVals[y] -= thpValues[thp_idx];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double familyValue = convertToDisplayUnit( currentFamilyValue, familyVariable );
|
|
|
|
|
QString familyUnit = getDisplayUnit( familyVariable );
|
|
|
|
|
QString familyTitle = QString( "%1: %2 %3" )
|
|
|
|
|
.arg( caf::AppEnum<RimVfpDefines::ProductionVariableType>::uiText( familyVariable ) )
|
|
|
|
|
.arg( familyValue )
|
|
|
|
|
.arg( familyUnit );
|
|
|
|
|
|
|
|
|
|
convertToDisplayUnit( yVals, RimVfpDefines::ProductionVariableType::THP );
|
|
|
|
|
convertToDisplayUnit( primaryAxisValues, primaryVariable );
|
|
|
|
|
|
|
|
|
|
plotData.appendCurve( familyTitle, primaryAxisValues, yVals );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return plotData;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-13 08:54:40 +02:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
QString RigVfpTables::asciiDataForTable( int tableNumber,
|
|
|
|
|
RimVfpDefines::ProductionVariableType primaryVariable,
|
|
|
|
|
RimVfpDefines::ProductionVariableType familyVariable,
|
|
|
|
|
RimVfpDefines::InterpolatedVariableType interpolatedVariable,
|
|
|
|
|
RimVfpDefines::FlowingPhaseType flowingPhase,
|
|
|
|
|
const VfpTableSelection& tableSelection ) const
|
|
|
|
|
{
|
|
|
|
|
VfpPlotData plotData;
|
|
|
|
|
auto prodTable = productionTable( tableNumber );
|
|
|
|
|
if ( prodTable.has_value() )
|
|
|
|
|
{
|
|
|
|
|
plotData = populatePlotData( *prodTable, primaryVariable, familyVariable, interpolatedVariable, flowingPhase, tableSelection );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
auto injTable = injectionTable( tableNumber );
|
|
|
|
|
if ( injTable.has_value() )
|
|
|
|
|
{
|
|
|
|
|
plotData = populatePlotData( *injTable, interpolatedVariable, flowingPhase );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return textForPlotData( plotData );
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-29 12:55:45 +02:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
std::vector<int> RigVfpTables::findClosestIndices( const std::vector<double>& sourceValues, const std::vector<double>& valuesToMatch )
|
|
|
|
|
{
|
|
|
|
|
std::vector<int> result( sourceValues.size(), -1 );
|
|
|
|
|
|
|
|
|
|
// Returns the indices of the closest values in valuesToMatch for each value in sourceValues.
|
|
|
|
|
for ( size_t i = 0; i < sourceValues.size(); ++i )
|
|
|
|
|
{
|
|
|
|
|
double minDistance = std::numeric_limits<double>::max();
|
|
|
|
|
int closestIndex = -1;
|
|
|
|
|
|
|
|
|
|
for ( size_t j = 0; j < valuesToMatch.size(); ++j )
|
|
|
|
|
{
|
|
|
|
|
double distance = std::abs( sourceValues[i] - valuesToMatch[j] );
|
|
|
|
|
if ( distance < minDistance )
|
|
|
|
|
{
|
|
|
|
|
minDistance = distance;
|
|
|
|
|
closestIndex = static_cast<int>( j );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( closestIndex < static_cast<int>( valuesToMatch.size() ) )
|
|
|
|
|
{
|
|
|
|
|
result[i] = closestIndex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
std::vector<int> RigVfpTables::uniqueClosestIndices( const std::vector<double>& sourceValues, const std::vector<double>& valuesToMatch )
|
|
|
|
|
{
|
|
|
|
|
// Find the closest value in valuesForMatch for each value in sourceValues
|
|
|
|
|
std::vector<double> distances( sourceValues.size(), std::numeric_limits<double>::max() );
|
|
|
|
|
|
|
|
|
|
auto closestIndices = findClosestIndices( sourceValues, valuesToMatch );
|
|
|
|
|
|
|
|
|
|
for ( size_t i = 0; i < sourceValues.size(); i++ )
|
|
|
|
|
{
|
|
|
|
|
if ( closestIndices[i] >= 0 )
|
|
|
|
|
{
|
|
|
|
|
distances[i] = std::abs( sourceValues[i] - valuesToMatch[closestIndices[i]] );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while ( std::any_of( distances.begin(), distances.end(), []( double val ) { return val != std::numeric_limits<double>::max(); } ) )
|
|
|
|
|
{
|
|
|
|
|
// find the index of the smallest value in minDistance
|
|
|
|
|
auto minDistanceIt = std::min_element( distances.begin(), distances.end() );
|
|
|
|
|
if ( minDistanceIt == distances.end() )
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto minDistanceIndex = std::distance( distances.begin(), minDistanceIt );
|
|
|
|
|
auto matchingIndex = closestIndices[minDistanceIndex];
|
|
|
|
|
|
|
|
|
|
if ( matchingIndex > -1 )
|
|
|
|
|
{
|
|
|
|
|
// Remove all references to the matching index
|
|
|
|
|
for ( size_t i = 0; i < sourceValues.size(); i++ )
|
|
|
|
|
{
|
|
|
|
|
if ( i == static_cast<size_t>( minDistanceIndex ) )
|
|
|
|
|
{
|
|
|
|
|
distances[i] = std::numeric_limits<double>::max();
|
|
|
|
|
}
|
|
|
|
|
else if ( closestIndices[i] == matchingIndex )
|
|
|
|
|
{
|
|
|
|
|
distances[i] = std::numeric_limits<double>::max();
|
|
|
|
|
closestIndices[i] = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return closestIndices;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-13 08:54:40 +02:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
QString RigVfpTables::axisTitle( RimVfpDefines::ProductionVariableType variableType, RimVfpDefines::FlowingPhaseType flowingPhase )
|
|
|
|
|
{
|
|
|
|
|
QString title;
|
|
|
|
|
|
|
|
|
|
if ( flowingPhase == RimVfpDefines::FlowingPhaseType::GAS )
|
|
|
|
|
{
|
|
|
|
|
title = "Gas ";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
title = "Liquid ";
|
|
|
|
|
}
|
|
|
|
|
title += QString( "%1 %2" ).arg( caf::AppEnum<RimVfpDefines::ProductionVariableType>::uiText( variableType ),
|
|
|
|
|
getDisplayUnitWithBracket( variableType ) );
|
|
|
|
|
|
|
|
|
|
return title;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
QString RigVfpTables::getDisplayUnit( RimVfpDefines::ProductionVariableType variableType )
|
|
|
|
|
{
|
|
|
|
|
if ( variableType == RimVfpDefines::ProductionVariableType::THP ) return "Bar";
|
|
|
|
|
|
|
|
|
|
if ( variableType == RimVfpDefines::ProductionVariableType::FLOW_RATE ) return "Sm3/day";
|
|
|
|
|
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
QString RigVfpTables::getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType variableType )
|
|
|
|
|
{
|
|
|
|
|
QString unit = getDisplayUnit( variableType );
|
|
|
|
|
if ( !unit.isEmpty() ) return QString( "[%1]" ).arg( unit );
|
|
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
double RigVfpTables::convertToDisplayUnit( double value, RimVfpDefines::ProductionVariableType variableType )
|
|
|
|
|
{
|
|
|
|
|
if ( variableType == RimVfpDefines::ProductionVariableType::THP )
|
|
|
|
|
{
|
|
|
|
|
return RiaEclipseUnitTools::pascalToBar( value );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( variableType == RimVfpDefines::ProductionVariableType::FLOW_RATE )
|
|
|
|
|
{
|
|
|
|
|
// Convert to m3/sec to m3/day
|
|
|
|
|
return value * static_cast<double>( 24 * 60 * 60 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RigVfpTables::convertToDisplayUnit( std::vector<double>& values, RimVfpDefines::ProductionVariableType variableType )
|
|
|
|
|
{
|
|
|
|
|
for ( double& value : values )
|
|
|
|
|
value = convertToDisplayUnit( value, variableType );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
QString RigVfpTables::textForPlotData( const VfpPlotData& plotData )
|
|
|
|
|
{
|
|
|
|
|
QString dataText;
|
|
|
|
|
|
|
|
|
|
if ( plotData.size() > 0 )
|
|
|
|
|
{
|
|
|
|
|
// The curves should have same dimensions
|
|
|
|
|
const size_t curveSize = plotData.curveSize( 0 );
|
|
|
|
|
|
|
|
|
|
// Generate the headers for the columns
|
|
|
|
|
// First column is the primary variable
|
|
|
|
|
QString columnTitleLine( plotData.xAxisTitle() );
|
|
|
|
|
|
|
|
|
|
// Then one column per "family"
|
|
|
|
|
for ( size_t s = 0; s < plotData.size(); s++ )
|
|
|
|
|
{
|
|
|
|
|
columnTitleLine.append( QString( "\t%1" ).arg( plotData.curveTitle( s ) ) );
|
|
|
|
|
}
|
|
|
|
|
columnTitleLine.append( "\n" );
|
|
|
|
|
|
|
|
|
|
dataText.append( columnTitleLine );
|
|
|
|
|
|
|
|
|
|
// Add the rows: one row per primary variable value
|
|
|
|
|
for ( size_t idx = 0; idx < curveSize; idx++ )
|
|
|
|
|
{
|
|
|
|
|
QString line;
|
|
|
|
|
|
|
|
|
|
// First item on each line is the primary variable
|
|
|
|
|
line.append( QString( "%1" ).arg( plotData.xData( 0 )[idx] ) );
|
|
|
|
|
|
|
|
|
|
for ( size_t s = 0; s < plotData.size(); s++ )
|
|
|
|
|
{
|
|
|
|
|
line.append( QString( "\t%1" ).arg( plotData.yData( s )[idx] ) );
|
|
|
|
|
}
|
|
|
|
|
dataText.append( line );
|
|
|
|
|
dataText.append( "\n" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dataText;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
std::vector<double> RigVfpTables::getProductionTableData( const Opm::VFPProdTable& table, RimVfpDefines::ProductionVariableType variableType )
|
|
|
|
|
{
|
|
|
|
|
std::vector<double> xVals;
|
|
|
|
|
if ( variableType == RimVfpDefines::ProductionVariableType::WATER_CUT )
|
|
|
|
|
{
|
|
|
|
|
xVals = table.getWFRAxis();
|
|
|
|
|
}
|
|
|
|
|
else if ( variableType == RimVfpDefines::ProductionVariableType::GAS_LIQUID_RATIO )
|
|
|
|
|
{
|
|
|
|
|
xVals = table.getGFRAxis();
|
|
|
|
|
}
|
|
|
|
|
else if ( variableType == RimVfpDefines::ProductionVariableType::ARTIFICIAL_LIFT_QUANTITY )
|
|
|
|
|
{
|
|
|
|
|
xVals = table.getALQAxis();
|
|
|
|
|
}
|
|
|
|
|
else if ( variableType == RimVfpDefines::ProductionVariableType::FLOW_RATE )
|
|
|
|
|
{
|
|
|
|
|
xVals = table.getFloAxis();
|
|
|
|
|
}
|
|
|
|
|
else if ( variableType == RimVfpDefines::ProductionVariableType::THP )
|
|
|
|
|
{
|
|
|
|
|
xVals = table.getTHPAxis();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return xVals;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
std::vector<double> RigVfpTables::getProductionTableData( int tableIndex, RimVfpDefines::ProductionVariableType variableType ) const
|
|
|
|
|
{
|
|
|
|
|
auto prodTable = productionTable( tableIndex );
|
|
|
|
|
if ( prodTable.has_value() )
|
|
|
|
|
{
|
|
|
|
|
return getProductionTableData( *prodTable, variableType );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
size_t RigVfpTables::getVariableIndex( const Opm::VFPProdTable& table,
|
|
|
|
|
RimVfpDefines::ProductionVariableType targetVariable,
|
|
|
|
|
RimVfpDefines::ProductionVariableType primaryVariable,
|
|
|
|
|
size_t primaryValue,
|
|
|
|
|
RimVfpDefines::ProductionVariableType familyVariable,
|
|
|
|
|
size_t familyValue,
|
|
|
|
|
const VfpTableSelection& tableSelection )
|
|
|
|
|
{
|
|
|
|
|
if ( targetVariable == primaryVariable ) return primaryValue;
|
|
|
|
|
if ( targetVariable == familyVariable ) return familyValue;
|
|
|
|
|
if ( targetVariable == RimVfpDefines::ProductionVariableType::WATER_CUT ) return tableSelection.waterCutIdx;
|
|
|
|
|
if ( targetVariable == RimVfpDefines::ProductionVariableType::GAS_LIQUID_RATIO ) return tableSelection.gasLiquidRatioIdx;
|
|
|
|
|
if ( targetVariable == RimVfpDefines::ProductionVariableType::ARTIFICIAL_LIFT_QUANTITY )
|
|
|
|
|
return tableSelection.articifialLiftQuantityIdx;
|
|
|
|
|
if ( targetVariable == RimVfpDefines::ProductionVariableType::FLOW_RATE ) return tableSelection.flowRateIdx;
|
|
|
|
|
if ( targetVariable == RimVfpDefines::ProductionVariableType::THP ) return tableSelection.thpIdx;
|
|
|
|
|
|
|
|
|
|
return getProductionTableData( table, targetVariable ).size() - 1;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-29 12:55:45 +02:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
size_t RigVfpTables::getVariableIndexForValue( const Opm::VFPProdTable& table,
|
|
|
|
|
RimVfpDefines::ProductionVariableType targetVariable,
|
|
|
|
|
RimVfpDefines::ProductionVariableType primaryVariable,
|
|
|
|
|
double primaryValue,
|
|
|
|
|
RimVfpDefines::ProductionVariableType familyVariable,
|
|
|
|
|
double familyValue,
|
|
|
|
|
const VfpValueSelection& valueSelection )
|
|
|
|
|
{
|
|
|
|
|
auto findClosestIndex = []( const std::vector<double>& values, const double value )
|
|
|
|
|
{
|
|
|
|
|
auto it = std::lower_bound( values.begin(), values.end(), value );
|
|
|
|
|
if ( it == values.begin() )
|
|
|
|
|
{
|
|
|
|
|
return (size_t)0;
|
|
|
|
|
}
|
|
|
|
|
if ( it == values.end() )
|
|
|
|
|
{
|
|
|
|
|
return values.size() - 1;
|
|
|
|
|
}
|
|
|
|
|
if ( *it == value )
|
|
|
|
|
{
|
|
|
|
|
return (size_t)std::distance( values.begin(), it );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto prev = it - 1;
|
|
|
|
|
if ( std::abs( *prev - value ) < std::abs( *it - value ) )
|
|
|
|
|
{
|
|
|
|
|
return (size_t)std::distance( values.begin(), prev );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (size_t)std::distance( values.begin(), it );
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if ( targetVariable == primaryVariable )
|
|
|
|
|
{
|
|
|
|
|
const auto values = getProductionTableData( table, targetVariable );
|
|
|
|
|
return findClosestIndex( values, primaryValue );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( targetVariable == familyVariable )
|
|
|
|
|
{
|
|
|
|
|
const auto values = getProductionTableData( table, targetVariable );
|
|
|
|
|
return findClosestIndex( values, familyValue );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto findClosestIndexForVariable =
|
|
|
|
|
[&]( RimVfpDefines::ProductionVariableType targetVariable, const double selectedValue, const Opm::VFPProdTable& table )
|
|
|
|
|
{
|
|
|
|
|
const auto values = getProductionTableData( table, targetVariable );
|
|
|
|
|
return findClosestIndex( values, selectedValue );
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
switch ( targetVariable )
|
|
|
|
|
{
|
|
|
|
|
case RimVfpDefines::ProductionVariableType::WATER_CUT:
|
|
|
|
|
{
|
|
|
|
|
return findClosestIndexForVariable( targetVariable, valueSelection.waterCutValue, table );
|
|
|
|
|
}
|
|
|
|
|
case RimVfpDefines::ProductionVariableType::GAS_LIQUID_RATIO:
|
|
|
|
|
{
|
|
|
|
|
return findClosestIndexForVariable( targetVariable, valueSelection.gasLiquidRatioValue, table );
|
|
|
|
|
}
|
|
|
|
|
case RimVfpDefines::ProductionVariableType::ARTIFICIAL_LIFT_QUANTITY:
|
|
|
|
|
{
|
2024-06-12 07:52:37 +02:00
|
|
|
return findClosestIndexForVariable( targetVariable, valueSelection.artificialLiftQuantityValue, table );
|
2024-05-29 12:55:45 +02:00
|
|
|
}
|
|
|
|
|
case RimVfpDefines::ProductionVariableType::FLOW_RATE:
|
|
|
|
|
{
|
|
|
|
|
return findClosestIndexForVariable( targetVariable, valueSelection.flowRateValue, table );
|
|
|
|
|
}
|
|
|
|
|
case RimVfpDefines::ProductionVariableType::THP:
|
|
|
|
|
{
|
|
|
|
|
return findClosestIndexForVariable( targetVariable, valueSelection.thpValue, table );
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-13 08:54:40 +02:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
std::optional<Opm::VFPInjTable> RigVfpTables::injectionTable( int tableNumber ) const
|
|
|
|
|
{
|
|
|
|
|
for ( const auto& table : m_injectionTables )
|
|
|
|
|
{
|
|
|
|
|
if ( table.getTableNum() == tableNumber )
|
|
|
|
|
{
|
|
|
|
|
return table;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::nullopt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
std::optional<Opm::VFPProdTable> RigVfpTables::productionTable( int tableNumber ) const
|
|
|
|
|
{
|
|
|
|
|
for ( const auto& table : m_productionTables )
|
|
|
|
|
{
|
|
|
|
|
if ( table.getTableNum() == tableNumber )
|
|
|
|
|
{
|
|
|
|
|
return table;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::nullopt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
RimVfpDefines::FlowingPhaseType RigVfpTables::getFlowingPhaseType( const Opm::VFPProdTable& table )
|
|
|
|
|
{
|
|
|
|
|
switch ( table.getFloType() )
|
|
|
|
|
{
|
|
|
|
|
case Opm::VFPProdTable::FLO_TYPE::FLO_OIL:
|
|
|
|
|
return RimVfpDefines::FlowingPhaseType::OIL;
|
|
|
|
|
case Opm::VFPProdTable::FLO_TYPE::FLO_GAS:
|
|
|
|
|
return RimVfpDefines::FlowingPhaseType::GAS;
|
|
|
|
|
case Opm::VFPProdTable::FLO_TYPE::FLO_LIQ:
|
|
|
|
|
return RimVfpDefines::FlowingPhaseType::LIQUID;
|
|
|
|
|
default:
|
|
|
|
|
return RimVfpDefines::FlowingPhaseType::INVALID;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
RimVfpDefines::FlowingPhaseType RigVfpTables::getFlowingPhaseType( const Opm::VFPInjTable& table )
|
|
|
|
|
{
|
|
|
|
|
switch ( table.getFloType() )
|
|
|
|
|
{
|
|
|
|
|
case Opm::VFPInjTable::FLO_TYPE::FLO_OIL:
|
|
|
|
|
return RimVfpDefines::FlowingPhaseType::OIL;
|
|
|
|
|
case Opm::VFPInjTable::FLO_TYPE::FLO_GAS:
|
|
|
|
|
return RimVfpDefines::FlowingPhaseType::GAS;
|
|
|
|
|
case Opm::VFPInjTable::FLO_TYPE::FLO_WAT:
|
|
|
|
|
return RimVfpDefines::FlowingPhaseType::WATER;
|
|
|
|
|
default:
|
|
|
|
|
return RimVfpDefines::FlowingPhaseType::INVALID;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
RimVfpDefines::FlowingWaterFractionType RigVfpTables::getFlowingWaterFractionType( const Opm::VFPProdTable& table )
|
|
|
|
|
{
|
|
|
|
|
switch ( table.getWFRType() )
|
|
|
|
|
{
|
|
|
|
|
case Opm::VFPProdTable::WFR_TYPE::WFR_WOR:
|
|
|
|
|
return RimVfpDefines::FlowingWaterFractionType::WOR;
|
|
|
|
|
case Opm::VFPProdTable::WFR_TYPE::WFR_WCT:
|
|
|
|
|
return RimVfpDefines::FlowingWaterFractionType::WCT;
|
|
|
|
|
case Opm::VFPProdTable::WFR_TYPE::WFR_WGR:
|
|
|
|
|
return RimVfpDefines::FlowingWaterFractionType::WGR;
|
|
|
|
|
default:
|
|
|
|
|
return RimVfpDefines::FlowingWaterFractionType::INVALID;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
RimVfpDefines::FlowingGasFractionType RigVfpTables::getFlowingGasFractionType( const Opm::VFPProdTable& table )
|
|
|
|
|
{
|
|
|
|
|
switch ( table.getGFRType() )
|
|
|
|
|
{
|
|
|
|
|
case Opm::VFPProdTable::GFR_TYPE::GFR_GOR:
|
|
|
|
|
return RimVfpDefines::FlowingGasFractionType::GOR;
|
|
|
|
|
case Opm::VFPProdTable::GFR_TYPE::GFR_GLR:
|
|
|
|
|
return RimVfpDefines::FlowingGasFractionType::GLR;
|
|
|
|
|
case Opm::VFPProdTable::GFR_TYPE::GFR_OGR:
|
|
|
|
|
return RimVfpDefines::FlowingGasFractionType::OGR;
|
|
|
|
|
default:
|
|
|
|
|
return RimVfpDefines::FlowingGasFractionType::INVALID;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RigVfpTables::addInjectionTable( const Opm::VFPInjTable& table )
|
|
|
|
|
{
|
|
|
|
|
m_injectionTables.push_back( table );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RigVfpTables::addProductionTable( const Opm::VFPProdTable& table )
|
|
|
|
|
{
|
|
|
|
|
m_productionTables.push_back( table );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
std::vector<int> RigVfpTables::injectionTableNumbers() const
|
|
|
|
|
{
|
|
|
|
|
std::vector<int> tableNumbers;
|
|
|
|
|
|
|
|
|
|
for ( const auto& table : m_injectionTables )
|
|
|
|
|
{
|
|
|
|
|
tableNumbers.push_back( table.getTableNum() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return tableNumbers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
std::vector<int> RigVfpTables::productionTableNumbers() const
|
|
|
|
|
{
|
|
|
|
|
std::vector<int> tableNumbers;
|
|
|
|
|
|
|
|
|
|
for ( const auto& table : m_productionTables )
|
|
|
|
|
{
|
|
|
|
|
tableNumbers.push_back( table.getTableNum() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return tableNumbers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
VfpTableInitialData RigVfpTables::getTableInitialData( int tableIndex ) const
|
|
|
|
|
{
|
|
|
|
|
auto prodTable = productionTable( tableIndex );
|
|
|
|
|
if ( prodTable.has_value() )
|
|
|
|
|
{
|
2024-06-12 07:52:37 +02:00
|
|
|
VfpTableInitialData initialData{};
|
2024-05-13 08:54:40 +02:00
|
|
|
initialData.isProductionTable = true;
|
|
|
|
|
initialData.tableNumber = prodTable->getTableNum();
|
|
|
|
|
initialData.datumDepth = prodTable->getDatumDepth();
|
|
|
|
|
initialData.flowingPhase = getFlowingPhaseType( *prodTable );
|
|
|
|
|
initialData.waterFraction = getFlowingWaterFractionType( *prodTable );
|
|
|
|
|
initialData.gasFraction = getFlowingGasFractionType( *prodTable );
|
|
|
|
|
|
|
|
|
|
return initialData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto injTable = injectionTable( tableIndex );
|
|
|
|
|
if ( injTable.has_value() )
|
|
|
|
|
{
|
2024-06-12 07:52:37 +02:00
|
|
|
VfpTableInitialData initialData{};
|
2024-05-13 08:54:40 +02:00
|
|
|
initialData.isProductionTable = false;
|
|
|
|
|
initialData.tableNumber = injTable->getTableNum();
|
|
|
|
|
initialData.datumDepth = injTable->getDatumDepth();
|
|
|
|
|
initialData.flowingPhase = getFlowingPhaseType( *injTable );
|
|
|
|
|
return initialData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
}
|