From b82566751ea9ab0b16d0b22374b5dee8203904be Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Tue, 18 Aug 2020 10:28:23 +0200 Subject: [PATCH] #6156 Handle gaps and inactive cells in MSW valve accumulation --- .../RicMswValveAccumulators.cpp | 14 ++-- .../RicMswValveAccumulators.h | 4 +- .../RicWellPathExportMswCompletionsImpl.cpp | 65 +++++++++++++++---- .../RicWellPathExportMswCompletionsImpl.h | 10 ++- 4 files changed, 72 insertions(+), 21 deletions(-) diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicMswValveAccumulators.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicMswValveAccumulators.cpp index 6fae424e31..b5b7729d79 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicMswValveAccumulators.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicMswValveAccumulators.cpp @@ -101,7 +101,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::WellPathComponentType::AICD ) @@ -116,9 +116,9 @@ bool RicMswAICDAccumulator::accumulateValveParameters( const RimWellPathValve* w std::pair 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; @@ -134,12 +134,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_length_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; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicMswValveAccumulators.h b/ApplicationCode/Commands/CompletionExportCommands/RicMswValveAccumulators.h index 549436c2d8..cf1b3ea25a 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicMswValveAccumulators.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicMswValveAccumulators.h @@ -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 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 valve ) override; private: diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.cpp index 6d6c767eaa..98edfb9147 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.cpp @@ -795,6 +795,29 @@ std::vector> return subSegmentMDPairs; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathExportMswCompletionsImpl::calculateLengthThroughActiveCells( + double startMD, + double endMD, + const std::vector& 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; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1023,7 +1046,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 intersections = generateCellSegments( eclipseCase, wellPath, initialMD ); @@ -1050,7 +1076,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 ); @@ -1431,6 +1461,8 @@ void RicWellPathExportMswCompletionsImpl::createValveCompletions( void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperICDsOrAICDs( const std::vector>& mainBoreSegments, const std::vector& perforationIntervals, + const std::vector& wellPathIntersections, + const RigActiveCellInfo* activeCellInfo, RiaEclipseUnitTools::UnitSystem unitSystem ) { ValveContributionMap assignedRegularValves; @@ -1469,21 +1501,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 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 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 ) ); } diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.h b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.h index caeed014b2..0eda14e9ae 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.h @@ -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& wellPathIntersections, + const RigActiveCellInfo* activeCellInfo ); + private: typedef std::vector> MainBoreSegments; typedef std::map, std::set>> ValveContributionMap; @@ -152,7 +158,9 @@ private: static void assignValveContributionsToSuperICDsOrAICDs( const std::vector>& mainBoreSegments, const std::vector& perforationIntervals, - RiaEclipseUnitTools::UnitSystem unitSystem ); + const std::vector& wellPathIntersections, + const RigActiveCellInfo* activeCellInfo, + RiaEclipseUnitTools::UnitSystem unitSystem ); static void moveIntersectionsToICVs( const std::vector>& mainBoreSegments, const std::vector& perforationIntervals,