#6156 Handle gaps and inactive cells in MSW valve accumulation

This commit is contained in:
Magne Sjaastad 2020-08-21 17:23:40 +02:00
parent 2188a33d4e
commit c3829da41b
4 changed files with 72 additions and 21 deletions

View File

@ -100,7 +100,7 @@ RicMswAICDAccumulator::RicMswAICDAccumulator( RiaEclipseUnitTools::UnitSystem un
bool RicMswAICDAccumulator::accumulateValveParameters( const RimWellPathValve* wellPathValve,
size_t subValve,
double contributionFraction,
double totalValveLengthOpenForFlow )
double totalValveCompsegsLength )
{
CVF_ASSERT( wellPathValve );
if ( wellPathValve->componentType() == RiaDefines::AICD )
@ -115,9 +115,9 @@ bool RicMswAICDAccumulator::accumulateValveParameters( const RimWellPathValve* w
std::pair<double, double> valveSegment = wellPathValve->valveSegments()[subValve];
double valveSegmentLength = std::fabs( valveSegment.second - valveSegment.first );
double lengthFraction = 1.0;
if ( totalValveLengthOpenForFlow > 1.0e-8 )
if ( totalValveCompsegsLength > 1.0e-8 )
{
lengthFraction = valveSegmentLength / totalValveLengthOpenForFlow;
lengthFraction = valveSegmentLength / totalValveCompsegsLength;
}
double combinedFraction = contributionFraction * lengthFraction;
@ -133,12 +133,12 @@ bool RicMswAICDAccumulator::accumulateValveParameters( const RimWellPathValve* w
// https://github.com/OPM/ResInsight/issues/6126
//
// flowScalingFactor = 1 / (length_fraction * N_AICDs)
// flowScalingFactor = 1 / (lengthFraction * aicdCount)
// where:
// length_fraction = length_COMPSEGS / Sum_lenght_COMPSEGS_for_valve
// lengthFraction = length_COMPSEGS / Sum_length_COMPSEGS_for_valve
// N_AICDs = number of AICDs in perforation interval
double divisor = wellPathValve->valveLocations().size() * combinedFraction;
size_t aicdCount = wellPathValve->valveLocations().size();
double divisor = aicdCount * combinedFraction;
m_accumulatedFlowScalingFactorDivisor += divisor;

View File

@ -57,7 +57,7 @@ public:
bool accumulateValveParameters( const RimWellPathValve* wellPathValve,
size_t subValve,
double contributionFraction,
double totalValveLengthOpenForFlow ) override;
double totalValveCompsegsLength ) override;
void applyToSuperValve( std::shared_ptr<RicMswValve> valve ) override;
private:
@ -75,7 +75,7 @@ public:
bool accumulateValveParameters( const RimWellPathValve* wellPathValve,
size_t subValve,
double contributionFraction,
double totalValveLengthOpenForFlow ) override;
double totalValveCompsegsLength ) override;
void applyToSuperValve( std::shared_ptr<RicMswValve> valve ) override;
private:

View File

@ -795,6 +795,29 @@ std::vector<std::pair<double, double>>
return subSegmentMDPairs;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RicWellPathExportMswCompletionsImpl::calculateLengthThroughActiveCells(
double startMD,
double endMD,
const std::vector<WellPathCellIntersectionInfo>& wellPathIntersections,
const RigActiveCellInfo* activeCellInfo )
{
double totalOverlap = 0.0;
for ( const WellPathCellIntersectionInfo& intersection : wellPathIntersections )
{
if ( activeCellInfo->isActive( intersection.globCellIndex ) )
{
double overlapStart = std::max( startMD, intersection.startMD );
double overlapEnd = std::min( endMD, intersection.endMD );
double overlap = std::max( 0.0, overlapEnd - overlapStart );
totalOverlap += overlap;
}
}
return totalOverlap;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -1022,7 +1045,10 @@ RicMswExportInfo RicWellPathExportMswCompletionsImpl::generatePerforationsMswExp
{
RiaEclipseUnitTools::UnitSystem unitSystem = eclipseCase->eclipseCaseData()->unitsType();
double initialMD = 0.0; // Start measured depth segment to export MSW data for. Either based on first intersection
const RigActiveCellInfo* activeCellInfo =
eclipseCase->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL );
double initialMD = 0.0; // Start measured depth location to export MSW data for. Either based on first intersection
// with active grid, or user defined value.
std::vector<WellPathCellIntersectionInfo> intersections = generateCellSegments( eclipseCase, wellPath, initialMD );
@ -1049,7 +1075,11 @@ RicMswExportInfo RicWellPathExportMswCompletionsImpl::generatePerforationsMswExp
&foundSubGridIntersections );
createValveCompletions( mainBoreSegments, perforationIntervals, wellPath, unitSystem );
assignValveContributionsToSuperICDsOrAICDs( mainBoreSegments, perforationIntervals, unitSystem );
assignValveContributionsToSuperICDsOrAICDs( mainBoreSegments,
perforationIntervals,
filteredIntersections,
activeCellInfo,
unitSystem );
moveIntersectionsToICVs( mainBoreSegments, perforationIntervals, unitSystem );
moveIntersectionsToSuperICDsOrAICDs( mainBoreSegments );
@ -1427,6 +1457,8 @@ void RicWellPathExportMswCompletionsImpl::createValveCompletions(
void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperICDsOrAICDs(
const std::vector<std::shared_ptr<RicMswSegment>>& mainBoreSegments,
const std::vector<const RimPerforationInterval*>& perforationIntervals,
const std::vector<WellPathCellIntersectionInfo>& wellPathIntersections,
const RigActiveCellInfo* activeCellInfo,
RiaEclipseUnitTools::UnitSystem unitSystem )
{
ValveContributionMap assignedRegularValves;
@ -1465,21 +1497,32 @@ void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperICDsOrA
{
if ( !valve->isChecked() ) continue;
double totalValveLength = calculateLengthThroughActiveCells( valve->startMD(),
valve->endMD(),
wellPathIntersections,
activeCellInfo );
for ( size_t nSubValve = 0u; nSubValve < valve->valveSegments().size(); ++nSubValve )
{
std::pair<double, double> valveSegment = valve->valveSegments()[nSubValve];
double valveSegmentLength = valveSegment.second - valveSegment.first;
double overlapStart = std::max( valveSegment.first, segment->startMD() );
double overlapEnd = std::min( valveSegment.second, segment->endMD() );
double overlap = std::max( 0.0, overlapEnd - overlapStart );
std::pair<double, double> valveSegment = valve->valveSegments()[nSubValve];
if ( overlap > 0.0 && accumulator )
double valveSegmentLength = calculateLengthThroughActiveCells( valveSegment.first,
valveSegment.second,
wellPathIntersections,
activeCellInfo );
double overlapStart = std::max( valveSegment.first, segment->startMD() );
double overlapEnd = std::min( valveSegment.second, segment->endMD() );
double overlapLength =
calculateLengthThroughActiveCells( overlapStart, overlapEnd, wellPathIntersections, activeCellInfo );
if ( overlapLength > 0.0 && valveSegmentLength > 0.0 && accumulator )
{
double lengthOpenForFlow = std::fabs( valve->endMD() - valve->startMD() );
if ( accumulator->accumulateValveParameters( valve,
nSubValve,
overlap / valveSegmentLength,
lengthOpenForFlow ) )
overlapLength / valveSegmentLength,
totalValveLength ) )
{
assignedRegularValves[superValve].insert( std::make_pair( valve, nSubValve ) );
}

View File

@ -22,6 +22,7 @@
class RicExportCompletionDataSettingsUi;
class RifTextDataTableFormatter;
class RigActiveCellInfo;
class RimEclipseCase;
class RimFishbonesMultipleSubs;
class RimPerforationInterval;
@ -129,6 +130,11 @@ private:
static void generateWsegvalvTable( RifTextDataTableFormatter& formatter, const RicMswExportInfo& exportInfo );
static void generateWsegAicdTable( RifTextDataTableFormatter& formatter, const RicMswExportInfo& exportInfo );
static double calculateLengthThroughActiveCells( double startMD,
double endMD,
const std::vector<WellPathCellIntersectionInfo>& wellPathIntersections,
const RigActiveCellInfo* activeCellInfo );
private:
typedef std::vector<std::shared_ptr<RicMswSegment>> MainBoreSegments;
typedef std::map<std::shared_ptr<RicMswCompletion>, std::set<std::pair<const RimWellPathValve*, size_t>>> ValveContributionMap;
@ -152,7 +158,9 @@ private:
static void
assignValveContributionsToSuperICDsOrAICDs( const std::vector<std::shared_ptr<RicMswSegment>>& mainBoreSegments,
const std::vector<const RimPerforationInterval*>& perforationIntervals,
RiaEclipseUnitTools::UnitSystem unitSystem );
const std::vector<WellPathCellIntersectionInfo>& wellPathIntersections,
const RigActiveCellInfo* activeCellInfo,
RiaEclipseUnitTools::UnitSystem unitSystem );
static void moveIntersectionsToICVs( const std::vector<std::shared_ptr<RicMswSegment>>& mainBoreSegments,
const std::vector<const RimPerforationInterval*>& perforationIntervals,