mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#7686 MSW Fishbones : Compute effective diameter for multiple laterals in same cell
This commit is contained in:
parent
9a6073eb7b
commit
fcb0bd391b
@ -266,3 +266,35 @@ void RicMswBranch::addChildBranch( std::unique_ptr<RicMswBranch> branch )
|
||||
{
|
||||
m_branches.push_back( std::move( branch ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RicMswSegment*> RicMswBranch::allSegmentsRecursively()
|
||||
{
|
||||
std::vector<RicMswSegment*> allSegments;
|
||||
|
||||
{
|
||||
std::vector<RicMswSegment*> branchSegments = segments();
|
||||
allSegments.insert( allSegments.begin(), branchSegments.begin(), branchSegments.end() );
|
||||
|
||||
for ( auto seg : branchSegments )
|
||||
{
|
||||
for ( auto completion : seg->completions() )
|
||||
{
|
||||
std::vector<RicMswSegment*> completionSegments = completion->allSegmentsRecursively();
|
||||
|
||||
allSegments.insert( allSegments.begin(), completionSegments.begin(), completionSegments.end() );
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto subBranch : branches() )
|
||||
{
|
||||
auto subBranchSegments = subBranch->allSegmentsRecursively();
|
||||
|
||||
allSegments.insert( allSegments.begin(), subBranchSegments.begin(), subBranchSegments.end() );
|
||||
}
|
||||
|
||||
return allSegments;
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,8 @@ public:
|
||||
|
||||
void addChildBranch( std::unique_ptr<RicMswBranch> branch );
|
||||
|
||||
std::vector<RicMswSegment*> allSegmentsRecursively();
|
||||
|
||||
private:
|
||||
double m_initialMD;
|
||||
double m_initialTVD;
|
||||
|
@ -46,6 +46,7 @@ RicMswSegment::RicMswSegment( const QString& label,
|
||||
, m_skinFactor( RicMswExportInfo::defaultDoubleValue() )
|
||||
, m_subIndex( subIndex )
|
||||
, m_segmentNumber( segmentNumber )
|
||||
, m_effectiveDiameter( 0.0 )
|
||||
{
|
||||
}
|
||||
|
||||
@ -235,6 +236,22 @@ void RicMswSegment::setSegmentNumber( int segmentNumber )
|
||||
m_segmentNumber = segmentNumber;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RicMswSegment::effectiveDiameter() const
|
||||
{
|
||||
return m_effectiveDiameter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswSegment::setEffectiveDiameter( double effectiveDiameter )
|
||||
{
|
||||
m_effectiveDiameter = effectiveDiameter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -285,6 +302,22 @@ std::vector<std::shared_ptr<RicMswSegmentCellIntersection>>& RicMswSegment::inte
|
||||
return m_intersections;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<size_t> RicMswSegment::globalCellsIntersected() const
|
||||
{
|
||||
return m_intersectedGlobalCells;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswSegment::setIntersectedGlobalCells( const std::set<size_t>& intersectedCells )
|
||||
{
|
||||
m_intersectedGlobalCells = intersectedCells;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -71,6 +71,9 @@ public:
|
||||
void setSkinFactor( double skinFactor );
|
||||
void setSegmentNumber( int segmentNumber );
|
||||
|
||||
double effectiveDiameter() const;
|
||||
void setEffectiveDiameter( double effectiveDiameter );
|
||||
|
||||
void addCompletion( std::unique_ptr<RicMswCompletion> completion );
|
||||
std::unique_ptr<RicMswCompletion> removeCompletion( RicMswCompletion* completion );
|
||||
|
||||
@ -79,6 +82,9 @@ public:
|
||||
const std::vector<std::shared_ptr<RicMswSegmentCellIntersection>>& intersections() const;
|
||||
std::vector<std::shared_ptr<RicMswSegmentCellIntersection>>& intersections();
|
||||
|
||||
std::set<size_t> globalCellsIntersected() const;
|
||||
void setIntersectedGlobalCells( const std::set<size_t>& intersectedCells );
|
||||
|
||||
void setSourcePdmObject( const caf::PdmObject* object );
|
||||
const caf::PdmObject* sourcePdmObject() const;
|
||||
|
||||
@ -95,13 +101,18 @@ private:
|
||||
double m_holeDiameter;
|
||||
double m_openHoleRoughnessFactor;
|
||||
double m_skinFactor;
|
||||
double m_effectiveDiameter; // Used to represent the effective diameter if we have multiple laterals in same cell
|
||||
|
||||
size_t m_subIndex;
|
||||
int m_segmentNumber;
|
||||
|
||||
std::vector<std::unique_ptr<RicMswCompletion>> m_completions;
|
||||
|
||||
// Connection to grid cells when we have a completion in this cell
|
||||
std::vector<std::shared_ptr<RicMswSegmentCellIntersection>> m_intersections;
|
||||
|
||||
// All global cells intersected by this segment
|
||||
std::set<std::size_t> m_intersectedGlobalCells;
|
||||
|
||||
caf::PdmPointer<caf::PdmObject> m_sourcePdmObject;
|
||||
};
|
||||
|
@ -865,13 +865,17 @@ void RicMswTableFormatterTools::writeCompletionWelsegsSegments( gsl::not_null<co
|
||||
depth = subEndTVD;
|
||||
length = subEndMD;
|
||||
}
|
||||
|
||||
double diameter = segment->equivalentDiameter();
|
||||
if ( segment->effectiveDiameter() > 0.0 ) diameter = segment->effectiveDiameter();
|
||||
|
||||
formatter.add( subSegmentNumber );
|
||||
formatter.add( subSegmentNumber );
|
||||
formatter.add( completion->branchNumber() );
|
||||
formatter.add( outletSegmentNumber );
|
||||
formatter.add( length );
|
||||
formatter.add( depth );
|
||||
formatter.add( segment->equivalentDiameter() );
|
||||
formatter.add( diameter );
|
||||
formatter.add( segment->openHoleRoughnessFactor() );
|
||||
formatter.rowCompleted();
|
||||
outletSegmentNumber = subSegmentNumber;
|
||||
|
@ -426,6 +426,8 @@ void RicWellPathExportMswCompletionsImpl::exportWellSegmentsForFishbones( RimEcl
|
||||
&exportInfo,
|
||||
exportInfo.mainBoreBranch() );
|
||||
|
||||
computeEffectiveDiameter( exportInfo.mainBoreBranch() );
|
||||
|
||||
int branchNumber = 1;
|
||||
|
||||
assignBranchNumbersToBranch( eclipseCase, &exportInfo, exportInfo.mainBoreBranch(), &branchNumber );
|
||||
@ -463,6 +465,47 @@ void RicWellPathExportMswCompletionsImpl::exportWellSegmentsForFishbones( RimEcl
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicWellPathExportMswCompletionsImpl::computeEffectiveDiameter( gsl::not_null<RicMswBranch*> branch )
|
||||
{
|
||||
std::map<size_t, std::set<RicMswSegment*>> segmentsInCell;
|
||||
{
|
||||
auto segments = branch->allSegmentsRecursively();
|
||||
for ( auto s : segments )
|
||||
{
|
||||
auto cellsIntersected = s->globalCellsIntersected();
|
||||
if ( !cellsIntersected.empty() )
|
||||
{
|
||||
for ( auto index : cellsIntersected )
|
||||
{
|
||||
segmentsInCell[index].insert( s );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto [index, segmentsInSameCell] : segmentsInCell )
|
||||
{
|
||||
double effectiveDiameter = 0.0;
|
||||
// Compute effective diameter based on square root of the sum of diameter squared
|
||||
// Deff = sqrt(d1^2 + d2^2 + ..)
|
||||
|
||||
for ( auto seg : segmentsInSameCell )
|
||||
{
|
||||
effectiveDiameter += ( seg->equivalentDiameter() * seg->equivalentDiameter() );
|
||||
}
|
||||
|
||||
effectiveDiameter = sqrt( effectiveDiameter );
|
||||
|
||||
for ( auto seg : segmentsInSameCell )
|
||||
{
|
||||
seg->setEffectiveDiameter( effectiveDiameter );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -546,20 +589,20 @@ void RicWellPathExportMswCompletionsImpl::generateFishbonesMswExportInfo(
|
||||
double intersectionMidpoint = 0.5 * ( cellIntersection.startMD + cellIntersection.endMD );
|
||||
size_t closestSubIndex = 0;
|
||||
double closestDistance = std::numeric_limits<double>::infinity();
|
||||
for ( const auto& sub : subAndLateralIndices )
|
||||
for ( const auto& [subIndex, lateralIndices] : subAndLateralIndices )
|
||||
{
|
||||
double subMD = subs->measuredDepth( sub.first );
|
||||
double subMD = subs->measuredDepth( subIndex );
|
||||
|
||||
if ( ( cellIntersection.startMD <= subMD ) && ( subMD <= cellIntersection.endMD ) )
|
||||
{
|
||||
cellIntersectionContainingSubIndex[sub.first] = intersectionIndex;
|
||||
cellIntersectionContainingSubIndex[subIndex] = intersectionIndex;
|
||||
}
|
||||
|
||||
auto distanceCandicate = std::abs( subMD - intersectionMidpoint );
|
||||
if ( distanceCandicate < closestDistance )
|
||||
{
|
||||
closestDistance = distanceCandicate;
|
||||
closestSubIndex = sub.first;
|
||||
closestSubIndex = subIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@ -568,17 +611,17 @@ void RicWellPathExportMswCompletionsImpl::generateFishbonesMswExportInfo(
|
||||
}
|
||||
}
|
||||
|
||||
for ( const auto& sub : subAndLateralIndices )
|
||||
for ( const auto& [subIndex, lateralIndices] : subAndLateralIndices )
|
||||
{
|
||||
double subEndMD = subs->measuredDepth( sub.first );
|
||||
double subEndMD = subs->measuredDepth( subIndex );
|
||||
double subEndTVD = RicMswTableFormatterTools::tvdFromMeasuredDepth( branch->wellPath(), subEndMD );
|
||||
|
||||
{
|
||||
// Add completion for ICD
|
||||
auto icdSegment =
|
||||
std::make_unique<RicMswSegment>( "ICD segment", subEndMD, subEndMD + 0.1, subEndTVD, subEndTVD, sub.first );
|
||||
std::make_unique<RicMswSegment>( "ICD segment", subEndMD, subEndMD + 0.1, subEndTVD, subEndTVD, subIndex );
|
||||
|
||||
for ( auto lateralIndex : sub.second )
|
||||
for ( auto lateralIndex : lateralIndices )
|
||||
{
|
||||
QString label = QString( "Lateral %1" ).arg( lateralIndex + 1 );
|
||||
icdSegment->addCompletion(
|
||||
@ -604,12 +647,12 @@ void RicWellPathExportMswCompletionsImpl::generateFishbonesMswExportInfo(
|
||||
const RigMainGrid* mainGrid = eclipseCase->mainGrid();
|
||||
|
||||
std::set<size_t> indices;
|
||||
for ( auto intersectionIndex : closestSubForCellIntersections[sub.first] )
|
||||
for ( auto intersectionIndex : closestSubForCellIntersections[subIndex] )
|
||||
{
|
||||
indices.insert( intersectionIndex );
|
||||
}
|
||||
|
||||
indices.insert( cellIntersectionContainingSubIndex[sub.first] );
|
||||
indices.insert( cellIntersectionContainingSubIndex[subIndex] );
|
||||
|
||||
for ( auto intersectionIndex : indices )
|
||||
{
|
||||
@ -1573,6 +1616,7 @@ void RicWellPathExportMswCompletionsImpl::assignFishbonesLateralIntersections( c
|
||||
subSegment->setOpenHoleRoughnessFactor( fishbonesSubs->openHoleRoughnessFactor( unitSystem ) );
|
||||
subSegment->setSkinFactor( fishbonesSubs->skinFactor() );
|
||||
subSegment->setSourcePdmObject( fishbonesSubs );
|
||||
subSegment->setIntersectedGlobalCells( { cellIntInfo.globCellIndex } );
|
||||
|
||||
auto intersection = std::make_shared<RicMswSegmentCellIntersection>( gridName,
|
||||
cellIntInfo.globCellIndex,
|
||||
|
@ -62,6 +62,8 @@ public:
|
||||
bool exportDataSourceAsComment,
|
||||
bool completionSegmentsAfterMainBore );
|
||||
|
||||
static void computeEffectiveDiameter( gsl::not_null<RicMswBranch*> branch );
|
||||
|
||||
static void exportWellSegmentsForPerforations( RimEclipseCase* eclipseCase,
|
||||
std::shared_ptr<QFile> exportFile,
|
||||
std::shared_ptr<QFile> lgrExportFile,
|
||||
|
Loading…
Reference in New Issue
Block a user