mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#6156 Handle gaps and inactive cells in MSW valve accumulation
This commit is contained in:
parent
374478ab16
commit
b82566751e
@ -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;
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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 ) );
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user