mirror of
https://github.com/OPM/ResInsight.git
synced 2026-11-02 09:00:14 -06:00
COMPLUMP: Choose completion number by largest overlap in cell
When several perforation intervals cut the same cell, the completion number was taken from the first contribution, which depended on the order events were applied. Unrelated event changes (e.g. group tree members) could then change COMPLUMP numbers on boundary cells. Pick the number with the largest summed MD overlap in the cell, with ties going to the lowest number. Also use stable_sort for same-date events so they keep file order.
This commit is contained in:
1 parent
66c2cd47d3
commit
409f175467
5 files changed
+144
-13
No files matched your search
+36
-12
@@ -379,6 +379,39 @@ std::vector<RigCompletionData> RicWellPathExportCompletionDataFeatureImpl::compu
|
||||
return completionsPerEclipseCell;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::optional<int> RicWellPathExportCompletionDataFeatureImpl::completionNumberForCell( const std::vector<RigCompletionData>& completions )
|
||||
{
|
||||
// One perforation interval can cross the same cell more than once, so lengths are summed per number
|
||||
std::map<int, double> overlapPerNumber;
|
||||
for ( const auto& completion : completions )
|
||||
{
|
||||
const auto number = completion.completionNumber();
|
||||
if ( !number.has_value() ) continue;
|
||||
|
||||
double length = 0.0;
|
||||
if ( completion.startMD().has_value() && completion.endMD().has_value() )
|
||||
{
|
||||
length = std::max( 0.0, completion.endMD().value() - completion.startMD().value() );
|
||||
}
|
||||
overlapPerNumber[number.value()] += length;
|
||||
}
|
||||
|
||||
if ( overlapPerNumber.empty() ) return std::nullopt;
|
||||
|
||||
// Iterating in ascending number order and requiring a strictly larger length makes ties go to the lowest number
|
||||
const double tolerance = 1.0e-6;
|
||||
|
||||
auto best = overlapPerNumber.begin();
|
||||
for ( auto it = std::next( best ); it != overlapPerNumber.end(); ++it )
|
||||
{
|
||||
if ( it->second > best->second + tolerance ) best = it;
|
||||
}
|
||||
return best->first;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
@@ -409,9 +442,8 @@ RigCompletionData RicWellPathExportCompletionDataFeatureImpl::combineEclipseCell
|
||||
auto isValidTransmissibility = []( double transmissibility )
|
||||
{ return RigStatisticsTools::isValidNumber<double>( transmissibility ) && transmissibility >= 0.0; };
|
||||
|
||||
auto startMD = completions[0].startMD();
|
||||
auto endMD = completions[0].endMD();
|
||||
auto completionNumber = completions[0].completionNumber();
|
||||
auto startMD = completions[0].startMD();
|
||||
auto endMD = completions[0].endMD();
|
||||
|
||||
for ( const RigCompletionData& completion : completions )
|
||||
{
|
||||
@@ -439,14 +471,6 @@ RigCompletionData RicWellPathExportCompletionDataFeatureImpl::combineEclipseCell
|
||||
}
|
||||
}
|
||||
|
||||
if ( !completionNumber.has_value() )
|
||||
{
|
||||
if ( completion.completionNumber().has_value() )
|
||||
{
|
||||
completionNumber = completion.completionNumber();
|
||||
}
|
||||
}
|
||||
|
||||
double transmissibility = completion.transmissibility();
|
||||
|
||||
if ( !isValidTransmissibility( transmissibility ) )
|
||||
@@ -473,7 +497,7 @@ RigCompletionData RicWellPathExportCompletionDataFeatureImpl::combineEclipseCell
|
||||
{
|
||||
resultCompletion.setDepthRange( startMD.value(), endMD.value() );
|
||||
}
|
||||
if ( completionNumber.has_value() ) resultCompletion.setCompletionNumber( completionNumber.value() );
|
||||
if ( auto completionNumber = completionNumberForCell( completions ) ) resultCompletion.setCompletionNumber( completionNumber.value() );
|
||||
|
||||
double combinedDiameter = diameterCalculator.weightedMean();
|
||||
double combinedSkinFactor = skinFactorCalculator.weightedMean();
|
||||
|
||||
+4
@@ -80,6 +80,10 @@ public:
|
||||
|
||||
static std::optional<QDateTime> exportDateForTimeStep( const RimEclipseCase* eclipseCase, size_t timeStepIndex );
|
||||
|
||||
// Completion number for a cell with several contributions: the number with the largest summed MD overlap
|
||||
// (endMD - startMD) wins, ties go to the lowest number. Independent of contribution order.
|
||||
static std::optional<int> completionNumberForCell( const std::vector<RigCompletionData>& completions );
|
||||
|
||||
private:
|
||||
static std::vector<RigCompletionData> generatePerforationsCompdatValues( const RimWellPath* wellPath,
|
||||
const std::vector<const RimPerforationInterval*>& intervals,
|
||||
|
||||
Reference in new issue
Block a user