#7049 AICD : Accumulate flow scaling factor for multiple valves in cell

Add multi lateral support
This commit is contained in:
Magne Sjaastad 2021-05-18 15:17:13 +02:00
parent 3bfeb194a9
commit e8e3dc39b4
2 changed files with 185 additions and 95 deletions

View File

@ -55,6 +55,36 @@ public:
double m_ac;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RicMswTableFormatterTools::AicdWsegvalveData
{
public:
explicit AicdWsegvalveData( const QString& wellName,
const QString& comment,
int segmentNumber,
double flowScalingFactor,
bool isOpen,
const std::array<double, AICD_NUM_PARAMS>& values )
: m_wellName( wellName )
, m_comment( comment )
, m_segmentNumber( segmentNumber )
, m_flowScalingFactor( flowScalingFactor )
, m_isOpen( isOpen )
, m_values( values )
{
}
QString m_wellName;
QString m_comment;
int m_segmentNumber;
double m_flowScalingFactor;
bool m_isOpen;
std::array<double, AICD_NUM_PARAMS> m_values;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -566,113 +596,168 @@ void RicMswTableFormatterTools::generateWsegvalvTableRecursively( gsl::not_null<
//--------------------------------------------------------------------------------------------------
void RicMswTableFormatterTools::generateWsegAicdTable( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo )
{
RifTextDataTableFormatter tighterFormatter( formatter );
tighterFormatter.setColumnSpacing( 1 );
tighterFormatter.setTableRowPrependText( " " );
std::map<size_t, std::vector<AicdWsegvalveData>> aicdValveData;
bool foundValve = false;
generateWsegAicdTableRecursively( exportInfo, exportInfo.mainBoreBranch(), aicdValveData );
for ( auto segment : exportInfo.mainBoreBranch()->segments() )
if ( !aicdValveData.empty() )
{
RifTextDataTableFormatter tighterFormatter( formatter );
tighterFormatter.setColumnSpacing( 1 );
tighterFormatter.setTableRowPrependText( " " );
{
// Write out header for AICD table
std::vector<QString> columnDescriptions =
{ "Well Name",
"Segment Number",
"Segment Number",
"Strength of AICD",
"Flow Scaling Factor for AICD",
"Density of Calibration Fluid",
"Viscosity of Calibration Fluid",
"Critical water in liquid fraction for emulsions viscosity model",
"Emulsion viscosity transition region",
"Max ratio of emulsion viscosity to continuous phase viscosity",
"Flow scaling factor method",
"Maximum flow rate for AICD device",
"Volume flow rate exponent, x",
"Viscosity function exponent, y",
"Device OPEN/SHUT",
"Exponent of the oil flowing fraction in the density mixture calculation",
"Exponent of the water flowing fraction in the density mixture calculation",
"Exponent of the gas flowing fraction in the density mixture calculation",
"Exponent of the oil flowing fraction in the density viscosity calculation",
"Exponent of the water flowing fraction in the density viscosity calculation",
"Exponent of the gas flowing fraction in the density viscosity calculation" };
tighterFormatter.keyword( "WSEGAICD" );
tighterFormatter.comment( "Column Overview:" );
for ( size_t i = 0; i < columnDescriptions.size(); ++i )
{
tighterFormatter.comment(
QString( "%1: %2" ).arg( i + 1, 2, 10, QChar( '0' ) ).arg( columnDescriptions[i] ) );
}
std::vector<RifTextDataTableColumn> header;
for ( size_t i = 1; i <= 21; ++i )
{
QString cName = QString( "%1" ).arg( i, 2, 10, QChar( '0' ) );
RifTextDataTableColumn col( cName,
RifTextDataTableDoubleFormatting( RifTextDataTableDoubleFormat::RIF_CONSISE ),
RIGHT );
header.push_back( col );
}
tighterFormatter.header( header );
}
// Export data for each cell with AICD valves
for ( auto [globalCellIndex, aicdDataForSameCell] : aicdValveData )
{
if ( aicdDataForSameCell.empty() ) continue;
double accumulatedFlowScalingFactorDivisor = 0.0;
QStringList comments;
// See RicMswAICDAccumulator::accumulateValveParameters for similar accumulation for multiple valves in same
// segment
for ( const auto& aicdData : aicdDataForSameCell )
{
accumulatedFlowScalingFactorDivisor += 1.0 / aicdData.m_flowScalingFactor;
comments.push_back( aicdData.m_comment );
}
for ( auto comment : comments )
{
tighterFormatter.comment( comment );
}
auto firstDataObject = aicdDataForSameCell.front();
tighterFormatter.add( firstDataObject.m_wellName ); // #1
tighterFormatter.add( firstDataObject.m_segmentNumber );
tighterFormatter.add( firstDataObject.m_segmentNumber );
std::array<double, AICD_NUM_PARAMS> values = firstDataObject.m_values;
tighterFormatter.add( values[AICD_STRENGTH] );
double flowScalingFactor = 1.0 / accumulatedFlowScalingFactorDivisor;
tighterFormatter.add( flowScalingFactor ); // #5 Eclipse Flow scaling factor used when
// item #11 is set to '1'
tighterFormatter.add( values[AICD_DENSITY_CALIB_FLUID] );
tighterFormatter.add( values[AICD_VISCOSITY_CALIB_FLUID] );
tighterFormatter.addValueOrDefaultMarker( values[AICD_CRITICAL_WATER_IN_LIQUID_FRAC],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_EMULSION_VISC_TRANS_REGION],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_MAX_RATIO_EMULSION_VISC],
RicMswExportInfo::defaultDoubleValue() ); // #10
tighterFormatter.add( 1 ); // #11 : Always use method "b. Scale factor". The value of the
// scale factor is given in item #5
tighterFormatter.addValueOrDefaultMarker( values[AICD_MAX_FLOW_RATE], RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.add( values[AICD_VOL_FLOW_EXP] );
tighterFormatter.add( values[AICD_VISOSITY_FUNC_EXP] );
tighterFormatter.add( firstDataObject.m_isOpen ? "OPEN" : "SHUT" ); // #15
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_OIL_FRAC_DENSITY],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_WATER_FRAC_DENSITY],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_GAS_FRAC_DENSITY],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_OIL_FRAC_VISCOSITY],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_WATER_FRAC_VISCOSITY],
RicMswExportInfo::defaultDoubleValue() ); // #20
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_GAS_FRAC_VISCOSITY],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.rowCompleted();
}
tighterFormatter.tableCompleted();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicMswTableFormatterTools::generateWsegAicdTableRecursively( RicMswExportInfo& exportInfo,
gsl::not_null<const RicMswBranch*> branch,
std::map<size_t, std::vector<AicdWsegvalveData>>& aicdValveData )
{
for ( auto segment : branch->segments() )
{
for ( auto completion : segment->completions() )
{
if ( completion->completionType() == RigCompletionData::CompletionType::PERFORATION_AICD )
{
auto aicd = static_cast<RicMswPerforationAICD*>( completion );
auto aicd = static_cast<const RicMswPerforationAICD*>( completion );
if ( aicd->isValid() )
{
if ( !foundValve )
{
std::vector<QString> columnDescriptions =
{ "Well Name",
"Segment Number",
"Segment Number",
"Strength of AICD",
"Flow Scaling Factor for AICD",
"Density of Calibration Fluid",
"Viscosity of Calibration Fluid",
"Critical water in liquid fraction for emulsions viscosity model",
"Emulsion viscosity transition region",
"Max ratio of emulsion viscosity to continuous phase viscosity",
"Flow scaling factor method",
"Maximum flow rate for AICD device",
"Volume flow rate exponent, x",
"Viscosity function exponent, y",
"Device OPEN/SHUT",
"Exponent of the oil flowing fraction in the density mixture calculation",
"Exponent of the water flowing fraction in the density mixture calculation",
"Exponent of the gas flowing fraction in the density mixture calculation",
"Exponent of the oil flowing fraction in the density viscosity calculation",
"Exponent of the water flowing fraction in the density viscosity calculation",
"Exponent of the gas flowing fraction in the density viscosity calculation" };
tighterFormatter.keyword( "WSEGAICD" );
tighterFormatter.comment( "Column Overview:" );
for ( size_t i = 0; i < columnDescriptions.size(); ++i )
{
tighterFormatter.comment(
QString( "%1: %2" ).arg( i + 1, 2, 10, QChar( '0' ) ).arg( columnDescriptions[i] ) );
}
std::vector<RifTextDataTableColumn> header;
for ( size_t i = 1; i <= 21; ++i )
{
QString cName = QString( "%1" ).arg( i, 2, 10, QChar( '0' ) );
RifTextDataTableColumn col( cName,
RifTextDataTableDoubleFormatting(
RifTextDataTableDoubleFormat::RIF_CONSISE ),
RIGHT );
header.push_back( col );
}
tighterFormatter.header( header );
foundValve = true;
}
if ( !aicd->segments().empty() )
{
CVF_ASSERT( aicd->segments().size() == 1u );
tighterFormatter.comment( aicd->label() );
tighterFormatter.add(
exportInfo.mainBoreBranch()->wellPath()->completionSettings()->wellNameForExport() ); // #1
tighterFormatter.add( aicd->segments().front()->segmentNumber() );
tighterFormatter.add( aicd->segments().front()->segmentNumber() );
auto firstSegment = aicd->segments().front();
std::array<double, AICD_NUM_PARAMS> values = aicd->values();
tighterFormatter.add( values[AICD_STRENGTH] );
size_t cellIndex = std::numeric_limits<size_t>::max();
if ( !firstSegment->intersections().empty() )
{
cellIndex = firstSegment->intersections().front()->globalCellIndex();
}
tighterFormatter.add( aicd->flowScalingFactor() ); // #5 Flow scaling factor used when item
// #11 is set to '1'
tighterFormatter.add( values[AICD_DENSITY_CALIB_FLUID] );
tighterFormatter.add( values[AICD_VISCOSITY_CALIB_FLUID] );
tighterFormatter.addValueOrDefaultMarker( values[AICD_CRITICAL_WATER_IN_LIQUID_FRAC],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_EMULSION_VISC_TRANS_REGION],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_MAX_RATIO_EMULSION_VISC],
RicMswExportInfo::defaultDoubleValue() ); // #10
tighterFormatter.add( 1 ); // #11 : Always use method "b. Scale factor". The value of the
// scale factor is given in item #5
tighterFormatter.addValueOrDefaultMarker( values[AICD_MAX_FLOW_RATE],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.add( values[AICD_VOL_FLOW_EXP] );
tighterFormatter.add( values[AICD_VISOSITY_FUNC_EXP] );
tighterFormatter.add( aicd->isOpen() ? "OPEN" : "SHUT" ); // #15
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_OIL_FRAC_DENSITY],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_WATER_FRAC_DENSITY],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_GAS_FRAC_DENSITY],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_OIL_FRAC_VISCOSITY],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_WATER_FRAC_VISCOSITY],
RicMswExportInfo::defaultDoubleValue() ); // #20
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_GAS_FRAC_VISCOSITY],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.rowCompleted();
auto wellName = exportInfo.mainBoreBranch()->wellPath()->completionSettings()->wellNameForExport();
auto comment = aicd->label();
aicdValveData[cellIndex].push_back( AicdWsegvalveData( wellName,
comment,
firstSegment->segmentNumber(),
aicd->flowScalingFactor(),
aicd->isOpen(),
aicd->values() ) );
}
}
else
@ -684,9 +769,10 @@ void RicMswTableFormatterTools::generateWsegAicdTable( RifTextDataTableFormatter
}
}
}
if ( foundValve )
for ( auto childBranch : branch->branches() )
{
tighterFormatter.tableCompleted();
generateWsegAicdTableRecursively( exportInfo, childBranch, aicdValveData );
}
}

View File

@ -35,6 +35,7 @@ class RimWellPath;
namespace RicMswTableFormatterTools
{
class WsegvalveData;
class AicdWsegvalveData;
class CvfVec3stComparator
{
@ -121,6 +122,9 @@ void generateWsegvalvTableRecursively( gsl::not_null<RicMswBranch*>
std::map<size_t, std::vector<WsegvalveData>>& wsegvalveData );
void generateWsegAicdTable( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo );
void generateWsegAicdTableRecursively( RicMswExportInfo& exportInfo,
gsl::not_null<const RicMswBranch*> branch,
std::map<size_t, std::vector<AicdWsegvalveData>>& aicdValveData );
std::vector<std::pair<double, double>> createSubSegmentMDPairs( double startMD, double endMD, double maxSegmentLength );