#6156 Handle gaps and inactive cells in MSW valve accumulation

This commit is contained in:
Gaute Lindkvist 2020-08-18 10:28:23 +02:00
parent 374478ab16
commit b82566751e
4 changed files with 72 additions and 21 deletions

View File

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

View File

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

View File

@ -795,6 +795,29 @@ std::vector<std::pair<double, double>>
return subSegmentMDPairs; 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;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -1023,7 +1046,10 @@ RicMswExportInfo RicWellPathExportMswCompletionsImpl::generatePerforationsMswExp
{ {
RiaEclipseUnitTools::UnitSystem unitSystem = eclipseCase->eclipseCaseData()->unitsType(); 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. // with active grid, or user defined value.
std::vector<WellPathCellIntersectionInfo> intersections = generateCellSegments( eclipseCase, wellPath, initialMD ); std::vector<WellPathCellIntersectionInfo> intersections = generateCellSegments( eclipseCase, wellPath, initialMD );
@ -1050,7 +1076,11 @@ RicMswExportInfo RicWellPathExportMswCompletionsImpl::generatePerforationsMswExp
&foundSubGridIntersections ); &foundSubGridIntersections );
createValveCompletions( mainBoreSegments, perforationIntervals, wellPath, unitSystem ); createValveCompletions( mainBoreSegments, perforationIntervals, wellPath, unitSystem );
assignValveContributionsToSuperICDsOrAICDs( mainBoreSegments, perforationIntervals, unitSystem ); assignValveContributionsToSuperICDsOrAICDs( mainBoreSegments,
perforationIntervals,
filteredIntersections,
activeCellInfo,
unitSystem );
moveIntersectionsToICVs( mainBoreSegments, perforationIntervals, unitSystem ); moveIntersectionsToICVs( mainBoreSegments, perforationIntervals, unitSystem );
moveIntersectionsToSuperICDsOrAICDs( mainBoreSegments ); moveIntersectionsToSuperICDsOrAICDs( mainBoreSegments );
@ -1431,6 +1461,8 @@ void RicWellPathExportMswCompletionsImpl::createValveCompletions(
void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperICDsOrAICDs( void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperICDsOrAICDs(
const std::vector<std::shared_ptr<RicMswSegment>>& mainBoreSegments, const std::vector<std::shared_ptr<RicMswSegment>>& mainBoreSegments,
const std::vector<const RimPerforationInterval*>& perforationIntervals, const std::vector<const RimPerforationInterval*>& perforationIntervals,
const std::vector<WellPathCellIntersectionInfo>& wellPathIntersections,
const RigActiveCellInfo* activeCellInfo,
RiaEclipseUnitTools::UnitSystem unitSystem ) RiaEclipseUnitTools::UnitSystem unitSystem )
{ {
ValveContributionMap assignedRegularValves; ValveContributionMap assignedRegularValves;
@ -1469,21 +1501,32 @@ void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperICDsOrA
{ {
if ( !valve->isChecked() ) continue; if ( !valve->isChecked() ) continue;
double totalValveLength = calculateLengthThroughActiveCells( valve->startMD(),
valve->endMD(),
wellPathIntersections,
activeCellInfo );
for ( size_t nSubValve = 0u; nSubValve < valve->valveSegments().size(); ++nSubValve ) for ( size_t nSubValve = 0u; nSubValve < valve->valveSegments().size(); ++nSubValve )
{ {
std::pair<double, double> valveSegment = valve->valveSegments()[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 );
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, if ( accumulator->accumulateValveParameters( valve,
nSubValve, nSubValve,
overlap / valveSegmentLength, overlapLength / valveSegmentLength,
lengthOpenForFlow ) ) totalValveLength ) )
{ {
assignedRegularValves[superValve].insert( std::make_pair( valve, nSubValve ) ); assignedRegularValves[superValve].insert( std::make_pair( valve, nSubValve ) );
} }

View File

@ -22,6 +22,7 @@
class RicExportCompletionDataSettingsUi; class RicExportCompletionDataSettingsUi;
class RifTextDataTableFormatter; class RifTextDataTableFormatter;
class RigActiveCellInfo;
class RimEclipseCase; class RimEclipseCase;
class RimFishbonesMultipleSubs; class RimFishbonesMultipleSubs;
class RimPerforationInterval; class RimPerforationInterval;
@ -129,6 +130,11 @@ private:
static void generateWsegvalvTable( RifTextDataTableFormatter& formatter, const RicMswExportInfo& exportInfo ); static void generateWsegvalvTable( RifTextDataTableFormatter& formatter, const RicMswExportInfo& exportInfo );
static void generateWsegAicdTable( 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: private:
typedef std::vector<std::shared_ptr<RicMswSegment>> MainBoreSegments; typedef std::vector<std::shared_ptr<RicMswSegment>> MainBoreSegments;
typedef std::map<std::shared_ptr<RicMswCompletion>, std::set<std::pair<const RimWellPathValve*, size_t>>> ValveContributionMap; typedef std::map<std::shared_ptr<RicMswCompletion>, std::set<std::pair<const RimWellPathValve*, size_t>>> ValveContributionMap;
@ -152,7 +158,9 @@ private:
static void static void
assignValveContributionsToSuperICDsOrAICDs( const std::vector<std::shared_ptr<RicMswSegment>>& mainBoreSegments, assignValveContributionsToSuperICDsOrAICDs( const std::vector<std::shared_ptr<RicMswSegment>>& mainBoreSegments,
const std::vector<const RimPerforationInterval*>& perforationIntervals, 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, static void moveIntersectionsToICVs( const std::vector<std::shared_ptr<RicMswSegment>>& mainBoreSegments,
const std::vector<const RimPerforationInterval*>& perforationIntervals, const std::vector<const RimPerforationInterval*>& perforationIntervals,