#7686 MSW Fishbones : Compute effective diameter for multiple laterals in same cell

This commit is contained in:
Magne Sjaastad 2021-05-14 12:16:59 +02:00
parent 9a6073eb7b
commit fcb0bd391b
7 changed files with 139 additions and 11 deletions

View File

@ -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;
}
}

View File

@ -63,6 +63,8 @@ public:
void addChildBranch( std::unique_ptr<RicMswBranch> branch );
std::vector<RicMswSegment*> allSegmentsRecursively();
private:
double m_initialMD;
double m_initialTVD;

View File

@ -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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -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;
};

View File

@ -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;

View File

@ -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,

View File

@ -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,