mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Improved simulation well visualization
* Move members to private in RigWellResultPoint * Create simulation well path geometry using well topology * Add separate MSW well pipe centerline computations * Review comments --------- Co-authored-by: magnesj <magnesj@users.noreply.github.com>
This commit is contained in:
parent
9b12885c23
commit
d2f435c00a
@ -1268,11 +1268,10 @@ size_t localGridCellIndexFromErtConnection( const RigGridBase* grid, const well_
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWellResultPoint RifReaderEclipseOutput::createWellResultPoint( const RigGridBase* grid,
|
||||
const well_conn_type* ert_connection,
|
||||
int ertBranchId,
|
||||
int ertSegmentId,
|
||||
const char* wellName )
|
||||
RigWellResultPoint RifReaderEclipseOutput::createWellResultPoint( const RigGridBase* grid,
|
||||
const well_conn_type* ert_connection,
|
||||
const well_segment_type* segment,
|
||||
const char* wellName )
|
||||
{
|
||||
CVF_ASSERT( ert_connection );
|
||||
CVF_ASSERT( grid );
|
||||
@ -1290,25 +1289,47 @@ RigWellResultPoint RifReaderEclipseOutput::createWellResultPoint( const RigGridB
|
||||
|
||||
if ( gridCellIndex != cvf::UNDEFINED_SIZE_T )
|
||||
{
|
||||
resultPoint.m_gridIndex = grid->gridIndex();
|
||||
resultPoint.m_gridCellIndex = gridCellIndex;
|
||||
int branchId = -1, segmentId = -1, outletBranchId = -1, outletSegmentId = -1;
|
||||
|
||||
resultPoint.m_isOpen = isCellOpen;
|
||||
if ( segment )
|
||||
{
|
||||
branchId = well_segment_get_branch_id( segment );
|
||||
segmentId = well_segment_get_id( segment );
|
||||
|
||||
resultPoint.m_ertBranchId = ertBranchId;
|
||||
resultPoint.m_ertSegmentId = ertSegmentId;
|
||||
resultPoint.m_flowRate = volumeRate;
|
||||
resultPoint.m_oilRate = oilRate;
|
||||
resultPoint.m_waterRate = waterRate;
|
||||
auto outletSegment = well_segment_get_outlet( segment );
|
||||
if ( outletSegment )
|
||||
{
|
||||
outletBranchId = well_segment_get_branch_id( outletSegment );
|
||||
outletSegmentId = well_segment_get_id( outletSegment );
|
||||
}
|
||||
}
|
||||
|
||||
resultPoint.m_gasRate = RiaEclipseUnitTools::convertSurfaceGasFlowRateToOilEquivalents( m_eclipseCase->unitsType(), gasRate );
|
||||
resultPoint.setGridIndex( grid->gridIndex() );
|
||||
resultPoint.setGridCellIndex( gridCellIndex );
|
||||
|
||||
resultPoint.m_connectionFactor = connectionFactor;
|
||||
resultPoint.setIsOpen( isCellOpen );
|
||||
|
||||
resultPoint.setSegmentData( branchId, segmentId );
|
||||
resultPoint.setOutletSegmentData( outletBranchId, outletSegmentId );
|
||||
|
||||
const double adjustedGasRate = RiaEclipseUnitTools::convertSurfaceGasFlowRateToOilEquivalents( m_eclipseCase->unitsType(), gasRate );
|
||||
resultPoint.setFlowData( volumeRate, oilRate, adjustedGasRate, waterRate );
|
||||
|
||||
resultPoint.setConnectionFactor( connectionFactor );
|
||||
}
|
||||
|
||||
return resultPoint;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWellResultPoint
|
||||
RifReaderEclipseOutput::createWellResultPoint( const RigGridBase* grid, const well_conn_type* ert_connection, const char* wellName )
|
||||
{
|
||||
return createWellResultPoint( grid, ert_connection, nullptr, wellName );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Inverse distance interpolation of the supplied points and distance weights for
|
||||
/// the contributing points which are closest above, and closest below
|
||||
@ -1493,8 +1514,8 @@ public:
|
||||
{
|
||||
if ( !wellResultPoint.isCell() ) return false;
|
||||
|
||||
size_t gridIndex = wellResultPoint.m_gridIndex;
|
||||
size_t gridCellIndex = wellResultPoint.m_gridCellIndex;
|
||||
size_t gridIndex = wellResultPoint.gridIndex();
|
||||
size_t gridCellIndex = wellResultPoint.cellIndex();
|
||||
|
||||
size_t reservoirCellIdx = m_mainGrid->reservoirCellIndexByGridAndGridLocalCellIndex( gridIndex, gridCellIndex );
|
||||
|
||||
@ -1657,11 +1678,11 @@ void RifReaderEclipseOutput::readWellCells( const ecl_grid_type* mainEclGrid, bo
|
||||
const well_conn_type* ert_wellhead = well_state_iget_wellhead( ert_well_state, static_cast<int>( gridNr ) );
|
||||
if ( ert_wellhead )
|
||||
{
|
||||
wellResFrame.m_wellHead = createWellResultPoint( grids[gridNr], ert_wellhead, -1, -1, wellName );
|
||||
wellResFrame.m_wellHead = createWellResultPoint( grids[gridNr], ert_wellhead, wellName );
|
||||
|
||||
// HACK: Ert returns open as "this is equally wrong as closed for well heads".
|
||||
// Well heads are not open jfr mail communication with HHGS and JH Statoil 07.01.2016
|
||||
wellResFrame.m_wellHead.m_isOpen = false;
|
||||
wellResFrame.m_wellHead.setIsOpen( false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1717,7 +1738,7 @@ void RifReaderEclipseOutput::readWellCells( const ecl_grid_type* mainEclGrid, bo
|
||||
{
|
||||
well_conn_type* ert_connection = well_conn_collection_iget( connections, connIdx );
|
||||
wellResultBranch.m_branchResultPoints.push_back(
|
||||
createWellResultPoint( grids[gridNr], ert_connection, branchId, well_segment_get_id( segment ), wellName ) );
|
||||
createWellResultPoint( grids[gridNr], ert_connection, segment, wellName ) );
|
||||
}
|
||||
|
||||
segmentHasConnections = true;
|
||||
@ -1725,11 +1746,10 @@ void RifReaderEclipseOutput::readWellCells( const ecl_grid_type* mainEclGrid, bo
|
||||
// Prepare data for segment position calculation
|
||||
|
||||
well_conn_type* ert_connection = well_conn_collection_iget( connections, 0 );
|
||||
RigWellResultPoint point =
|
||||
createWellResultPoint( grids[gridNr], ert_connection, branchId, well_segment_get_id( segment ), wellName );
|
||||
lastConnectionPos = grids[gridNr]->cell( point.m_gridCellIndex ).center();
|
||||
RigWellResultPoint point = createWellResultPoint( grids[gridNr], ert_connection, segment, wellName );
|
||||
lastConnectionPos = grids[gridNr]->cell( point.cellIndex() ).center();
|
||||
cvf::Vec3d cellVxes[8];
|
||||
grids[gridNr]->cellCornerVertices( point.m_gridCellIndex, cellVxes );
|
||||
grids[gridNr]->cellCornerVertices( point.cellIndex(), cellVxes );
|
||||
lastConnectionCellCorner = cellVxes[0];
|
||||
lastConnectionCellSize = ( lastConnectionPos - cellVxes[0] ).length();
|
||||
|
||||
@ -1747,8 +1767,7 @@ void RifReaderEclipseOutput::readWellCells( const ecl_grid_type* mainEclGrid, bo
|
||||
if ( !segmentHasConnections )
|
||||
{
|
||||
RigWellResultPoint data;
|
||||
data.m_ertBranchId = branchId;
|
||||
data.m_ertSegmentId = well_segment_get_id( segment );
|
||||
data.setSegmentData( branchId, well_segment_get_id( segment ) );
|
||||
|
||||
wellResultBranch.m_branchResultPoints.push_back( data );
|
||||
|
||||
@ -1801,11 +1820,7 @@ void RifReaderEclipseOutput::readWellCells( const ecl_grid_type* mainEclGrid, bo
|
||||
// Select the deepest connection
|
||||
well_conn_type* ert_connection = well_conn_collection_iget( connections, connectionCount - 1 );
|
||||
|
||||
auto resultPoint = createWellResultPoint( grids[gridNr],
|
||||
ert_connection,
|
||||
well_segment_get_branch_id( outletSegment ),
|
||||
well_segment_get_id( outletSegment ),
|
||||
wellName );
|
||||
auto resultPoint = createWellResultPoint( grids[gridNr], ert_connection, outletSegment, wellName );
|
||||
// This result point is only supposed to be used to indicate connection to a parent well
|
||||
// Clear all flow in this result point
|
||||
resultPoint.clearAllFlow();
|
||||
@ -1822,8 +1837,7 @@ void RifReaderEclipseOutput::readWellCells( const ecl_grid_type* mainEclGrid, bo
|
||||
// Store the result point
|
||||
|
||||
RigWellResultPoint data;
|
||||
data.m_ertBranchId = well_segment_get_branch_id( outletSegment );
|
||||
data.m_ertSegmentId = well_segment_get_id( outletSegment );
|
||||
data.setSegmentData( well_segment_get_branch_id( outletSegment ), well_segment_get_id( outletSegment ) );
|
||||
wellResultBranch.m_branchResultPoints.push_back( data );
|
||||
|
||||
// Store data for segment position calculation,
|
||||
@ -1954,17 +1968,12 @@ void RifReaderEclipseOutput::readWellCells( const ecl_grid_type* mainEclGrid, bo
|
||||
prevResPoint = wellResultBranch.m_branchResultPoints[rpIdx - 1];
|
||||
}
|
||||
|
||||
cvf::Vec3d lastConnectionPos = grids[prevResPoint.m_gridIndex]->cell( prevResPoint.m_gridCellIndex ).center();
|
||||
cvf::Vec3d lastConnectionPos = grids[prevResPoint.gridIndex()]->cell( prevResPoint.cellIndex() ).center();
|
||||
|
||||
SegmentPositionContribution posContrib( prevResPoint.m_ertSegmentId,
|
||||
lastConnectionPos,
|
||||
0.0,
|
||||
false,
|
||||
-1,
|
||||
prevResPoint.m_ertSegmentId,
|
||||
true );
|
||||
SegmentPositionContribution
|
||||
posContrib( prevResPoint.segmentId(), lastConnectionPos, 0.0, false, -1, prevResPoint.segmentId(), true );
|
||||
|
||||
int ertSegmentId = resPoint.m_ertSegmentId;
|
||||
int ertSegmentId = resPoint.segmentId();
|
||||
|
||||
std::map<int, std::vector<SegmentPositionContribution>>::iterator posContribIt;
|
||||
posContribIt = segmentIdToPositionContrib.find( ertSegmentId );
|
||||
@ -1973,7 +1982,7 @@ void RifReaderEclipseOutput::readWellCells( const ecl_grid_type* mainEclGrid, bo
|
||||
std::vector<SegmentPositionContribution> posContributions = posContribIt->second;
|
||||
for ( size_t i = 0; i < posContributions.size(); ++i )
|
||||
{
|
||||
posContributions[i].m_segmentIdAbove = prevResPoint.m_ertSegmentId;
|
||||
posContributions[i].m_segmentIdAbove = prevResPoint.segmentId();
|
||||
}
|
||||
posContributions.push_back( posContrib );
|
||||
|
||||
@ -2006,7 +2015,7 @@ void RifReaderEclipseOutput::readWellCells( const ecl_grid_type* mainEclGrid, bo
|
||||
RigWellResultPoint& resPoint = wellResultBranch.m_branchResultPoints[rpIdx];
|
||||
if ( !resPoint.isCell() )
|
||||
{
|
||||
resPoint.m_bottomPosition = bottomPositions[resPoint.m_ertSegmentId];
|
||||
resPoint.setBottomPosition( bottomPositions[resPoint.segmentId()] );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2023,10 +2032,10 @@ void RifReaderEclipseOutput::readWellCells( const ecl_grid_type* mainEclGrid, bo
|
||||
const well_conn_type* ert_wellhead = well_state_iget_wellhead( ert_well_state, static_cast<int>( gridNr ) );
|
||||
if ( ert_wellhead )
|
||||
{
|
||||
RigWellResultPoint wellHeadRp = createWellResultPoint( grids[gridNr], ert_wellhead, -1, -1, wellName );
|
||||
RigWellResultPoint wellHeadRp = createWellResultPoint( grids[gridNr], ert_wellhead, wellName );
|
||||
// HACK: Ert returns open as "this is equally wrong as closed for well heads".
|
||||
// Well heads are not open jfr mail communication with HHGS and JH Statoil 07.01.2016
|
||||
wellHeadRp.m_isOpen = false;
|
||||
wellHeadRp.setIsOpen( false );
|
||||
|
||||
if ( !subCellConnCalc.hasSubCellConnection( wellHeadRp ) ) wellResFrame.m_wellHead = wellHeadRp;
|
||||
}
|
||||
@ -2051,7 +2060,7 @@ void RifReaderEclipseOutput::readWellCells( const ecl_grid_type* mainEclGrid, bo
|
||||
for ( int connIdx = 0; connIdx < connectionCount; connIdx++ )
|
||||
{
|
||||
well_conn_type* ert_connection = well_conn_collection_iget( connections, connIdx );
|
||||
RigWellResultPoint wellRp = createWellResultPoint( grids[gridNr], ert_connection, -1, -1, wellName );
|
||||
RigWellResultPoint wellRp = createWellResultPoint( grids[gridNr], ert_connection, wellName );
|
||||
|
||||
if ( !subCellConnCalc.hasSubCellConnection( wellRp ) )
|
||||
{
|
||||
|
@ -39,9 +39,10 @@ class QDateTime;
|
||||
|
||||
struct RigWellResultPoint;
|
||||
|
||||
typedef struct ecl_grid_struct ecl_grid_type;
|
||||
typedef struct ecl_file_struct ecl_file_type;
|
||||
typedef struct well_conn_struct well_conn_type;
|
||||
typedef struct ecl_grid_struct ecl_grid_type;
|
||||
typedef struct ecl_file_struct ecl_file_type;
|
||||
typedef struct well_conn_struct well_conn_type;
|
||||
typedef struct well_segment_struct well_segment_type;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
@ -91,11 +92,12 @@ private:
|
||||
|
||||
std::string ertGridName( size_t gridNr );
|
||||
|
||||
RigWellResultPoint createWellResultPoint( const RigGridBase* grid,
|
||||
const well_conn_type* ert_connection,
|
||||
int ertBranchId,
|
||||
int ertSegmentId,
|
||||
const char* wellName );
|
||||
RigWellResultPoint createWellResultPoint( const RigGridBase* grid, const well_conn_type* ert_connection, const char* wellName );
|
||||
|
||||
RigWellResultPoint createWellResultPoint( const RigGridBase* grid,
|
||||
const well_conn_type* ert_connection,
|
||||
const well_segment_type* segment,
|
||||
const char* wellName );
|
||||
|
||||
void importFaults( const QStringList& fileSet, cvf::Collection<RigFault>* faults );
|
||||
|
||||
|
@ -22,8 +22,11 @@
|
||||
|
||||
#include "RiaColorTables.h"
|
||||
#include "RiaExtractionTools.h"
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "RigEclipseWellLogExtractor.h"
|
||||
#include "RigMswCenterLineCalculator.h"
|
||||
#include "RigSimulationWellCenterLineCalculator.h"
|
||||
#include "RigVirtualPerforationTransmissibilities.h"
|
||||
#include "RigWellLogExtractor.h"
|
||||
#include "RigWellPath.h"
|
||||
@ -154,9 +157,27 @@ void RivSimWellPipesPartMgr::buildWellPipeParts( const caf::DisplayCoordTransfor
|
||||
m_wellBranches.clear();
|
||||
m_flattenedBranchWellHeadOffsets.clear();
|
||||
m_pipeBranchesCLCoords.clear();
|
||||
std::vector<std::vector<RigWellResultPoint>> pipeBranchesCellIds;
|
||||
|
||||
m_simWellInView->calculateWellPipeStaticCenterLine( m_pipeBranchesCLCoords, pipeBranchesCellIds );
|
||||
auto createSimWells = []( RimSimWellInView* simWellInView ) -> std::vector<SimulationWellCellBranch> {
|
||||
std::vector<SimulationWellCellBranch> simWellBranches;
|
||||
const RigSimWellData* simWellData = simWellInView->simWellData();
|
||||
if ( simWellData && simWellData->isMultiSegmentWell() )
|
||||
{
|
||||
simWellBranches = RigMswCenterLineCalculator::calculateMswWellPipeGeometry( simWellInView );
|
||||
}
|
||||
else
|
||||
{
|
||||
simWellBranches = RigSimulationWellCenterLineCalculator::calculateWellPipeStaticCenterline( simWellInView );
|
||||
}
|
||||
|
||||
return simWellBranches;
|
||||
};
|
||||
|
||||
auto simWells = createSimWells( m_simWellInView );
|
||||
const auto& [coords, wellCells] = RigSimulationWellCenterLineCalculator::extractBranchData( simWells );
|
||||
|
||||
m_pipeBranchesCLCoords = coords;
|
||||
std::vector<std::vector<RigWellResultPoint>> pipeBranchesCellIds = wellCells;
|
||||
|
||||
double pipeRadius = m_simWellInView->pipeRadius();
|
||||
int crossSectionVertexCount = m_simWellInView->pipeCrossSectionVertexCount();
|
||||
@ -294,7 +315,7 @@ void RivSimWellPipesPartMgr::buildWellPipeParts( const caf::DisplayCoordTransfor
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !virtualPerforationResult->showConnectionFactorsOnClosedConnections() && !wResCell->m_isOpen )
|
||||
if ( !virtualPerforationResult->showConnectionFactorsOnClosedConnections() && !wResCell->isOpen() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -417,14 +438,14 @@ void RivSimWellPipesPartMgr::updatePipeResultColor( size_t frameIndex )
|
||||
|
||||
if ( cellIds[wcIdx].isCell() )
|
||||
{
|
||||
wResCell = wResFrame->findResultCellWellHeadExcluded( cellIds[wcIdx].m_gridIndex, cellIds[wcIdx].m_gridCellIndex );
|
||||
wResCell = wResFrame->findResultCellWellHeadExcluded( cellIds[wcIdx].gridIndex(), cellIds[wcIdx].cellIndex() );
|
||||
}
|
||||
|
||||
if ( wResCell )
|
||||
{
|
||||
double cellState = defaultState;
|
||||
|
||||
if ( wResCell->m_isOpen )
|
||||
if ( wResCell->isOpen() )
|
||||
{
|
||||
switch ( wResFrame->m_productionType )
|
||||
{
|
||||
|
@ -88,13 +88,13 @@ void RivWellSpheresPartMgr::appendDynamicGeometryPartsToModel( cvf::ModelBasicLi
|
||||
{
|
||||
for ( const RigWellResultPoint& wellResultPoint : wellResultBranch.m_branchResultPoints )
|
||||
{
|
||||
size_t gridIndex = wellResultPoint.m_gridIndex;
|
||||
size_t gridIndex = wellResultPoint.gridIndex();
|
||||
|
||||
if ( gridIndex >= mainGrid->gridCount() ) continue;
|
||||
|
||||
const RigGridBase* rigGrid = mainGrid->gridByIndex( gridIndex );
|
||||
|
||||
size_t gridCellIndex = wellResultPoint.m_gridCellIndex;
|
||||
size_t gridCellIndex = wellResultPoint.cellIndex();
|
||||
if ( gridCellIndex >= rigGrid->cellCount() ) continue;
|
||||
|
||||
const RigCell& rigCell = rigGrid->cell( gridCellIndex );
|
||||
@ -207,7 +207,7 @@ cvf::Color3f RivWellSpheresPartMgr::wellCellColor( const RigWellResultFrame* wel
|
||||
|
||||
if ( wellColl )
|
||||
{
|
||||
if ( wellResultPoint.m_isOpen )
|
||||
if ( wellResultPoint.isOpen() )
|
||||
{
|
||||
switch ( wellResultFrame->m_productionType )
|
||||
{
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "RigCell.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigSimWellData.h"
|
||||
#include "RigSimulationWellCenterLineCalculator.h"
|
||||
#include "RigWellPath.h"
|
||||
#include "RigWellResultPoint.h"
|
||||
|
||||
#include "RimEclipseView.h"
|
||||
@ -30,7 +32,6 @@
|
||||
#include "RimProject.h"
|
||||
#include "RimSimWellInView.h"
|
||||
|
||||
#include "RigWellPath.h"
|
||||
#include "cafPdmUiDoubleSliderEditor.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimSimWellFracture, "SimWellFracture" );
|
||||
@ -344,14 +345,10 @@ void RimSimWellFracture::computeSimWellBranchCenterLines()
|
||||
this->firstAncestorOrThisOfType( rimWell );
|
||||
CVF_ASSERT( rimWell );
|
||||
|
||||
std::vector<std::vector<cvf::Vec3d>> pipeBranchesCLCoords;
|
||||
std::vector<std::vector<RigWellResultPoint>> pipeBranchesCellIds;
|
||||
|
||||
rimWell->calculateWellPipeStaticCenterLine( pipeBranchesCLCoords, pipeBranchesCellIds );
|
||||
|
||||
for ( const auto& branch : pipeBranchesCLCoords )
|
||||
const auto simWellBranches = RigSimulationWellCenterLineCalculator::calculateWellPipeStaticCenterline( rimWell );
|
||||
for ( const auto& [coords, wellCells] : simWellBranches )
|
||||
{
|
||||
RigSimulationWellCoordsAndMD wellPathWithMD( branch );
|
||||
RigSimulationWellCoordsAndMD wellPathWithMD( coords );
|
||||
|
||||
m_branchCenterLines.push_back( wellPathWithMD );
|
||||
}
|
||||
|
@ -191,11 +191,11 @@ std::map<std::string, std::vector<int>> RimFlowDiagSolution::allTracerActiveCell
|
||||
{
|
||||
for ( const RigWellResultPoint& wrp : wBr.m_branchResultPoints )
|
||||
{
|
||||
if ( wrp.isValid() && wrp.m_isOpen &&
|
||||
if ( wrp.isValid() && wrp.isOpen() &&
|
||||
( ( useInjectors && wrp.flowRate() < 0.0 ) || ( !useInjectors && wrp.flowRate() > 0.0 ) ) )
|
||||
{
|
||||
RigGridBase* grid = mainGrid->gridByIndex( wrp.m_gridIndex );
|
||||
size_t reservoirCellIndex = grid->reservoirCellIndex( wrp.m_gridCellIndex );
|
||||
RigGridBase* grid = mainGrid->gridByIndex( wrp.gridIndex() );
|
||||
size_t reservoirCellIndex = grid->reservoirCellIndex( wrp.cellIndex() );
|
||||
|
||||
int cellActiveIndex = static_cast<int>( activeCellInfo->cellResultIndex( reservoirCellIndex ) );
|
||||
|
||||
|
@ -454,18 +454,16 @@ RimWellAllocationOverTimeCollection RimWellAllocationOverTimePlot::createWellAll
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<std::vector<cvf::Vec3d>> pipeBranchesCLCoords;
|
||||
std::vector<std::vector<RigWellResultPoint>> pipeBranchesCellIds;
|
||||
std::map<QString, const std::vector<double>*> tracerFractionCellValues =
|
||||
RimWellAllocationTools::findOrCreateRelevantTracerCellFractions( simWellData, m_flowDiagSolution, i );
|
||||
|
||||
RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineFromWellFrame( m_case->eclipseCaseData(),
|
||||
simWellData,
|
||||
i,
|
||||
branchDetection,
|
||||
true,
|
||||
pipeBranchesCLCoords,
|
||||
pipeBranchesCellIds );
|
||||
auto simWellBranches = RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineForTimeStep( m_case->eclipseCaseData(),
|
||||
simWellData,
|
||||
i,
|
||||
branchDetection,
|
||||
true );
|
||||
|
||||
const auto& [pipeBranchesCLCoords, pipeBranchesCellIds] = RigSimulationWellCenterLineCalculator::extractBranchData( simWellBranches );
|
||||
|
||||
if ( tracerFractionCellValues.size() )
|
||||
{
|
||||
|
@ -246,16 +246,12 @@ void RimWellAllocationPlot::updateFromWell()
|
||||
if ( !simWellData ) return;
|
||||
|
||||
// Set up the Accumulated Well Flow Calculator
|
||||
std::vector<std::vector<cvf::Vec3d>> pipeBranchesCLCoords;
|
||||
std::vector<std::vector<RigWellResultPoint>> pipeBranchesCellIds;
|
||||
|
||||
RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineFromWellFrame( m_case->eclipseCaseData(),
|
||||
simWellData,
|
||||
m_timeStep,
|
||||
m_branchDetection,
|
||||
true,
|
||||
pipeBranchesCLCoords,
|
||||
pipeBranchesCellIds );
|
||||
const auto simWellBranches = RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineForTimeStep( m_case->eclipseCaseData(),
|
||||
simWellData,
|
||||
m_timeStep,
|
||||
m_branchDetection,
|
||||
true );
|
||||
const auto& [pipeBranchesCLCoords, pipeBranchesCellIds] = RigSimulationWellCenterLineCalculator::extractBranchData( simWellBranches );
|
||||
|
||||
std::map<QString, const std::vector<double>*> tracerFractionCellValues =
|
||||
RimWellAllocationTools::findOrCreateRelevantTracerCellFractions( simWellData, m_flowDiagSolution, m_timeStep );
|
||||
|
@ -353,15 +353,14 @@ public:
|
||||
m_pipeBranchMeasuredDepths.push_back( intersections[wpExIdx].endMD );
|
||||
|
||||
RigWellResultPoint resPoint;
|
||||
resPoint.m_isOpen = true;
|
||||
resPoint.m_gridIndex = 0; // Always main grid
|
||||
resPoint.m_gridCellIndex = globCellIdx; // Shortcut, since we only have
|
||||
// main grid results from RFT
|
||||
resPoint.setIsOpen( true );
|
||||
resPoint.setGridIndex( 0 ); // Always main grid
|
||||
resPoint.setGridCellIndex( globCellIdx ); // Shortcut, since we only have
|
||||
// main grid results from RFT
|
||||
|
||||
resPoint.m_gasRate = RiaEclipseUnitTools::convertSurfaceGasFlowRateToOilEquivalents( eclCase->eclipseCaseData()->unitsType(),
|
||||
gasRates[it->second] );
|
||||
resPoint.m_oilRate = oilRates[it->second];
|
||||
resPoint.m_waterRate = watRates[it->second];
|
||||
const double adjustedGasRate =
|
||||
RiaEclipseUnitTools::convertSurfaceGasFlowRateToOilEquivalents( eclCase->eclipseCaseData()->unitsType(), gasRates[it->second] );
|
||||
resPoint.setFlowData( -1.0, oilRates[it->second], adjustedGasRate, watRates[it->second] );
|
||||
|
||||
m_pipeBranchWellResultPoints.push_back( resPoint );
|
||||
|
||||
@ -415,8 +414,8 @@ public:
|
||||
const std::vector<RigWellResultPoint>& branchResPoints = resFrame->m_wellResultBranches[brIdx].m_branchResultPoints;
|
||||
for ( size_t wrpIdx = 0; wrpIdx < branchResPoints.size(); wrpIdx++ )
|
||||
{
|
||||
const RigGridBase* grid = mainGrid->gridByIndex( branchResPoints[wrpIdx].m_gridIndex );
|
||||
size_t globalCellIndex = grid->reservoirCellIndex( branchResPoints[wrpIdx].m_gridCellIndex );
|
||||
const RigGridBase* grid = mainGrid->gridByIndex( branchResPoints[wrpIdx].gridIndex() );
|
||||
size_t globalCellIndex = grid->reservoirCellIndex( branchResPoints[wrpIdx].cellIndex() );
|
||||
|
||||
globCellIdxToIdxInSimWellBranch[globalCellIndex] = std::make_pair( brIdx, wrpIdx );
|
||||
}
|
||||
|
@ -433,7 +433,7 @@ const RigVirtualPerforationTransmissibilities* RimEclipseCase::computeAndGetVirt
|
||||
if ( r.isCell() )
|
||||
{
|
||||
RigCompletionData compData( wellRes->m_wellName,
|
||||
RigCompletionDataGridCell( r.m_gridCellIndex, rigEclipseCase->mainGrid() ),
|
||||
RigCompletionDataGridCell( r.cellIndex(), rigEclipseCase->mainGrid() ),
|
||||
0 );
|
||||
compData.setTransmissibility( r.connectionFactor() );
|
||||
|
||||
|
@ -1685,14 +1685,14 @@ void RimEclipseView::calculateVisibleWellCellsIncFence( cvf::UByteArray* visible
|
||||
const std::vector<RigWellResultPoint>& wsResCells = wellResSegments[wsIdx].m_branchResultPoints;
|
||||
for ( size_t cIdx = 0; cIdx < wsResCells.size(); ++cIdx )
|
||||
{
|
||||
if ( wsResCells[cIdx].m_gridIndex == grid->gridIndex() )
|
||||
if ( wsResCells[cIdx].gridIndex() == grid->gridIndex() )
|
||||
{
|
||||
if ( !wsResCells[cIdx].isCell() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t gridCellIndex = wsResCells[cIdx].m_gridCellIndex;
|
||||
size_t gridCellIndex = wsResCells[cIdx].cellIndex();
|
||||
( *visibleCells )[gridCellIndex] = true;
|
||||
|
||||
// Calculate well fence cells
|
||||
|
@ -192,15 +192,6 @@ std::vector<const RigWellPath*> RimSimWellInView::wellPipeBranches() const
|
||||
return std::vector<const RigWellPath*>();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSimWellInView::calculateWellPipeStaticCenterLine( std::vector<std::vector<cvf::Vec3d>>& pipeBranchesCLCoords,
|
||||
std::vector<std::vector<RigWellResultPoint>>& pipeBranchesCellIds )
|
||||
{
|
||||
RigSimulationWellCenterLineCalculator::calculateWellPipeStaticCenterline( this, pipeBranchesCLCoords, pipeBranchesCellIds );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// frameIndex = -1 will use the static well frame
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -340,8 +331,8 @@ bool RimSimWellInView::intersectsWellCellsFilteredCells( const RigWellResultFram
|
||||
|
||||
// First check the wellhead:
|
||||
|
||||
size_t gridIndex = wrsf->m_wellHead.m_gridIndex;
|
||||
size_t gridCellIndex = wrsf->m_wellHead.m_gridCellIndex;
|
||||
size_t gridIndex = wrsf->m_wellHead.gridIndex();
|
||||
size_t gridCellIndex = wrsf->m_wellHead.cellIndex();
|
||||
|
||||
if ( gridIndex != cvf::UNDEFINED_SIZE_T && gridCellIndex != cvf::UNDEFINED_SIZE_T )
|
||||
{
|
||||
@ -362,8 +353,8 @@ bool RimSimWellInView::intersectsWellCellsFilteredCells( const RigWellResultFram
|
||||
{
|
||||
if ( wellResultPoint.isCell() )
|
||||
{
|
||||
gridIndex = wellResultPoint.m_gridIndex;
|
||||
gridCellIndex = wellResultPoint.m_gridCellIndex;
|
||||
gridIndex = wellResultPoint.gridIndex();
|
||||
gridCellIndex = wellResultPoint.cellIndex();
|
||||
|
||||
const cvf::UByteArray* cellVisibility = rvMan->cellVisibility( visGridPart, gridIndex, frameIndex );
|
||||
if ( gridCellIndex < cellVisibility->size() && ( *cellVisibility )[gridCellIndex] )
|
||||
@ -770,24 +761,21 @@ void RimSimWellInView::scaleDisk( double minValue, double maxValue )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::BoundingBox RimSimWellInView::boundingBoxInDomainCoords() const
|
||||
{
|
||||
std::vector<std::vector<cvf::Vec3d>> pipeBranchesCLCoords;
|
||||
std::vector<std::vector<RigWellResultPoint>> pipeBranchesCellIds;
|
||||
|
||||
auto noConst = const_cast<RimSimWellInView*>( this );
|
||||
RigSimulationWellCenterLineCalculator::calculateWellPipeStaticCenterline( noConst, pipeBranchesCLCoords, pipeBranchesCellIds );
|
||||
auto noConst = const_cast<RimSimWellInView*>( this );
|
||||
auto simWellBranches = RigSimulationWellCenterLineCalculator::calculateWellPipeStaticCenterline( noConst );
|
||||
|
||||
cvf::BoundingBox bb;
|
||||
for ( auto branch : pipeBranchesCLCoords )
|
||||
for ( const auto& [coords, wellCells] : simWellBranches )
|
||||
{
|
||||
if ( !branch.empty() )
|
||||
if ( !coords.empty() )
|
||||
{
|
||||
// Estimate the bounding box based on first, middle and last coordinate of branches
|
||||
bb.add( branch.front() );
|
||||
bb.add( coords.front() );
|
||||
|
||||
size_t mid = branch.size() / 2;
|
||||
bb.add( branch[mid] );
|
||||
size_t mid = coords.size() / 2;
|
||||
bb.add( coords[mid] );
|
||||
|
||||
bb.add( branch.back() );
|
||||
bb.add( coords.back() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,9 +76,6 @@ public:
|
||||
|
||||
std::vector<const RigWellPath*> wellPipeBranches() const;
|
||||
|
||||
void calculateWellPipeStaticCenterLine( std::vector<std::vector<cvf::Vec3d>>& pipeBranchesCLCoords,
|
||||
std::vector<std::vector<RigWellResultPoint>>& pipeBranchesCellIds );
|
||||
|
||||
void wellHeadTopBottomPosition( int frameIndex, cvf::Vec3d* top, cvf::Vec3d* bottom );
|
||||
double pipeRadius();
|
||||
int pipeCrossSectionVertexCount();
|
||||
|
@ -409,9 +409,9 @@ void RimStreamlineInViewCollection::findStartCells( int
|
||||
{
|
||||
for ( const auto& point : branch.m_branchResultPoints )
|
||||
{
|
||||
if ( point.isValid() && point.m_isOpen )
|
||||
if ( point.isValid() && point.isOpen() )
|
||||
{
|
||||
RigCell cell = grids[point.m_gridIndex]->cell( point.m_gridCellIndex );
|
||||
RigCell cell = grids[point.gridIndex()]->cell( point.cellIndex() );
|
||||
if ( frame->m_productionType == RiaDefines::WellProductionType::PRODUCER )
|
||||
{
|
||||
outProducerCells.push_back( std::pair<QString, RigCell>( swdata->m_wellName, cell ) );
|
||||
|
@ -96,6 +96,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigSurfaceStatisticsCalculator.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigWellLogIndexDepthOffset.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigPressureDepthData.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigMswCenterLineCalculator.h
|
||||
)
|
||||
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
@ -189,6 +190,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigSurfaceStatisticsCalculator.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigWellLogIndexDepthOffset.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigPressureDepthData.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigMswCenterLineCalculator.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
|
||||
|
@ -711,9 +711,9 @@ std::vector<double> RigAccWellFlowCalculator::calculateWellCellFlowPrTracer( con
|
||||
|
||||
if ( m_tracerCellFractionValues )
|
||||
{
|
||||
if ( wellCell.isCell() && wellCell.m_isOpen )
|
||||
if ( wellCell.isCell() && wellCell.isOpen() )
|
||||
{
|
||||
size_t resCellIndex = m_cellIndexCalculator.resultCellIndex( wellCell.m_gridIndex, wellCell.m_gridCellIndex );
|
||||
size_t resCellIndex = m_cellIndexCalculator.resultCellIndex( wellCell.gridIndex(), wellCell.cellIndex() );
|
||||
size_t tracerIdx = 0;
|
||||
double totalTracerFractionInCell = 0.0;
|
||||
for ( const auto& tracerFractionValsPair : ( *m_tracerCellFractionValues ) )
|
||||
@ -768,23 +768,23 @@ std::vector<size_t> RigAccWellFlowCalculator::wrpToUniqueWrpIndexFromBottom( con
|
||||
|
||||
if ( clSegIdx < 0 ) return resPointToConnectionIndexFromBottom;
|
||||
|
||||
size_t prevGridIdx = branchCells[clSegIdx].m_gridIndex;
|
||||
size_t prevGridCellIdx = branchCells[clSegIdx].m_gridCellIndex;
|
||||
int prevErtSegId = branchCells[clSegIdx].m_ertSegmentId;
|
||||
int prevErtBranchId = branchCells[clSegIdx].m_ertBranchId;
|
||||
size_t prevGridIdx = branchCells[clSegIdx].gridIndex();
|
||||
size_t prevGridCellIdx = branchCells[clSegIdx].cellIndex();
|
||||
int prevErtSegId = branchCells[clSegIdx].segmentId();
|
||||
int prevErtBranchId = branchCells[clSegIdx].branchId();
|
||||
|
||||
while ( clSegIdx >= 0 )
|
||||
{
|
||||
if ( branchCells[clSegIdx].isValid() &&
|
||||
( branchCells[clSegIdx].m_gridIndex != prevGridIdx || branchCells[clSegIdx].m_gridCellIndex != prevGridCellIdx ||
|
||||
branchCells[clSegIdx].m_ertSegmentId != prevErtSegId || branchCells[clSegIdx].m_ertBranchId != prevErtBranchId ) )
|
||||
( branchCells[clSegIdx].gridIndex() != prevGridIdx || branchCells[clSegIdx].cellIndex() != prevGridCellIdx ||
|
||||
branchCells[clSegIdx].segmentId() != prevErtSegId || branchCells[clSegIdx].branchId() != prevErtBranchId ) )
|
||||
{
|
||||
++connIdxFromBottom;
|
||||
|
||||
prevGridIdx = branchCells[clSegIdx].m_gridIndex;
|
||||
prevGridCellIdx = branchCells[clSegIdx].m_gridCellIndex;
|
||||
prevErtSegId = branchCells[clSegIdx].m_ertSegmentId;
|
||||
prevErtBranchId = branchCells[clSegIdx].m_ertBranchId;
|
||||
prevGridIdx = branchCells[clSegIdx].gridIndex();
|
||||
prevGridCellIdx = branchCells[clSegIdx].cellIndex();
|
||||
prevErtSegId = branchCells[clSegIdx].segmentId();
|
||||
prevErtBranchId = branchCells[clSegIdx].branchId();
|
||||
}
|
||||
|
||||
resPointToConnectionIndexFromBottom[clSegIdx] = connIdxFromBottom;
|
||||
@ -812,10 +812,10 @@ std::vector<size_t> RigAccWellFlowCalculator::findDownStreamBranchIdxs( const Ri
|
||||
|
||||
for ( size_t bIdx = 0; bIdx < m_pipeBranchesWellResultPoints.size(); ++bIdx )
|
||||
{
|
||||
if ( m_pipeBranchesWellResultPoints[bIdx][0].m_gridIndex == connectionPoint.m_gridIndex &&
|
||||
m_pipeBranchesWellResultPoints[bIdx][0].m_gridCellIndex == connectionPoint.m_gridCellIndex &&
|
||||
m_pipeBranchesWellResultPoints[bIdx][0].m_ertBranchId == connectionPoint.m_ertBranchId &&
|
||||
m_pipeBranchesWellResultPoints[bIdx][0].m_ertSegmentId == connectionPoint.m_ertSegmentId )
|
||||
if ( m_pipeBranchesWellResultPoints[bIdx][0].gridIndex() == connectionPoint.gridIndex() &&
|
||||
m_pipeBranchesWellResultPoints[bIdx][0].cellIndex() == connectionPoint.cellIndex() &&
|
||||
m_pipeBranchesWellResultPoints[bIdx][0].branchId() == connectionPoint.branchId() &&
|
||||
m_pipeBranchesWellResultPoints[bIdx][0].segmentId() == connectionPoint.segmentId() )
|
||||
{
|
||||
downStreamBranchIdxs.push_back( bIdx );
|
||||
}
|
||||
|
@ -248,8 +248,8 @@ void RigEclipseCaseData::computeWellCellsPrGrid()
|
||||
size_t cdIdx;
|
||||
for ( cdIdx = 0; cdIdx < wellSegment.m_branchResultPoints.size(); ++cdIdx )
|
||||
{
|
||||
size_t gridIndex = wellSegment.m_branchResultPoints[cdIdx].m_gridIndex;
|
||||
size_t gridCellIndex = wellSegment.m_branchResultPoints[cdIdx].m_gridCellIndex;
|
||||
size_t gridIndex = wellSegment.m_branchResultPoints[cdIdx].gridIndex();
|
||||
size_t gridCellIndex = wellSegment.m_branchResultPoints[cdIdx].cellIndex();
|
||||
|
||||
if ( gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size() )
|
||||
{
|
||||
@ -340,8 +340,8 @@ const RigCell& RigEclipseCaseData::cellFromWellResultCell( const RigWellResultPo
|
||||
{
|
||||
CVF_ASSERT( wellResultCell.isCell() );
|
||||
|
||||
size_t gridIndex = wellResultCell.m_gridIndex;
|
||||
size_t gridCellIndex = wellResultCell.m_gridCellIndex;
|
||||
size_t gridIndex = wellResultCell.gridIndex();
|
||||
size_t gridCellIndex = wellResultCell.cellIndex();
|
||||
|
||||
std::vector<const RigGridBase*> grids;
|
||||
allGrids( &grids );
|
||||
@ -356,11 +356,11 @@ bool RigEclipseCaseData::findSharedSourceFace( cvf::StructGridInterface::FaceTyp
|
||||
const RigWellResultPoint& sourceWellCellResult,
|
||||
const RigWellResultPoint& otherWellCellResult ) const
|
||||
{
|
||||
size_t gridIndex = sourceWellCellResult.m_gridIndex;
|
||||
size_t gridCellIndex = sourceWellCellResult.m_gridCellIndex;
|
||||
size_t gridIndex = sourceWellCellResult.gridIndex();
|
||||
size_t gridCellIndex = sourceWellCellResult.cellIndex();
|
||||
|
||||
size_t otherGridIndex = otherWellCellResult.m_gridIndex;
|
||||
size_t otherGridCellIndex = otherWellCellResult.m_gridCellIndex;
|
||||
size_t otherGridIndex = otherWellCellResult.gridIndex();
|
||||
size_t otherGridCellIndex = otherWellCellResult.cellIndex();
|
||||
|
||||
if ( gridIndex != otherGridIndex ) return false;
|
||||
|
||||
@ -504,22 +504,17 @@ std::vector<const RigWellPath*>
|
||||
|
||||
if ( m_simWellBranchCache.find( simWellSeachItem ) == m_simWellBranchCache.end() )
|
||||
{
|
||||
std::vector<std::vector<cvf::Vec3d>> pipeBranchesCLCoords;
|
||||
std::vector<std::vector<RigWellResultPoint>> pipeBranchesCellIds;
|
||||
|
||||
RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineFromWellFrame( this,
|
||||
simWellData,
|
||||
-1,
|
||||
useAutoDetectionOfBranches,
|
||||
includeAllCellCenters,
|
||||
pipeBranchesCLCoords,
|
||||
pipeBranchesCellIds );
|
||||
const auto simWellBranches = RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineForTimeStep( this,
|
||||
simWellData,
|
||||
-1,
|
||||
useAutoDetectionOfBranches,
|
||||
includeAllCellCenters );
|
||||
|
||||
m_simWellBranchCache.insert( std::make_pair( simWellSeachItem, cvf::Collection<RigWellPath>() ) );
|
||||
|
||||
for ( size_t brIdx = 0; brIdx < pipeBranchesCLCoords.size(); ++brIdx )
|
||||
for ( const auto& [coords, wellCells] : simWellBranches )
|
||||
{
|
||||
auto wellMdCalculator = RigSimulationWellCoordsAndMD( pipeBranchesCLCoords[brIdx] );
|
||||
auto wellMdCalculator = RigSimulationWellCoordsAndMD( coords );
|
||||
|
||||
cvf::ref<RigWellPath> newWellPath = new RigWellPath( wellMdCalculator.wellPathPoints(), wellMdCalculator.measuredDepths() );
|
||||
|
||||
|
@ -0,0 +1,342 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2023- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RigMswCenterLineCalculator.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RigCell.h"
|
||||
#include "RigCellFaceGeometryTools.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigSimWellData.h"
|
||||
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimSimWellInView.h"
|
||||
#include "RimSimWellInViewCollection.h"
|
||||
|
||||
#include "cvfRay.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<SimulationWellCellBranch> RigMswCenterLineCalculator::calculateMswWellPipeGeometry( RimSimWellInView* rimWell )
|
||||
{
|
||||
CVF_ASSERT( rimWell );
|
||||
|
||||
const RigSimWellData* simWellData = rimWell->simWellData();
|
||||
if ( !simWellData ) return {};
|
||||
|
||||
RimEclipseView* eclipseView;
|
||||
rimWell->firstAncestorOrThisOfType( eclipseView );
|
||||
|
||||
CVF_ASSERT( eclipseView );
|
||||
|
||||
if ( eclipseView->eclipseCase() && eclipseView->eclipseCase()->eclipseCaseData() )
|
||||
{
|
||||
auto eclipseCaseData = eclipseView->eclipseCase()->eclipseCaseData();
|
||||
int timeStepIndex = eclipseView->currentTimeStep();
|
||||
|
||||
return calculateMswWellPipeGeometryForTimeStep( eclipseCaseData, simWellData, timeStepIndex );
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<SimulationWellCellBranch>
|
||||
RigMswCenterLineCalculator::calculateMswWellPipeGeometryForTimeStep( const RigEclipseCaseData* eclipseCaseData,
|
||||
const RigSimWellData* wellResults,
|
||||
int timeStepIndex )
|
||||
{
|
||||
if ( timeStepIndex >= 0 && !wellResults->hasAnyValidCells( timeStepIndex ) ) return {};
|
||||
|
||||
const RigWellResultFrame* wellFramePtr = nullptr;
|
||||
|
||||
if ( timeStepIndex < 0 )
|
||||
{
|
||||
wellFramePtr = wellResults->staticWellCells();
|
||||
}
|
||||
else
|
||||
{
|
||||
wellFramePtr = wellResults->wellResultFrame( timeStepIndex );
|
||||
}
|
||||
|
||||
const RigWellResultFrame& wellFrame = *wellFramePtr;
|
||||
const std::vector<RigWellResultBranch>& resultBranches = wellFrame.m_wellResultBranches;
|
||||
|
||||
std::vector<WellBranch> wellBranches = mergeShortBranchesIntoLongBranches( resultBranches );
|
||||
|
||||
// Connect outlet segment of branches to parent branch
|
||||
|
||||
for ( const auto& resultBranch : resultBranches )
|
||||
{
|
||||
if ( resultBranch.m_branchResultPoints.empty() ) continue;
|
||||
|
||||
const auto firstResultPoint = resultBranch.m_branchResultPoints.front();
|
||||
|
||||
for ( auto& wellBranch : wellBranches )
|
||||
{
|
||||
if ( wellBranch.m_branchId == resultBranch.m_ertBranchId )
|
||||
{
|
||||
if ( firstResultPoint.branchId() == resultBranch.m_ertBranchId )
|
||||
{
|
||||
// The first result point is on the same branch, use well head as outlet
|
||||
RigWellResultPoint outletResultPoint = wellFrame.m_wellHead;
|
||||
|
||||
auto gridAndCellIndex = std::make_pair( outletResultPoint.gridIndex(), outletResultPoint.cellIndex() );
|
||||
wellBranch.m_segmentsWithGridCells[outletResultPoint.segmentId()].push_back( gridAndCellIndex );
|
||||
}
|
||||
else
|
||||
{
|
||||
// The first result point on a different branch. Find the branch and add the grid cell
|
||||
for ( const auto& candidateResultBranch : wellBranches )
|
||||
{
|
||||
if ( firstResultPoint.branchId() == candidateResultBranch.m_branchId )
|
||||
{
|
||||
std::pair<size_t, size_t> gridAndCellIndexForTieIn;
|
||||
|
||||
for ( const auto& [segment, gridAndCellIndices] : candidateResultBranch.m_segmentsWithGridCells )
|
||||
{
|
||||
if ( segment > firstResultPoint.segmentId() ) continue;
|
||||
if ( !gridAndCellIndices.empty() )
|
||||
{
|
||||
gridAndCellIndexForTieIn = gridAndCellIndices.front();
|
||||
}
|
||||
}
|
||||
|
||||
wellBranch.m_segmentsWithGridCells[firstResultPoint.segmentId()].push_back( gridAndCellIndexForTieIn );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<SimulationWellCellBranch> simWellBranches;
|
||||
for ( const auto& wellBranch : wellBranches )
|
||||
{
|
||||
std::vector<cvf::Vec3d> cellCenterCoords;
|
||||
std::vector<RigWellResultPoint> cellCenterResultPoints;
|
||||
|
||||
if ( wellBranch.m_branchId == 1 && !wellBranch.m_segmentsWithGridCells.empty() )
|
||||
{
|
||||
const auto& [firstSegment, gridAndCellIndices] = *wellBranch.m_segmentsWithGridCells.begin();
|
||||
if ( !gridAndCellIndices.empty() )
|
||||
{
|
||||
const auto& [gridIndex, cellIndex] = gridAndCellIndices.front();
|
||||
if ( gridIndex < eclipseCaseData->gridCount() && cellIndex < eclipseCaseData->grid( gridIndex )->cellCount() )
|
||||
{
|
||||
const RigCell& cell = eclipseCaseData->grid( gridIndex )->cell( cellIndex );
|
||||
cvf::Vec3d whStartPos = cell.faceCenter( cvf::StructGridInterface::NEG_K );
|
||||
|
||||
// Add extra coordinate between cell face and cell center
|
||||
// to make sure the well pipe terminated in a segment parallel to z-axis
|
||||
|
||||
cvf::Vec3d whIntermediate = whStartPos;
|
||||
whIntermediate.z() = ( whStartPos.z() + cell.center().z() ) / 2.0;
|
||||
|
||||
RigWellResultPoint resPoint;
|
||||
for ( const auto& resBranch : resultBranches )
|
||||
{
|
||||
for ( const auto& respoint : resBranch.m_branchResultPoints )
|
||||
{
|
||||
if ( respoint.segmentId() == firstSegment )
|
||||
{
|
||||
resPoint = respoint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cellCenterCoords.push_back( whStartPos );
|
||||
cellCenterResultPoints.push_back( resPoint );
|
||||
cellCenterCoords.push_back( whIntermediate );
|
||||
cellCenterResultPoints.push_back( resPoint );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( const auto& [segmentId, gridAndCellIndices] : wellBranch.m_segmentsWithGridCells )
|
||||
{
|
||||
for ( const auto& [gridIndex, cellIndex] : gridAndCellIndices )
|
||||
{
|
||||
if ( gridIndex < eclipseCaseData->gridCount() && cellIndex < eclipseCaseData->grid( gridIndex )->cellCount() )
|
||||
{
|
||||
const RigCell& cell = eclipseCaseData->grid( gridIndex )->cell( cellIndex );
|
||||
cvf::Vec3d pos = cell.center();
|
||||
|
||||
RigWellResultPoint resPoint;
|
||||
|
||||
// The result point is only used to transport the grid index and cell index
|
||||
// The current implementation will propagate the cell open state to the well segment from one cell to
|
||||
// the next.
|
||||
resPoint.setGridIndex( gridIndex );
|
||||
resPoint.setGridCellIndex( cellIndex );
|
||||
|
||||
cellCenterCoords.push_back( pos );
|
||||
cellCenterResultPoints.push_back( resPoint );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto simWellBranch = addCoordsAtCellFaceIntersectionsAndCreateBranch( cellCenterCoords, cellCenterResultPoints, eclipseCaseData );
|
||||
|
||||
simWellBranches.emplace_back( simWellBranch );
|
||||
}
|
||||
|
||||
return simWellBranches;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
SimulationWellCellBranch
|
||||
RigMswCenterLineCalculator::addCoordsAtCellFaceIntersectionsAndCreateBranch( const std::vector<cvf::Vec3d> branchCoords,
|
||||
const std::vector<RigWellResultPoint>& resultPoints,
|
||||
const RigEclipseCaseData* eclipseCaseData )
|
||||
{
|
||||
std::vector<cvf::Vec3d> adjustedCoords;
|
||||
std::vector<RigWellResultPoint> adjustedResPoints;
|
||||
|
||||
RigWellResultPoint previusPoint;
|
||||
|
||||
for ( size_t resPointIdx = 0; resPointIdx < resultPoints.size(); resPointIdx++ )
|
||||
{
|
||||
if ( resPointIdx >= branchCoords.size() ) continue;
|
||||
|
||||
const auto& currentPoint = resultPoints[resPointIdx];
|
||||
const auto& currentCellCenter = branchCoords[resPointIdx];
|
||||
|
||||
if ( previusPoint.isCell() )
|
||||
{
|
||||
const RigCell& prevCell = eclipseCaseData->cellFromWellResultCell( previusPoint );
|
||||
const cvf::Vec3d previousCellCenter = prevCell.center();
|
||||
|
||||
{
|
||||
// Insert extra coordinate at the location where the well path is leaving the previous cell
|
||||
|
||||
cvf::Ray rayToThisCell;
|
||||
rayToThisCell.setOrigin( previousCellCenter );
|
||||
rayToThisCell.setDirection( ( currentCellCenter - previousCellCenter ).getNormalized() );
|
||||
|
||||
cvf::Vec3d outOfPrevCell( previousCellCenter );
|
||||
|
||||
prevCell.firstIntersectionPoint( rayToThisCell, &outOfPrevCell );
|
||||
if ( ( currentCellCenter - outOfPrevCell ).lengthSquared() > 1e-3 )
|
||||
{
|
||||
adjustedCoords.push_back( outOfPrevCell );
|
||||
adjustedResPoints.push_back( RigWellResultPoint() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( currentPoint.isCell() )
|
||||
{
|
||||
// Insert extra coordinate at the location where the well path is entering the current cell
|
||||
|
||||
const RigCell& currentCell = eclipseCaseData->cellFromWellResultCell( currentPoint );
|
||||
|
||||
cvf::Ray rayFromThisCell;
|
||||
rayFromThisCell.setOrigin( currentCellCenter );
|
||||
rayFromThisCell.setDirection( ( previousCellCenter - currentCellCenter ).getNormalized() );
|
||||
|
||||
cvf::Vec3d outOfCurrentCell( currentCellCenter );
|
||||
|
||||
currentCell.firstIntersectionPoint( rayFromThisCell, &outOfCurrentCell );
|
||||
if ( ( currentCellCenter - outOfCurrentCell ).lengthSquared() > 1e-3 )
|
||||
{
|
||||
adjustedCoords.push_back( outOfCurrentCell );
|
||||
adjustedResPoints.push_back( currentPoint );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
adjustedResPoints.push_back( currentPoint );
|
||||
adjustedCoords.push_back( currentCellCenter );
|
||||
|
||||
previusPoint = currentPoint;
|
||||
}
|
||||
|
||||
// Duplicate last coord to make sure we have N+1 coordinates for N result points
|
||||
adjustedCoords.push_back( adjustedCoords.back() );
|
||||
|
||||
return { adjustedCoords, adjustedResPoints };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RigMswCenterLineCalculator::WellBranch>
|
||||
RigMswCenterLineCalculator::mergeShortBranchesIntoLongBranches( const std::vector<RigWellResultBranch>& resBranches )
|
||||
{
|
||||
std::vector<WellBranch> longWellBranches;
|
||||
std::vector<WellBranch> shortWellBranches;
|
||||
|
||||
for ( const auto& resultBranch : resBranches )
|
||||
{
|
||||
WellBranch branch;
|
||||
branch.m_branchId = resultBranch.m_ertBranchId;
|
||||
|
||||
for ( const auto& resPoint : resultBranch.m_branchResultPoints )
|
||||
{
|
||||
size_t gridIndex = resPoint.gridIndex();
|
||||
size_t gridCellIndex = resPoint.cellIndex();
|
||||
|
||||
auto gridAndCellIndex = std::make_pair( gridIndex, gridCellIndex );
|
||||
if ( gridIndex != cvf::UNDEFINED_SIZE_T && gridCellIndex != cvf::UNDEFINED_SIZE_T && !branch.containsGridCell( gridAndCellIndex ) )
|
||||
{
|
||||
OutputSegment outputSegment{ resPoint.outletSegmentId(), resPoint.outletBranchId() };
|
||||
branch.m_gridCellsConnectedToSegments[gridAndCellIndex] = outputSegment;
|
||||
branch.m_segmentsWithGridCells[resPoint.segmentId()].push_back( gridAndCellIndex );
|
||||
}
|
||||
}
|
||||
|
||||
const int resultPointThreshold = 3;
|
||||
if ( resultBranch.m_branchResultPoints.size() > resultPointThreshold )
|
||||
{
|
||||
longWellBranches.push_back( branch );
|
||||
}
|
||||
else
|
||||
{
|
||||
shortWellBranches.push_back( branch );
|
||||
}
|
||||
}
|
||||
|
||||
// Move all grid cells of small branch to the long branch
|
||||
for ( const auto& branch : shortWellBranches )
|
||||
{
|
||||
if ( branch.m_gridCellsConnectedToSegments.empty() ) continue;
|
||||
|
||||
const auto& outputSegment = branch.m_gridCellsConnectedToSegments.begin()->second;
|
||||
for ( auto& longBranch : longWellBranches )
|
||||
{
|
||||
if ( longBranch.m_branchId == outputSegment.outputSegmentBranchId )
|
||||
{
|
||||
for ( const auto& [gridAndCellIndex, localOutputSegment] : branch.m_gridCellsConnectedToSegments )
|
||||
{
|
||||
longBranch.m_segmentsWithGridCells[outputSegment.outputSegmentId].push_back( gridAndCellIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return longWellBranches;
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2023- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RigWellResultPoint.h"
|
||||
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class RigEclipseCaseData;
|
||||
class RimSimWellInView;
|
||||
class RigSimWellData;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RigMswCenterLineCalculator
|
||||
{
|
||||
public:
|
||||
static std::vector<SimulationWellCellBranch> calculateMswWellPipeGeometry( RimSimWellInView* rimWell );
|
||||
|
||||
private:
|
||||
struct OutputSegment
|
||||
{
|
||||
int outputSegmentId = -1;
|
||||
int outputSegmentBranchId = -1;
|
||||
};
|
||||
|
||||
struct WellBranch
|
||||
{
|
||||
int m_branchId = -1;
|
||||
|
||||
std::map<std::pair<size_t, size_t>, OutputSegment> m_gridCellsConnectedToSegments;
|
||||
std::map<int, std::vector<std::pair<size_t, size_t>>> m_segmentsWithGridCells;
|
||||
|
||||
bool containsGridCell( const std::pair<size_t, size_t>& candidateGridAndCellIndex ) const
|
||||
{
|
||||
for ( const auto& [segmentId, gridAndCellIndex] : m_segmentsWithGridCells )
|
||||
{
|
||||
if ( std::find( gridAndCellIndex.begin(), gridAndCellIndex.end(), candidateGridAndCellIndex ) != gridAndCellIndex.end() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
};
|
||||
|
||||
private:
|
||||
static std::vector<SimulationWellCellBranch> calculateMswWellPipeGeometryForTimeStep( const RigEclipseCaseData* eclipseCaseData,
|
||||
const RigSimWellData* simWellData,
|
||||
int timeStepIndex );
|
||||
|
||||
static SimulationWellCellBranch addCoordsAtCellFaceIntersectionsAndCreateBranch( const std::vector<cvf::Vec3d> branchCoords,
|
||||
const std::vector<RigWellResultPoint>& resultPoints,
|
||||
const RigEclipseCaseData* eclipseCaseData );
|
||||
|
||||
static std::vector<WellBranch> mergeShortBranchesIntoLongBranches( const std::vector<RigWellResultBranch>& resBranches );
|
||||
};
|
@ -396,8 +396,8 @@ void RigReservoirBuilderMock::addWellData( RigEclipseCaseData* eclipseCase, RigG
|
||||
wellCells.m_productionType = RiaDefines::WellProductionType::PRODUCER;
|
||||
wellCells.m_isOpen = true;
|
||||
|
||||
wellCells.m_wellHead.m_gridIndex = 0;
|
||||
wellCells.m_wellHead.m_gridCellIndex = grid->cellIndexFromIJK( 1, 0, 0 );
|
||||
wellCells.m_wellHead.setGridIndex( 0 );
|
||||
wellCells.m_wellHead.setGridCellIndex( grid->cellIndexFromIJK( 1, 0, 0 ) );
|
||||
|
||||
// Connections
|
||||
// int connectionCount = std::min(dim.x(), std::min(dim.y(), dim.z())) - 2;
|
||||
@ -414,53 +414,53 @@ void RigReservoirBuilderMock::addWellData( RigEclipseCaseData* eclipseCase, RigG
|
||||
if ( connIdx == ( size_t )( connectionCount / 4 ) ) continue;
|
||||
|
||||
RigWellResultPoint data;
|
||||
data.m_gridIndex = 0;
|
||||
data.setGridIndex( 0 );
|
||||
|
||||
if ( connIdx < dim.y() - 2 )
|
||||
data.m_gridCellIndex = grid->cellIndexFromIJK( 1, 1 + connIdx, 1 + connIdx );
|
||||
data.setGridCellIndex( grid->cellIndexFromIJK( 1, 1 + connIdx, 1 + connIdx ) );
|
||||
else
|
||||
data.m_gridCellIndex = grid->cellIndexFromIJK( 1, dim.y() - 2, 1 + connIdx );
|
||||
data.setGridCellIndex( grid->cellIndexFromIJK( 1, dim.y() - 2, 1 + connIdx ) );
|
||||
|
||||
if ( connIdx < connectionCount / 2 )
|
||||
{
|
||||
data.m_isOpen = true;
|
||||
data.setIsOpen( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
data.m_isOpen = false;
|
||||
data.setIsOpen( false );
|
||||
}
|
||||
|
||||
if ( wellSegment.m_branchResultPoints.size() == 0 ||
|
||||
wellSegment.m_branchResultPoints.back().m_gridCellIndex != data.m_gridCellIndex )
|
||||
wellSegment.m_branchResultPoints.back().cellIndex() != data.cellIndex() )
|
||||
{
|
||||
wellSegment.m_branchResultPoints.push_back( data );
|
||||
|
||||
if ( connIdx == connectionCount / 2 )
|
||||
{
|
||||
RigWellResultPoint deadEndData = data;
|
||||
deadEndData.m_gridCellIndex = data.m_gridCellIndex + 1;
|
||||
deadEndData.m_isOpen = true;
|
||||
deadEndData.setGridCellIndex( data.cellIndex() + 1 );
|
||||
deadEndData.setIsOpen( true );
|
||||
|
||||
RigWellResultPoint deadEndData1 = data;
|
||||
deadEndData1.m_gridCellIndex = data.m_gridCellIndex + 2;
|
||||
deadEndData1.m_isOpen = false;
|
||||
deadEndData1.setGridCellIndex( data.cellIndex() + 2 );
|
||||
deadEndData1.setIsOpen( false );
|
||||
|
||||
wellSegment.m_branchResultPoints.push_back( deadEndData );
|
||||
wellSegment.m_branchResultPoints.push_back( deadEndData1 );
|
||||
|
||||
wellSegment.m_branchResultPoints.push_back( deadEndData );
|
||||
|
||||
data.m_isOpen = true;
|
||||
data.setIsOpen( true );
|
||||
wellSegment.m_branchResultPoints.push_back( data );
|
||||
}
|
||||
}
|
||||
|
||||
if ( connIdx < dim.y() - 2 )
|
||||
{
|
||||
data.m_gridCellIndex = grid->cellIndexFromIJK( 1, 1 + connIdx, 2 + connIdx );
|
||||
data.setGridCellIndex( grid->cellIndexFromIJK( 1, 1 + connIdx, 2 + connIdx ) );
|
||||
|
||||
if ( wellSegment.m_branchResultPoints.size() == 0 ||
|
||||
wellSegment.m_branchResultPoints.back().m_gridCellIndex != data.m_gridCellIndex )
|
||||
wellSegment.m_branchResultPoints.back().cellIndex() != data.cellIndex() )
|
||||
{
|
||||
wellSegment.m_branchResultPoints.push_back( data );
|
||||
}
|
||||
|
@ -138,11 +138,11 @@ bool RigSimWellData::hasAnyValidCells( size_t resultTimeStepIndex ) const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
bool operator==( const RigWellResultPoint& p1, const RigWellResultPoint& p2 )
|
||||
{
|
||||
return p1.m_gridIndex == p2.m_gridIndex && p1.m_gridCellIndex == p2.m_gridCellIndex && p1.m_ertBranchId == p2.m_ertBranchId &&
|
||||
p1.m_ertSegmentId == p2.m_ertSegmentId;
|
||||
// TODO : Remove when <=> operator has been added to RigWellResultPoint
|
||||
return p1.gridIndex() == p2.gridIndex() && p1.cellIndex() == p2.cellIndex() && p1.branchId() == p2.branchId() &&
|
||||
p1.segmentId() == p2.segmentId();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -369,7 +369,7 @@ const RigWellResultPoint* RigWellResultFrame::findResultCellWellHeadIncluded( si
|
||||
// This behavior was different prior to release 2019.04 and was rendered as a closed connection (gray)
|
||||
// https://github.com/OPM/ResInsight/issues/712
|
||||
|
||||
if ( m_wellHead.m_gridCellIndex == gridCellIndex && m_wellHead.m_gridIndex == gridIndex )
|
||||
if ( m_wellHead.cellIndex() == gridCellIndex && m_wellHead.gridIndex() == gridIndex )
|
||||
{
|
||||
return &m_wellHead;
|
||||
}
|
||||
@ -388,8 +388,8 @@ const RigWellResultPoint* RigWellResultFrame::findResultCellWellHeadExcluded( si
|
||||
{
|
||||
for ( size_t wc = 0; wc < m_wellResultBranches[wb].m_branchResultPoints.size(); ++wc )
|
||||
{
|
||||
if ( m_wellResultBranches[wb].m_branchResultPoints[wc].m_gridCellIndex == gridCellIndex &&
|
||||
m_wellResultBranches[wb].m_branchResultPoints[wc].m_gridIndex == gridIndex )
|
||||
if ( m_wellResultBranches[wb].m_branchResultPoints[wc].cellIndex() == gridCellIndex &&
|
||||
m_wellResultBranches[wb].m_branchResultPoints[wc].gridIndex() == gridIndex )
|
||||
{
|
||||
return &( m_wellResultBranches[wb].m_branchResultPoints[wc] );
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include "RigSimulationWellCenterLineCalculator.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RigCell.h"
|
||||
#include "RigCellFaceGeometryTools.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
@ -38,6 +40,79 @@
|
||||
#include <deque>
|
||||
#include <list>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<SimulationWellCellBranch> RigSimulationWellCenterLineCalculator::calculateWellPipeStaticCenterline( RimSimWellInView* rimWell )
|
||||
{
|
||||
std::vector<std::vector<cvf::Vec3d>> pipeBranchesCLCoords;
|
||||
std::vector<std::vector<RigWellResultPoint>> pipeBranchesCellIds;
|
||||
|
||||
calculateWellPipeStaticCenterline( rimWell, pipeBranchesCLCoords, pipeBranchesCellIds );
|
||||
|
||||
std::vector<SimulationWellCellBranch> simuationBranches;
|
||||
for ( size_t i = 0; i < pipeBranchesCLCoords.size(); i++ )
|
||||
{
|
||||
if ( i < pipeBranchesCellIds.size() )
|
||||
{
|
||||
simuationBranches.emplace_back( std::make_pair( pipeBranchesCLCoords[i], pipeBranchesCellIds[i] ) );
|
||||
}
|
||||
}
|
||||
|
||||
return simuationBranches;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<SimulationWellCellBranch>
|
||||
RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineForTimeStep( const RigEclipseCaseData* eclipseCaseData,
|
||||
const RigSimWellData* simWellData,
|
||||
int timeStepIndex,
|
||||
bool isAutoDetectBranches,
|
||||
bool useAllCellCenters )
|
||||
{
|
||||
std::vector<std::vector<cvf::Vec3d>> pipeBranchesCLCoords;
|
||||
std::vector<std::vector<RigWellResultPoint>> pipeBranchesCellIds;
|
||||
|
||||
calculateWellPipeCenterlineForTimeStep( eclipseCaseData,
|
||||
simWellData,
|
||||
timeStepIndex,
|
||||
isAutoDetectBranches,
|
||||
useAllCellCenters,
|
||||
pipeBranchesCLCoords,
|
||||
pipeBranchesCellIds );
|
||||
|
||||
std::vector<SimulationWellCellBranch> simuationBranches;
|
||||
for ( size_t i = 0; i < pipeBranchesCLCoords.size(); i++ )
|
||||
{
|
||||
if ( i < pipeBranchesCellIds.size() )
|
||||
{
|
||||
simuationBranches.emplace_back( std::make_pair( pipeBranchesCLCoords[i], pipeBranchesCellIds[i] ) );
|
||||
}
|
||||
}
|
||||
|
||||
return simuationBranches;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<std::vector<std::vector<cvf::Vec3d>>, std::vector<std::vector<RigWellResultPoint>>>
|
||||
RigSimulationWellCenterLineCalculator::extractBranchData( const std::vector<SimulationWellCellBranch> simulationBranch )
|
||||
{
|
||||
std::vector<std::vector<cvf::Vec3d>> pipeBranchesCLCoords;
|
||||
std::vector<std::vector<RigWellResultPoint>> pipeBranchesCellIds;
|
||||
|
||||
for ( const auto& [coords, wellCells] : simulationBranch )
|
||||
{
|
||||
pipeBranchesCLCoords.emplace_back( coords );
|
||||
pipeBranchesCellIds.emplace_back( wellCells );
|
||||
}
|
||||
|
||||
return { pipeBranchesCLCoords, pipeBranchesCellIds };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Based on the points and cells, calculate a pipe centerline
|
||||
/// The returned CellIds is one less than the number of centerline points,
|
||||
@ -63,13 +138,56 @@ void RigSimulationWellCenterLineCalculator::calculateWellPipeStaticCenterline( R
|
||||
bool useAllCellCenters = rimWell->isUsingCellCenterForPipe();
|
||||
int timeStepIndex = -1;
|
||||
|
||||
calculateWellPipeCenterlineFromWellFrame( eclipseCaseData,
|
||||
simWellData,
|
||||
timeStepIndex,
|
||||
isAutoDetectBranches,
|
||||
useAllCellCenters,
|
||||
pipeBranchesCLCoords,
|
||||
pipeBranchesCellIds );
|
||||
calculateWellPipeCenterlineForTimeStep( eclipseCaseData,
|
||||
simWellData,
|
||||
timeStepIndex,
|
||||
isAutoDetectBranches,
|
||||
useAllCellCenters,
|
||||
pipeBranchesCLCoords,
|
||||
pipeBranchesCellIds );
|
||||
|
||||
// DEBUG output, please keep code
|
||||
bool printDebug = false;
|
||||
if ( printDebug )
|
||||
{
|
||||
QString txt;
|
||||
|
||||
for ( size_t idx = 0; idx < pipeBranchesCellIds.size(); idx++ )
|
||||
{
|
||||
const auto& branchCells = pipeBranchesCellIds[idx];
|
||||
for ( const auto& resultPoint : branchCells )
|
||||
{
|
||||
QString myTxt;
|
||||
int fieldWidth = 3;
|
||||
myTxt += QString( "Ri branch index: %1 " ).arg( idx, fieldWidth );
|
||||
myTxt += QString( "Seg: %1 Branch: %2 " ).arg( resultPoint.segmentId(), fieldWidth ).arg( resultPoint.branchId(), fieldWidth );
|
||||
|
||||
if ( resultPoint.isCell() )
|
||||
{
|
||||
size_t i = 0, j = 0, k = 0;
|
||||
auto grid = eclipseCaseData->grid( resultPoint.gridIndex() );
|
||||
grid->ijkFromCellIndex( resultPoint.cellIndex(), &i, &j, &k );
|
||||
|
||||
myTxt += QString( "Grid %1 %2 %3 " ).arg( i + 1, fieldWidth ).arg( j + 1, fieldWidth ).arg( k + 1, fieldWidth );
|
||||
}
|
||||
|
||||
myTxt += QString( "OutSeg: %1 OutBranch: %2 " )
|
||||
.arg( resultPoint.outletSegmentId(), fieldWidth )
|
||||
.arg( resultPoint.outletBranchId(), fieldWidth );
|
||||
|
||||
int coordFieldWidth = 12;
|
||||
myTxt += QString( "Bottom pos: %1 %2 %3 " )
|
||||
.arg( resultPoint.bottomPosition().x(), coordFieldWidth )
|
||||
.arg( resultPoint.bottomPosition().y(), coordFieldWidth )
|
||||
.arg( resultPoint.bottomPosition().z(), coordFieldWidth );
|
||||
|
||||
myTxt += "\n";
|
||||
txt += myTxt;
|
||||
}
|
||||
}
|
||||
|
||||
RiaLogging::debug( txt );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -77,14 +195,13 @@ void RigSimulationWellCenterLineCalculator::calculateWellPipeStaticCenterline( R
|
||||
/// The returned CellIds is one less than the number of centerline points,
|
||||
/// and are describing the lines between the points, starting with the first line
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineFromWellFrame(
|
||||
const RigEclipseCaseData* eclipseCaseData,
|
||||
const RigSimWellData* wellResults,
|
||||
int timeStepIndex,
|
||||
bool isAutoDetectBranches,
|
||||
bool useAllCellCenters,
|
||||
std::vector<std::vector<cvf::Vec3d>>& pipeBranchesCLCoords,
|
||||
std::vector<std::vector<RigWellResultPoint>>& pipeBranchesCellIds )
|
||||
void RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineForTimeStep( const RigEclipseCaseData* eclipseCaseData,
|
||||
const RigSimWellData* wellResults,
|
||||
int timeStepIndex,
|
||||
bool isAutoDetectBranches,
|
||||
bool useAllCellCenters,
|
||||
std::vector<std::vector<cvf::Vec3d>>& pipeBranchesCLCoords,
|
||||
std::vector<std::vector<RigWellResultPoint>>& pipeBranchesCellIds )
|
||||
{
|
||||
// Initialize the return arrays
|
||||
pipeBranchesCLCoords.clear();
|
||||
@ -200,7 +317,7 @@ void RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineFromWellF
|
||||
// Use the interpolated value of branch head
|
||||
CVF_ASSERT( currentWellResPoint.isPointValid() );
|
||||
|
||||
cvf::Vec3d currentPoint = currentWellResPoint.m_bottomPosition;
|
||||
cvf::Vec3d currentPoint = currentWellResPoint.bottomPosition();
|
||||
|
||||
// If we have a real previous cell, we need to go out of it, before adding the current point
|
||||
// That is: add a CL-point describing where it leaves the previous cell.
|
||||
@ -273,7 +390,7 @@ void RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineFromWellF
|
||||
}
|
||||
else
|
||||
{
|
||||
centerPreviousCell = prevWellResPoint->m_bottomPosition;
|
||||
centerPreviousCell = prevWellResPoint->bottomPosition();
|
||||
}
|
||||
|
||||
distanceToWellHeadIsLonger = ( centerThisCell - centerPreviousCell ).lengthSquared() <=
|
||||
@ -378,7 +495,7 @@ void RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineFromWellF
|
||||
else if ( prevWellResPoint && prevWellResPoint->isPointValid() )
|
||||
{
|
||||
// Continue the line with the same point, just to keep the last Cell ID
|
||||
pipeBranchesCLCoords.back().push_back( prevWellResPoint->m_bottomPosition );
|
||||
pipeBranchesCLCoords.back().push_back( prevWellResPoint->bottomPosition() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -660,7 +777,7 @@ private:
|
||||
const RigCell& whCell = m_eclipseCaseData->cellFromWellResultCell( m_orgWellResultFrame.wellHeadOrStartCell() );
|
||||
cvf::Vec3d whStartPos = whCell.faceCenter( cvf::StructGridInterface::NEG_K );
|
||||
|
||||
wellHeadAsPoint.m_bottomPosition = whStartPos;
|
||||
wellHeadAsPoint.setBottomPosition( whStartPos );
|
||||
m_branchedWell.m_wellResultBranches[branchIdx].m_branchResultPoints.push_back( wellHeadAsPoint );
|
||||
}
|
||||
|
||||
@ -694,7 +811,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
branchStartAsResultPoint.m_bottomPosition = branchStartPos;
|
||||
branchStartAsResultPoint.setBottomPosition( branchStartPos );
|
||||
m_branchedWell.m_wellResultBranches[branchIdx].m_branchResultPoints.push_back( branchStartAsResultPoint );
|
||||
}
|
||||
else
|
||||
|
@ -19,8 +19,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RigWellResultPoint.h"
|
||||
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class RigEclipseCaseData;
|
||||
@ -36,19 +39,38 @@ class RigWellResultFrame;
|
||||
class RigSimulationWellCenterLineCalculator
|
||||
{
|
||||
public:
|
||||
static std::vector<SimulationWellCellBranch> calculateWellPipeStaticCenterline( RimSimWellInView* rimWell );
|
||||
|
||||
static std::vector<SimulationWellCellBranch> calculateWellPipeCenterlineForTimeStep( const RigEclipseCaseData* eclipseCaseData,
|
||||
const RigSimWellData* simWellData,
|
||||
int timeStepIndex,
|
||||
bool isAutoDetectBranches,
|
||||
bool useAllCellCenters );
|
||||
|
||||
static std::pair<std::vector<std::vector<cvf::Vec3d>>, std::vector<std::vector<RigWellResultPoint>>>
|
||||
extractBranchData( const std::vector<SimulationWellCellBranch> simulationBranch );
|
||||
|
||||
private:
|
||||
static void calculateWellPipeStaticCenterline( RimSimWellInView* rimWell,
|
||||
std::vector<std::vector<cvf::Vec3d>>& pipeBranchesCLCoords,
|
||||
std::vector<std::vector<RigWellResultPoint>>& pipeBranchesCellIds );
|
||||
|
||||
static void calculateWellPipeCenterlineFromWellFrame( const RigEclipseCaseData* eclipseCaseData,
|
||||
const RigSimWellData* simWellData,
|
||||
int timeStepIndex,
|
||||
bool isAutoDetectBranches,
|
||||
bool useAllCellCenters,
|
||||
std::vector<std::vector<cvf::Vec3d>>& pipeBranchesCLCoords,
|
||||
std::vector<std::vector<RigWellResultPoint>>& pipeBranchesCellIds );
|
||||
static void calculateWellPipeCenterlineForTimeStep( const RigEclipseCaseData* eclipseCaseData,
|
||||
const RigSimWellData* simWellData,
|
||||
int timeStepIndex,
|
||||
bool isAutoDetectBranches,
|
||||
bool useAllCellCenters,
|
||||
std::vector<std::vector<cvf::Vec3d>>& pipeBranchesCLCoords,
|
||||
std::vector<std::vector<RigWellResultPoint>>& pipeBranchesCellIds );
|
||||
|
||||
static std::vector<SimulationWellCellBranch> calculateMswWellPipeGeometryForTimeStep( const RigEclipseCaseData* eclipseCaseData,
|
||||
const RigSimWellData* simWellData,
|
||||
int timeStepIndex );
|
||||
|
||||
static SimulationWellCellBranch addSegmentsToCellFaces( const std::vector<cvf::Vec3d> branchCoords,
|
||||
const std::vector<RigWellResultPoint>& resultPoints,
|
||||
const RigEclipseCaseData* eclipseCaseData );
|
||||
|
||||
private:
|
||||
static bool hasAnyValidDataCells( const RigWellResultBranch& branch );
|
||||
static void finishPipeCenterLine( std::vector<std::vector<cvf::Vec3d>>& pipeBranchesCLCoords, const cvf::Vec3d& lastCellCenter );
|
||||
|
||||
|
@ -23,10 +23,12 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWellResultPoint::RigWellResultPoint()
|
||||
: m_gridIndex( cvf::UNDEFINED_SIZE_T )
|
||||
, m_gridCellIndex( cvf::UNDEFINED_SIZE_T )
|
||||
, m_cellIndex( cvf::UNDEFINED_SIZE_T )
|
||||
, m_isOpen( false )
|
||||
, m_ertBranchId( -1 )
|
||||
, m_ertSegmentId( -1 )
|
||||
, m_ertOutletBranchId( -1 )
|
||||
, m_ertOutletSegmentId( -1 )
|
||||
, m_bottomPosition( cvf::Vec3d::UNDEFINED )
|
||||
, m_flowRate( 0.0 )
|
||||
, m_oilRate( 0.0 )
|
||||
@ -36,6 +38,75 @@ RigWellResultPoint::RigWellResultPoint()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWellResultPoint::setGridIndex( size_t gridIndex )
|
||||
{
|
||||
m_gridIndex = gridIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWellResultPoint::setGridCellIndex( size_t cellIndex )
|
||||
{
|
||||
m_cellIndex = cellIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWellResultPoint::setIsOpen( bool isOpen )
|
||||
{
|
||||
m_isOpen = isOpen;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWellResultPoint::setFlowData( double flowRate, double oilRate, double gasRate, double waterRate )
|
||||
{
|
||||
m_flowRate = flowRate;
|
||||
m_oilRate = oilRate;
|
||||
m_gasRate = gasRate;
|
||||
m_waterRate = waterRate;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWellResultPoint::setConnectionFactor( double connectionFactor )
|
||||
{
|
||||
m_connectionFactor = connectionFactor;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWellResultPoint::setSegmentData( int branchId, int segmentId )
|
||||
{
|
||||
m_ertBranchId = branchId;
|
||||
m_ertSegmentId = segmentId;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWellResultPoint::setOutletSegmentData( int outletBranchId, int outletSegmentId )
|
||||
{
|
||||
m_ertOutletBranchId = outletBranchId;
|
||||
m_ertOutletSegmentId = outletSegmentId;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWellResultPoint::setBottomPosition( const cvf::Vec3d& bottomPosition )
|
||||
{
|
||||
m_bottomPosition = bottomPosition;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -49,7 +120,7 @@ bool RigWellResultPoint::isPointValid() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigWellResultPoint::isCell() const
|
||||
{
|
||||
return m_gridCellIndex != cvf::UNDEFINED_SIZE_T;
|
||||
return m_cellIndex != cvf::UNDEFINED_SIZE_T;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -60,12 +131,20 @@ bool RigWellResultPoint::isValid() const
|
||||
return isCell() || isPointValid();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigWellResultPoint::isOpen() const
|
||||
{
|
||||
return m_isOpen;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigWellResultPoint::isEqual( const RigWellResultPoint& other ) const
|
||||
{
|
||||
return ( m_gridIndex == other.m_gridIndex && m_gridCellIndex == other.m_gridCellIndex && m_isOpen == other.m_isOpen &&
|
||||
return ( m_gridIndex == other.m_gridIndex && m_cellIndex == other.m_cellIndex && m_isOpen == other.m_isOpen &&
|
||||
m_ertBranchId == other.m_ertBranchId && m_ertSegmentId == other.m_ertSegmentId && m_flowRate == other.m_flowRate &&
|
||||
m_oilRate == other.m_oilRate && m_gasRate == other.m_gasRate && m_waterRate == other.m_waterRate );
|
||||
}
|
||||
@ -149,3 +228,59 @@ void RigWellResultPoint::clearAllFlow()
|
||||
m_gasRate = 0.0;
|
||||
m_waterRate = 0.0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigWellResultPoint::gridIndex() const
|
||||
{
|
||||
return m_gridIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigWellResultPoint::cellIndex() const
|
||||
{
|
||||
return m_cellIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RigWellResultPoint::branchId() const
|
||||
{
|
||||
return m_ertBranchId;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RigWellResultPoint::segmentId() const
|
||||
{
|
||||
return m_ertSegmentId;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RigWellResultPoint::outletBranchId() const
|
||||
{
|
||||
return m_ertOutletBranchId;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RigWellResultPoint::outletSegmentId() const
|
||||
{
|
||||
return m_ertOutletSegmentId;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RigWellResultPoint::bottomPosition() const
|
||||
{
|
||||
return m_bottomPosition;
|
||||
}
|
||||
|
@ -34,9 +34,21 @@ struct RigWellResultPoint
|
||||
{
|
||||
RigWellResultPoint();
|
||||
|
||||
void setGridIndex( size_t gridIndex );
|
||||
void setGridCellIndex( size_t cellIndex );
|
||||
void setIsOpen( bool isOpen );
|
||||
void setFlowData( double flowRate, double oilRate, double gasRate, double waterRate );
|
||||
void setConnectionFactor( double connectionFactor );
|
||||
|
||||
void setSegmentData( int branchId, int segmentId );
|
||||
void setOutletSegmentData( int outletBranchId, int outletSegmentId );
|
||||
|
||||
void setBottomPosition( const cvf::Vec3d& bottomPosition );
|
||||
|
||||
bool isPointValid() const;
|
||||
bool isCell() const;
|
||||
bool isValid() const;
|
||||
bool isOpen() const;
|
||||
bool isEqual( const RigWellResultPoint& other ) const;
|
||||
|
||||
double flowRate() const;
|
||||
@ -46,12 +58,25 @@ struct RigWellResultPoint
|
||||
double connectionFactor() const;
|
||||
void clearAllFlow();
|
||||
|
||||
size_t gridIndex() const;
|
||||
size_t cellIndex() const;
|
||||
|
||||
int branchId() const;
|
||||
int segmentId() const;
|
||||
int outletBranchId() const;
|
||||
int outletSegmentId() const;
|
||||
|
||||
cvf::Vec3d bottomPosition() const;
|
||||
|
||||
private:
|
||||
size_t m_gridIndex;
|
||||
size_t m_gridCellIndex; //< Index to cell which is included in the well
|
||||
size_t m_cellIndex; //< Index to cell which is included in the well
|
||||
bool m_isOpen; //< Marks the well as open or closed as of Eclipse simulation
|
||||
|
||||
int m_ertBranchId;
|
||||
int m_ertSegmentId;
|
||||
int m_ertOutletBranchId;
|
||||
int m_ertOutletSegmentId;
|
||||
|
||||
cvf::Vec3d m_bottomPosition; //< The estimated bottom position of the well segment, when we have no grid cell
|
||||
// connections for the segment.
|
||||
@ -103,3 +128,5 @@ public:
|
||||
|
||||
std::vector<RigWellResultBranch> m_wellResultBranches;
|
||||
};
|
||||
|
||||
using SimulationWellCellBranch = std::pair<std::vector<cvf::Vec3d>, std::vector<RigWellResultPoint>>;
|
||||
|
@ -295,11 +295,11 @@ public:
|
||||
size_t i;
|
||||
size_t j;
|
||||
size_t k;
|
||||
size_t gridIdx = resPoint.m_gridIndex;
|
||||
grids[gridIdx]->ijkFromCellIndex( resPoint.m_gridCellIndex, &i, &j, &k );
|
||||
bool isOpen = resPoint.m_isOpen;
|
||||
int branchId = resPoint.m_ertBranchId;
|
||||
int segmentId = resPoint.m_ertSegmentId;
|
||||
size_t gridIdx = resPoint.gridIndex();
|
||||
grids[gridIdx]->ijkFromCellIndex( resPoint.cellIndex(), &i, &j, &k );
|
||||
bool isOpen = resPoint.isOpen();
|
||||
int branchId = resPoint.branchId();
|
||||
int segmentId = resPoint.segmentId();
|
||||
|
||||
cellIs.push_back( static_cast<qint32>( i + 1 ) ); // NB: 1-based index in Octave
|
||||
cellJs.push_back( static_cast<qint32>( j + 1 ) ); // NB: 1-based index in Octave
|
||||
|
@ -1155,24 +1155,34 @@ QString RiuResultTextBuilder::wellResultText()
|
||||
if ( m_eclResDef->eclipseCase() && m_eclResDef->eclipseCase()->eclipseCaseData() )
|
||||
{
|
||||
cvf::Collection<RigSimWellData> simWellData = m_eclResDef->eclipseCase()->eclipseCaseData()->wellResults();
|
||||
for ( size_t i = 0; i < simWellData.size(); i++ )
|
||||
for ( const auto& singleWellResultData : simWellData )
|
||||
{
|
||||
RigSimWellData* singleWellResultData = simWellData.at( i );
|
||||
|
||||
if ( !singleWellResultData->hasWellResult( m_timeStepIndex ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const RigWellResultFrame* wellResultFrame = singleWellResultData->wellResultFrame( m_timeStepIndex );
|
||||
const RigWellResultPoint* wellResultCell = wellResultFrame->findResultCellWellHeadIncluded( m_gridIndex, m_cellIndex );
|
||||
if ( !wellResultFrame )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const RigWellResultPoint* wellResultCell = wellResultFrame->findResultCellWellHeadIncluded( m_gridIndex, m_cellIndex );
|
||||
if ( wellResultCell )
|
||||
{
|
||||
const int branchId = wellResultCell->branchId();
|
||||
const int segmentId = wellResultCell->segmentId();
|
||||
const int outletBranchId = wellResultCell->outletBranchId();
|
||||
const int outletSegmentId = wellResultCell->outletSegmentId();
|
||||
|
||||
text += QString( "-- Well-cell connection info --\n Well Name: %1\n Branch Id: %2\n Segment "
|
||||
"Id: %3\n" )
|
||||
"Id: %3\n Outlet Branch Id: %4\n Outlet Segment Id: %5" )
|
||||
.arg( singleWellResultData->m_wellName )
|
||||
.arg( wellResultCell->m_ertBranchId )
|
||||
.arg( wellResultCell->m_ertSegmentId );
|
||||
.arg( branchId )
|
||||
.arg( segmentId )
|
||||
.arg( outletBranchId )
|
||||
.arg( outletSegmentId );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,8 +125,8 @@ grpc::Status RiaGrpcSimulationWellService::GetSimulationWellCells( grpc::ServerC
|
||||
size_t i;
|
||||
size_t j;
|
||||
size_t k;
|
||||
size_t gridIdx = resPoint.m_gridIndex;
|
||||
grids[gridIdx]->ijkFromCellIndex( resPoint.m_gridCellIndex, &i, &j, &k );
|
||||
const size_t gridIdx = resPoint.gridIndex();
|
||||
grids[gridIdx]->ijkFromCellIndex( resPoint.cellIndex(), &i, &j, &k );
|
||||
|
||||
Vec3i* ijk = new Vec3i;
|
||||
ijk->set_i( i );
|
||||
@ -135,9 +135,9 @@ grpc::Status RiaGrpcSimulationWellService::GetSimulationWellCells( grpc::ServerC
|
||||
|
||||
cellInfo->set_allocated_ijk( ijk );
|
||||
cellInfo->set_grid_index( gridIdx );
|
||||
cellInfo->set_is_open( resPoint.m_isOpen );
|
||||
cellInfo->set_branch_id( resPoint.m_ertBranchId );
|
||||
cellInfo->set_segment_id( resPoint.m_ertSegmentId );
|
||||
cellInfo->set_is_open( resPoint.isOpen() );
|
||||
cellInfo->set_branch_id( resPoint.branchId() );
|
||||
cellInfo->set_segment_id( resPoint.segmentId() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user