#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,23 +596,19 @@ void RicMswTableFormatterTools::generateWsegvalvTableRecursively( gsl::not_null<
//--------------------------------------------------------------------------------------------------
void RicMswTableFormatterTools::generateWsegAicdTable( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo )
{
std::map<size_t, std::vector<AicdWsegvalveData>> aicdValveData;
generateWsegAicdTableRecursively( exportInfo, exportInfo.mainBoreBranch(), aicdValveData );
if ( !aicdValveData.empty() )
{
RifTextDataTableFormatter tighterFormatter( formatter );
tighterFormatter.setColumnSpacing( 1 );
tighterFormatter.setTableRowPrependText( " " );
bool foundValve = false;
{
// Write out header for AICD table
for ( auto segment : exportInfo.mainBoreBranch()->segments() )
{
for ( auto completion : segment->completions() )
{
if ( completion->completionType() == RigCompletionData::CompletionType::PERFORATION_AICD )
{
auto aicd = static_cast<RicMswPerforationAICD*>( completion );
if ( aicd->isValid() )
{
if ( !foundValve )
{
std::vector<QString> columnDescriptions =
{ "Well Name",
"Segment Number",
@ -619,29 +645,48 @@ void RicMswTableFormatterTools::generateWsegAicdTable( RifTextDataTableFormatter
{
QString cName = QString( "%1" ).arg( i, 2, 10, QChar( '0' ) );
RifTextDataTableColumn col( cName,
RifTextDataTableDoubleFormatting(
RifTextDataTableDoubleFormat::RIF_CONSISE ),
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() );
std::array<double, AICD_NUM_PARAMS> values = aicd->values();
// 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] );
tighterFormatter.add( aicd->flowScalingFactor() ); // #5 Flow scaling factor used when item
// #11 is set to '1'
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] );
@ -655,11 +700,10 @@ void RicMswTableFormatterTools::generateWsegAicdTable( RifTextDataTableFormatter
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.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.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],
@ -674,6 +718,47 @@ void RicMswTableFormatterTools::generateWsegAicdTable( RifTextDataTableFormatter
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<const RicMswPerforationAICD*>( completion );
if ( aicd->isValid() )
{
if ( !aicd->segments().empty() )
{
CVF_ASSERT( aicd->segments().size() == 1u );
auto firstSegment = aicd->segments().front();
size_t cellIndex = std::numeric_limits<size_t>::max();
if ( !firstSegment->intersections().empty() )
{
cellIndex = firstSegment->intersections().front()->globalCellIndex();
}
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 );