#6126 MSW AICDs: Fix computation of flow scaling factor

This commit is contained in:
Magne Sjaastad 2020-06-24 12:35:51 +02:00
parent 44b3cb76df
commit e935343fab
5 changed files with 80 additions and 25 deletions

View File

@ -246,6 +246,7 @@ RicMswPerforationAICD::RicMswPerforationAICD( const QString& label, const RimWel
, m_valid( false )
, m_deviceOpen( false )
, m_length( 0.0 )
, m_flowScalingFactor( 0.0 )
{
}
@ -305,6 +306,22 @@ void RicMswPerforationAICD::setLength( double length )
m_length = length;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RicMswPerforationAICD::flowScalingFactor() const
{
return m_flowScalingFactor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicMswPerforationAICD::setflowScalingFactor( double scalingFactor )
{
m_flowScalingFactor = scalingFactor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -170,6 +170,8 @@ public:
void setIsOpen( bool deviceOpen );
double length() const;
void setLength( double length );
double flowScalingFactor() const;
void setflowScalingFactor( double scalingFactor );
const std::array<double, AICD_NUM_PARAMS>& values() const;
std::array<double, AICD_NUM_PARAMS>& values();
@ -179,4 +181,5 @@ private:
bool m_deviceOpen;
std::array<double, AICD_NUM_PARAMS> m_parameters;
double m_length;
double m_flowScalingFactor;
};

View File

@ -38,7 +38,8 @@ RicMswICDAccumulator::RicMswICDAccumulator( RiaEclipseUnitTools::UnitSystem unit
//--------------------------------------------------------------------------------------------------
bool RicMswICDAccumulator::accumulateValveParameters( const RimWellPathValve* wellPathValve,
size_t subValve,
double contributionFraction )
double contributionFraction,
double totalValveLengthOpenForFlow )
{
CVF_ASSERT( wellPathValve );
if ( wellPathValve->componentType() == RiaDefines::WellPathComponentType::ICV ||
@ -76,6 +77,7 @@ RicMswAICDAccumulator::RicMswAICDAccumulator( RiaEclipseUnitTools::UnitSystem un
, m_valid( false )
, m_deviceOpen( false )
, m_accumulatedLength( 0.0 )
, m_accumulatedFlowScalingFactorDivisor( 0.0 )
{
}
@ -84,7 +86,8 @@ RicMswAICDAccumulator::RicMswAICDAccumulator( RiaEclipseUnitTools::UnitSystem un
//--------------------------------------------------------------------------------------------------
bool RicMswAICDAccumulator::accumulateValveParameters( const RimWellPathValve* wellPathValve,
size_t subValve,
double contributionFraction )
double contributionFraction,
double totalValveLengthOpenForFlow )
{
CVF_ASSERT( wellPathValve );
if ( wellPathValve->componentType() == RiaDefines::WellPathComponentType::AICD )
@ -104,16 +107,26 @@ bool RicMswAICDAccumulator::accumulateValveParameters( const RimWellPathValve* w
m_meanCalculators[i].addValueAndWeight( values[i], contributionFraction );
}
}
std::pair<double, double> valveSegment = wellPathValve->valveSegments()[subValve];
double valveSegmentLength = std::fabs( valveSegment.second - valveSegment.first );
const RimPerforationInterval* perfInterval = nullptr;
wellPathValve->firstAncestorOrThisOfTypeAsserted( perfInterval );
double perfIntervalLength = std::fabs( perfInterval->endMD() - perfInterval->startMD() );
double lengthFraction = 1.0;
if ( perfIntervalLength > 1.0e-8 )
double lengthFraction = 1.0;
if ( totalValveLengthOpenForFlow > 1.0e-8 )
{
lengthFraction = valveSegmentLength / perfIntervalLength;
lengthFraction = valveSegmentLength / totalValveLengthOpenForFlow;
}
// https://github.com/OPM/ResInsight/issues/6126
//
// flowScalingFactor = 1 / (length_fraction * N_AICDs)
// where:
// length_fraction = length_COMPSEGS / Sum_lenght_COMPSEGS_for_valve
// N_AICDs = number of AICDs in perforation interval
double divisor = wellPathValve->valveLocations().size() * lengthFraction * contributionFraction;
m_accumulatedFlowScalingFactorDivisor += divisor;
m_accumulatedLength += lengthFraction * contributionFraction;
}
}
@ -148,6 +161,15 @@ void RicMswAICDAccumulator::applyToSuperValve( std::shared_ptr<RicMswValve> valv
aicd->setIsOpen( m_deviceOpen );
aicd->setLength( m_accumulatedLength );
// See https://github.com/OPM/ResInsight/issues/6126
double flowScalingFactor = 0.0;
if ( m_accumulatedFlowScalingFactorDivisor > 1.0e-8 )
{
flowScalingFactor = 1.0 / m_accumulatedFlowScalingFactorDivisor;
}
aicd->setflowScalingFactor( flowScalingFactor );
aicd->values() = values;
}
}

View File

@ -39,8 +39,9 @@ public:
}
virtual bool accumulateValveParameters( const RimWellPathValve* wellPathValve,
size_t subValve,
double contributionFraction ) = 0;
virtual void applyToSuperValve( std::shared_ptr<RicMswValve> valve ) = 0;
double contributionFraction,
double totalValveLengthOpenForFlow ) = 0;
virtual void applyToSuperValve( std::shared_ptr<RicMswValve> valve ) = 0;
protected:
RiaEclipseUnitTools::UnitSystem m_unitSystem;
@ -55,7 +56,8 @@ public:
RicMswICDAccumulator( RiaEclipseUnitTools::UnitSystem unitSystem );
bool accumulateValveParameters( const RimWellPathValve* wellPathValve,
size_t subValve,
double contributionFraction ) override;
double contributionFraction,
double totalValveLengthOpenForFlow ) override;
void applyToSuperValve( std::shared_ptr<RicMswValve> valve ) override;
private:
@ -72,7 +74,8 @@ public:
RicMswAICDAccumulator( RiaEclipseUnitTools::UnitSystem unitSystem );
bool accumulateValveParameters( const RimWellPathValve* wellPathValve,
size_t subValve,
double contributionFraction ) override;
double contributionFraction,
double totalValveLengthOpenForFlow ) override;
void applyToSuperValve( std::shared_ptr<RicMswValve> valve ) override;
private:
@ -80,4 +83,5 @@ private:
bool m_deviceOpen;
std::array<RiaWeightedMeanCalculator<double>, AICD_NUM_PARAMS> m_meanCalculators;
double m_accumulatedLength;
};
double m_accumulatedFlowScalingFactorDivisor;
};

