#2195 Final fix of missing connections in high level grids, if connections in lower levels exist.

This commit is contained in:
Jacob Støren
2017-12-04 16:37:53 +01:00
parent fcd9d0f3e6
commit 1ec6d77ff9
2 changed files with 100 additions and 35 deletions
@@ -1076,10 +1076,7 @@ struct SegmentPositionContribution
bool m_isFromAbove; bool m_isFromAbove;
}; };
//-------------------------------------------------------------------------------------------------- size_t localGridCellIndexFromErtConnection(const RigGridBase* grid, const well_conn_type* ert_connection, const char* wellNameForErrorMsgs )
///
//--------------------------------------------------------------------------------------------------
RigWellResultPoint RifReaderEclipseOutput::createWellResultPoint(const RigGridBase* grid, const well_conn_type* ert_connection, int ertBranchId, int ertSegmentId, const char* wellName)
{ {
CVF_ASSERT(ert_connection); CVF_ASSERT(ert_connection);
CVF_ASSERT(grid); CVF_ASSERT(grid);
@@ -1087,11 +1084,6 @@ RigWellResultPoint RifReaderEclipseOutput::createWellResultPoint(const RigGridBa
int cellI = well_conn_get_i( ert_connection ); int cellI = well_conn_get_i( ert_connection );
int cellJ = well_conn_get_j( ert_connection ); int cellJ = well_conn_get_j( ert_connection );
int cellK = well_conn_get_k( ert_connection ); int cellK = well_conn_get_k( ert_connection );
bool isCellOpen = well_conn_open( ert_connection );
double volumeRate = well_conn_get_volume_rate( ert_connection);
double oilRate = well_conn_get_oil_rate(ert_connection) ;
double gasRate = well_conn_get_gas_rate(ert_connection);
double waterRate = well_conn_get_water_rate(ert_connection);
// If a well is defined in fracture region, the K-value is from (cellCountK - 1) -> cellCountK*2 - 1 // If a well is defined in fracture region, the K-value is from (cellCountK - 1) -> cellCountK*2 - 1
// Adjust K so index is always in valid grid region // Adjust K so index is always in valid grid region
@@ -1102,18 +1094,18 @@ RigWellResultPoint RifReaderEclipseOutput::createWellResultPoint(const RigGridBa
// See description for keyword ICON at page 54/55 of Rile Formats Reference Manual 2010.2 // See description for keyword ICON at page 54/55 of Rile Formats Reference Manual 2010.2
/* /*
Integer completion data array Integer completion data array
ICON(NICONZ,NCWMAX,NWELLS) with dimensions ICON(NICONZ,NCWMAX,NWELLS) with dimensions
defined by INTEHEAD. The following items are required for each completion in each well: defined by INTEHEAD. The following items are required for each completion in each well:
Item 1 - Well connection index ICON(1,IC,IWELL) = IC (set to -IC if connection is not in current LGR) Item 1 - Well connection index ICON(1,IC,IWELL) = IC (set to -IC if connection is not in current LGR)
Item 2 - I-coordinate (<= 0 if not in this LGR) Item 2 - I-coordinate (<= 0 if not in this LGR)
Item 3 - J-coordinate (<= 0 if not in this LGR) Item 3 - J-coordinate (<= 0 if not in this LGR)
Item 4 - K-coordinate (<= 0 if not in this LGR) Item 4 - K-coordinate (<= 0 if not in this LGR)
Item 6 - Connection status > 0 open, <= 0 shut Item 6 - Connection status > 0 open, <= 0 shut
Item 14 - Penetration direction (1=x, 2=y, 3=z, 4=fractured in x-direction, 5=fractured in y-direction) Item 14 - Penetration direction (1=x, 2=y, 3=z, 4=fractured in x-direction, 5=fractured in y-direction)
If undefined or zero, assume Z If undefined or zero, assume Z
Item 15 - Segment number containing connection (for multi-segment wells, =0 for ordinary wells) Item 15 - Segment number containing connection (for multi-segment wells, =0 for ordinary wells)
Undefined items in this array may be set to zero. Undefined items in this array may be set to zero.
*/ */
// The K value might also be -1. It is not yet known why, or what it is supposed to mean, // The K value might also be -1. It is not yet known why, or what it is supposed to mean,
@@ -1125,19 +1117,45 @@ RigWellResultPoint RifReaderEclipseOutput::createWellResultPoint(const RigGridBa
cellK = 0; cellK = 0;
} }
RigWellResultPoint resultPoint;
// Introduced based on discussion with Håkon Høgstøl 08.09.2016 // Introduced based on discussion with Håkon Høgstøl 08.09.2016
if (cellK >= static_cast<int>(grid->cellCountK())) if (cellK >= static_cast<int>(grid->cellCountK()))
{ {
int maxCellK = static_cast<int>(grid->cellCountK()); int maxCellK = static_cast<int>(grid->cellCountK());
cvf::Trace::show("Well Connection for grid " + cvf::String(grid->gridName()) + "\n - Ignored connection with invalid K value (K=" + cvf::String(cellK) + ", max K = " + cvf::String(maxCellK) + ") for well : " + cvf::String(wellName)); if (wellNameForErrorMsgs)
{
cvf::Trace::show("Well Connection for grid " + cvf::String(grid->gridName()) + "\n - Ignored connection with invalid K value (K=" + cvf::String(cellK) + ", max K = " + cvf::String(maxCellK) + ") for well : " + cvf::String(wellNameForErrorMsgs));
}
return cvf::UNDEFINED_SIZE_T;
} }
else
return grid->cellIndexFromIJK(cellI, cellJ, cellK);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigWellResultPoint RifReaderEclipseOutput::createWellResultPoint(const RigGridBase* grid, const well_conn_type* ert_connection, int ertBranchId, int ertSegmentId, const char* wellName)
{
CVF_ASSERT(ert_connection);
CVF_ASSERT(grid);
size_t gridCellIndex = localGridCellIndexFromErtConnection(grid, ert_connection, wellName);
bool isCellOpen = well_conn_open( ert_connection );
double volumeRate = well_conn_get_volume_rate( ert_connection);
double oilRate = well_conn_get_oil_rate(ert_connection) ;
double gasRate = well_conn_get_gas_rate(ert_connection);
double waterRate = well_conn_get_water_rate(ert_connection);
RigWellResultPoint resultPoint;
if (gridCellIndex != cvf::UNDEFINED_SIZE_T)
{ {
resultPoint.m_gridIndex = grid->gridIndex(); resultPoint.m_gridIndex = grid->gridIndex();
resultPoint.m_gridCellIndex = grid->cellIndexFromIJK(cellI, cellJ, cellK); resultPoint.m_gridCellIndex = gridCellIndex;
resultPoint.m_isOpen = isCellOpen; resultPoint.m_isOpen = isCellOpen;
@@ -1300,7 +1318,38 @@ void propagatePosContribDownwards(std::map<int, std::vector<SegmentPositionContr
class WellResultPointHasSubCellConnectionCalculator class WellResultPointHasSubCellConnectionCalculator
{ {
public: public:
explicit WellResultPointHasSubCellConnectionCalculator(const RigMainGrid* mainGrid): m_mainGrid(mainGrid) {} explicit WellResultPointHasSubCellConnectionCalculator(const RigMainGrid* mainGrid, well_state_type* ert_well_state): m_mainGrid(mainGrid)
{
int lastGridNr = static_cast<int>(m_mainGrid->gridCount()) - 1;
for ( int gridNr = lastGridNr; gridNr >= 0; --gridNr )
{
const well_conn_type* ert_wellhead = well_state_iget_wellhead(ert_well_state, static_cast<int>(gridNr));
if ( ert_wellhead )
{
size_t localGridCellidx = localGridCellIndexFromErtConnection( m_mainGrid->gridByIndex(gridNr), ert_wellhead, nullptr);
this->insertTheParentCells(gridNr, localGridCellidx);
}
std::string gridname = gridNr == 0 ? ECL_GRID_GLOBAL_GRID: m_mainGrid->gridByIndex(gridNr)->gridName();
const well_conn_collection_type* connections = well_state_get_grid_connections(ert_well_state, gridname.data());
if ( connections )
{
int connectionCount = well_conn_collection_get_size(connections);
if ( connectionCount )
{
for ( int connIdx = 0; connIdx < connectionCount; connIdx++ )
{
well_conn_type* ert_connection = well_conn_collection_iget(connections, connIdx);
size_t localGridCellidx = localGridCellIndexFromErtConnection( m_mainGrid->gridByIndex(gridNr), ert_connection, nullptr);
this->insertTheParentCells(gridNr, localGridCellidx);
}
}
}
}
}
bool hasSubCellConnection(const RigWellResultPoint& wellResultPoint) bool hasSubCellConnection(const RigWellResultPoint& wellResultPoint)
{ {
@@ -1311,7 +1360,23 @@ public:
size_t reservoirCellIdx = m_mainGrid->reservoirCellIndexByGridAndGridLocalCellIndex(gridIndex, gridCellIndex); size_t reservoirCellIdx = m_mainGrid->reservoirCellIndexByGridAndGridLocalCellIndex(gridIndex, gridCellIndex);
if ( m_gridCellsWithSubCellWellConnections.count(reservoirCellIdx) ) return true; if ( m_gridCellsWithSubCellWellConnections.count(reservoirCellIdx) )
{
return true;
}
else
{
return false;
}
}
private:
void insertTheParentCells( size_t gridIndex, size_t gridCellIndex )
{
if (gridCellIndex == cvf::UNDEFINED_SIZE_T) return;
size_t reservoirCellIdx = m_mainGrid->reservoirCellIndexByGridAndGridLocalCellIndex(gridIndex, gridCellIndex);
// Traverse parent gridcells, and add them to the map // Traverse parent gridcells, and add them to the map
@@ -1327,11 +1392,8 @@ public:
size_t parentReservoirCellIdx = m_mainGrid->reservoirCellIndexByGridAndGridLocalCellIndex(gridIndex, gridCellIndex); size_t parentReservoirCellIdx = m_mainGrid->reservoirCellIndexByGridAndGridLocalCellIndex(gridIndex, gridCellIndex);
m_gridCellsWithSubCellWellConnections.insert(parentReservoirCellIdx); m_gridCellsWithSubCellWellConnections.insert(parentReservoirCellIdx);
} }
return false;
} }
private:
std::set<size_t> m_gridCellsWithSubCellWellConnections; std::set<size_t> m_gridCellsWithSubCellWellConnections;
const RigMainGrid* m_mainGrid; const RigMainGrid* m_mainGrid;
}; };
@@ -1858,9 +1920,9 @@ void RifReaderEclipseOutput::readWellCells(const ecl_grid_type* mainEclGrid, boo
{ {
// Code handling None-MSW Wells ... Normal wells that is. // Code handling None-MSW Wells ... Normal wells that is.
WellResultPointHasSubCellConnectionCalculator subCellConnCalc(m_eclipseCase->mainGrid()); WellResultPointHasSubCellConnectionCalculator subCellConnCalc(m_eclipseCase->mainGrid(), ert_well_state);
int lastGridNr = static_cast<int>(grids.size()) - 1; int lastGridNr = static_cast<int>(grids.size()) - 1;
for ( int gridNr = lastGridNr; gridNr >= 0; --gridNr ) for ( int gridNr = 0; gridNr <= lastGridNr; ++gridNr )
{ {
const well_conn_type* ert_wellhead = well_state_iget_wellhead(ert_well_state, static_cast<int>(gridNr)); const well_conn_type* ert_wellhead = well_state_iget_wellhead(ert_well_state, static_cast<int>(gridNr));
if ( ert_wellhead ) if ( ert_wellhead )
@@ -381,9 +381,12 @@ RigWellResultPoint RigWellResultFrame::wellHeadOrStartCell() const
{ {
if (m_wellHead.isCell()) return m_wellHead; if (m_wellHead.isCell()) return m_wellHead;
if (m_wellResultBranches.size() && m_wellResultBranches.front().m_branchResultPoints.size() ) for ( const RigWellResultBranch& resBranch : m_wellResultBranches )
{ {
return m_wellResultBranches.front().m_branchResultPoints.front(); for ( const RigWellResultPoint& wrp: resBranch.m_branchResultPoints )
{
if ( wrp.isCell() ) return wrp;
}
} }
return m_wellHead; // Nothing else to do return m_wellHead; // Nothing else to do