View File

@ -737,7 +737,7 @@ void RicWellPathExportMswCompletionsImpl::generateWsegAicdTable( RifTextDataTabl
"Segment Number",
"Segment Number",
"Strength of AICD",
"Length of AICD",
"Flow Scaling Factor for AICD",
"Density of Calibration Fluid",
"Viscosity of Calibration Fluid",
"Critical water in liquid fraction for emulsions viscosity model",
@ -781,13 +781,16 @@ void RicWellPathExportMswCompletionsImpl::generateWsegAicdTable( RifTextDataTabl
{
CVF_ASSERT( aicd->subSegments().size() == 1u );
tighterFormatter.comment( aicd->label() );
tighterFormatter.add( exportInfo.wellPath()->completions()->wellNameForExport() ); // 1
tighterFormatter.add( exportInfo.wellPath()->completions()->wellNameForExport() ); // #1
tighterFormatter.add( aicd->subSegments().front()->segmentNumber() );
tighterFormatter.add( aicd->subSegments().front()->segmentNumber() );
std::array<double, AICD_NUM_PARAMS> values = aicd->values();
tighterFormatter.add( values[AICD_STRENGTH] );
tighterFormatter.add( aicd->length() ); // 5
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],
@ -795,13 +798,16 @@ void RicWellPathExportMswCompletionsImpl::generateWsegAicdTable( RifTextDataTabl
tighterFormatter.addValueOrDefaultMarker( values[AICD_EMULSION_VISC_TRANS_REGION],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_MAX_RATIO_EMULSION_VISC],
RicMswExportInfo::defaultDoubleValue() ); // 10
tighterFormatter.add( 1 );
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.add( aicd->isOpen() ? "OPEN" : "SHUT" ); // #15
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_OIL_FRAC_DENSITY],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_WATER_FRAC_DENSITY],
@ -811,7 +817,7 @@ void RicWellPathExportMswCompletionsImpl::generateWsegAicdTable( RifTextDataTabl
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_OIL_FRAC_VISCOSITY],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_WATER_FRAC_VISCOSITY],
RicMswExportInfo::defaultDoubleValue() ); // 20
RicMswExportInfo::defaultDoubleValue() ); // #20
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_GAS_FRAC_VISCOSITY],
RicMswExportInfo::defaultDoubleValue() );
tighterFormatter.rowCompleted();
@ -1276,9 +1282,9 @@ RicWellPathExportMswCompletionsImpl::MainBoreSegments
{
MainBoreSegments mainBoreSegments;
// Intersections along the well path with grid geometry is handled by well log extraction tools. The threshold in
// RigWellLogExtractionTools::isEqualDepth is currently set to 0.1m, and this is a pretty large threshold based on
// the indicated threshold of 0.001m for MSW segments
// Intersections along the well path with grid geometry is handled by well log extraction tools.
// The threshold in RigWellLogExtractionTools::isEqualDepth is currently set to 0.1m, and this
// is a pretty large threshold based on the indicated threshold of 0.001m for MSW segments
const double segmentLengthThreshold = 1.0e-3;
for ( const auto& cellIntInfo : subSegIntersections )
@ -1515,7 +1521,6 @@ void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperICDsOrA
std::vector<const RimWellPathValve*> perforationValves;
interval->descendantsIncludingThisOfType( perforationValves );
for ( const RimWellPathValve* valve : perforationValves )
{
if ( !valve->isChecked() ) continue;
@ -1530,7 +1535,11 @@ void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperICDsOrA
if ( overlap > 0.0 && accumulator )
{
if ( accumulator->accumulateValveParameters( valve, nSubValve, overlap / valveSegmentLength ) )
double lengthOpenForFlow = std::fabs( valve->endMD() - valve->startMD() );
if ( accumulator->accumulateValveParameters( valve,
nSubValve,
overlap / valveSegmentLength,
lengthOpenForFlow ) )
{
assignedRegularValves[superValve].insert( std::make_pair( valve, nSubValve ) );
}