Multi Segment Wells: Read in connection between a well branch and the branch head.

Compute intersection point between branch top well cell and branch head in the main branch.
p4#: 21954
This commit is contained in:
Magne Sjaastad 2013-06-18 09:41:02 +02:00
parent fa410ba8a5
commit 16cd7a04ae
4 changed files with 317 additions and 138 deletions

View File

@ -783,20 +783,23 @@ void RifReaderEclipseOutput::readWellCells(const ecl_grid_type* mainEclGrid)
// Loop over all the grids in the model. If we have connections in one, we will discard
// the maingrid connections as they are "duplicates"
// the main grid connections as the well connections are duplicated in the main grid and LGR grids
bool hasWellConnectionsInLGR = false;
// for (size_t gridNr = 1; gridNr < grids.size(); ++gridNr)
// {
// RigGridBase* lgrGrid = m_eclipseCase->grid(gridNr);
// if (well_state_has_grid_connections(ert_well_state, lgrGrid->gridName().data()))
// {
// hasWellConnectionsInLGR = true;
// break;
// }
// }
#if 0
// To be discussed with Statoil
for (size_t gridNr = 1; gridNr < grids.size(); ++gridNr)
{
RigGridBase* lgrGrid = m_eclipseCase->grid(gridNr);
if (well_state_has_grid_connections(ert_well_state, lgrGrid->gridName().data()))
{
hasWellConnectionsInLGR = true;
break;
}
}
#endif
size_t gridNr = hasWellConnectionsInLGR ? 1 : 0;
for (; gridNr < grids.size(); ++gridNr)
@ -821,6 +824,7 @@ void RifReaderEclipseOutput::readWellCells(const ecl_grid_type* mainEclGrid)
wellResFrame.m_wellHead.m_gridIndex = gridNr;
}
std::string gridName;
if (gridNr == 0)
{
@ -840,108 +844,128 @@ void RifReaderEclipseOutput::readWellCells(const ecl_grid_type* mainEclGrid)
for (int branchIdx = 0; branchIdx < well_branch_collection_get_size(branches); branchIdx++)
{
RigWellResultBranch& wellSegment = wellResFrame.m_wellResultBranches[branchIdx];
wellSegment.m_branchNumber = branchIdx;
RigWellResultBranch& rigWellResultBranch = wellResFrame.m_wellResultBranches[branchIdx];
rigWellResultBranch.m_branchIndex = branchIdx;
wellResults->setMultiSegmentWell(true);
const well_segment_type* segment = well_branch_collection_iget_start_segment(branches, branchIdx);
CVF_ASSERT(segment);
const well_segment_type* branchBottomSegment = well_branch_collection_iget_start_segment(branches, branchIdx);
CVF_ASSERT(branchBottomSegment);
std::vector<const well_segment_type*> ertBranchSegments; // Segment closest to well head first in this vector
int wellSegmentBranchId = well_segment_get_branch_id(segment);
int nextWellSegmentBranchId = wellSegmentBranchId;
while (segment && nextWellSegmentBranchId == wellSegmentBranchId)
rigWellResultBranch.m_ertBranchId = well_segment_get_branch_id(branchBottomSegment);
// Find outlet segment in next branch
// Start from bottom, and iterate over segments until next branch is detected
int outletErtBranchId = rigWellResultBranch.m_ertBranchId;
const well_segment_type* outletSegmentInNextBranch = branchBottomSegment;
while (outletSegmentInNextBranch && outletErtBranchId == rigWellResultBranch.m_ertBranchId)
{
// Insert at front, as we want the segments to be ordered starting closest to the well head
ertBranchSegments.insert(ertBranchSegments.begin(), segment);
ertBranchSegments.insert(ertBranchSegments.begin(), outletSegmentInNextBranch);
segment = well_segment_get_outlet(segment);
if (segment)
outletSegmentInNextBranch = well_segment_get_outlet(outletSegmentInNextBranch);
if (outletSegmentInNextBranch)
{
nextWellSegmentBranchId = well_segment_get_branch_id(segment);
outletErtBranchId = well_segment_get_branch_id(outletSegmentInNextBranch);
}
}
// Get grid cell index to connect the branch to
bool foundGridCellConnection = false;
if (segment)
if (outletSegmentInNextBranch)
{
const well_conn_collection_type* connections = well_segment_get_connections(segment, gridName.data());
if (connections)
{
size_t existingConnCount = wellSegment.m_wellCells.size();
int connectionCount = well_conn_collection_get_size(connections);
if (connectionCount > 0)
{
// Get last connection from the outlet segment
well_conn_type* ert_connection = well_conn_collection_iget(connections, connectionCount - 1);
int cellI = well_conn_get_i( ert_connection );
int cellJ = well_conn_get_j( ert_connection );
int cellK = well_conn_get_k( ert_connection );
rigWellResultBranch.m_connectionDepthOnOutletBranch = well_segment_get_depth(outletSegmentInNextBranch);
// 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
if (cellK >= static_cast<int>(grids[gridNr]->cellCountK()))
{
cellK -= static_cast<int>(grids[gridNr]->cellCountK());
}
wellSegment.m_branchHead.m_gridIndex = gridNr;
wellSegment.m_branchHead.m_gridCellIndex = grids[gridNr]->cellIndexFromIJK(cellI , cellJ , cellK);
foundGridCellConnection = true;
}
}
else
{
// No connections present in segment this branch is connected to
// Store intersection data used for visualization in RivWellPipesPartMgr
wellSegment.m_intersectionSegmentOutletBranchIndex = nextWellSegmentBranchId;
wellSegment.m_intersectionSegmentOutletDepth = well_segment_get_depth(segment);
}
// No connections present in segment this branch is connected to
// Store intersection data used for visualization in RivWellPipesPartMgr
rigWellResultBranch.m_outletErtBranchId = outletErtBranchId;
}
// Get first segment with connections in order to find grid cell index to connect the branch to
while(outletSegmentInNextBranch && !well_segment_has_grid_connections(outletSegmentInNextBranch, gridName.data()))
{
outletSegmentInNextBranch = well_segment_get_outlet(outletSegmentInNextBranch);
// There are no connections in the directly connected outlet segment.
rigWellResultBranch.m_useBranchHeadAsCenterLineIntersectionTop = true;
}
if (outletSegmentInNextBranch)
{
const well_conn_collection_type* connections = well_segment_get_connections(outletSegmentInNextBranch, gridName.data());
CVF_ASSERT(connections);
size_t existingConnCount = rigWellResultBranch.m_wellCells.size();
int connectionCount = well_conn_collection_get_size(connections);
CVF_ASSERT(connectionCount > 0);
// Get last connection from the outlet segment
well_conn_type* ert_connection = well_conn_collection_iget(connections, connectionCount - 1);
int cellI = well_conn_get_i( ert_connection );
int cellJ = well_conn_get_j( ert_connection );
int cellK = well_conn_get_k( ert_connection );
// 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
if (cellK >= static_cast<int>(grids[gridNr]->cellCountK()))
{
cellK -= static_cast<int>(grids[gridNr]->cellCountK());
}
rigWellResultBranch.m_branchHead.m_gridIndex = gridNr;
rigWellResultBranch.m_branchHead.m_gridCellIndex = grids[gridNr]->cellIndexFromIJK(cellI , cellJ , cellK);
rigWellResultBranch.m_branchHead.m_isOpen = well_conn_open(ert_connection);
CVF_ASSERT(rigWellResultBranch.m_branchHead.m_gridCellIndex != cvf::UNDEFINED_SIZE_T);
}
else
{
// Use well head as branch head
rigWellResultBranch.m_branchHead = wellResFrame.m_wellHead;
CVF_ASSERT(rigWellResultBranch.m_branchHead.m_gridCellIndex != cvf::UNDEFINED_SIZE_T);
// TODO: Possibly add branch ID for the main branch the well head is a part of
}
CVF_ASSERT(rigWellResultBranch.m_branchHead.m_gridCellIndex != cvf::UNDEFINED_SIZE_T);
for (size_t i = 0; i < ertBranchSegments.size(); i++)
{
segment = ertBranchSegments[i];
outletSegmentInNextBranch = ertBranchSegments[i];
const well_conn_collection_type* connections = well_segment_get_connections(segment , gridName.data());
const well_conn_collection_type* connections = well_segment_get_connections(outletSegmentInNextBranch , gridName.data());
if (!connections) continue;
size_t existingConnCount = wellSegment.m_wellCells.size();
size_t existingConnCount = rigWellResultBranch.m_wellCells.size();
int connectionCount = well_conn_collection_get_size(connections);
if (connectionCount > 0)
{
wellSegment.m_wellCells.resize(existingConnCount + connectionCount);
rigWellResultBranch.m_wellCells.resize(existingConnCount + connectionCount);
}
for (int connIdx = 0; connIdx < connectionCount; connIdx++)
{
well_conn_type* ert_connection = well_conn_collection_iget(connections, connIdx);
RigWellResultCell& data = wellSegment.m_wellCells[existingConnCount + connIdx];
data.m_gridIndex = gridNr;
RigWellResultCell& data = rigWellResultBranch.m_wellCells[existingConnCount + connIdx];
int cellI = well_conn_get_i( ert_connection );
int cellJ = well_conn_get_j( ert_connection );
int cellK = well_conn_get_k( ert_connection );
bool open = well_conn_open( ert_connection );
int segmentId = well_conn_get_segment( ert_connection );
// 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
if (cellK >= static_cast<int>(grids[gridNr]->cellCountK()))
{
int cellI = well_conn_get_i( ert_connection );
int cellJ = well_conn_get_j( ert_connection );
int cellK = well_conn_get_k( ert_connection );
bool open = well_conn_open( ert_connection );
int branch = well_segment_get_branch_id(segment);
int segment = well_conn_get_segment( ert_connection );
// 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
if (cellK >= static_cast<int>(grids[gridNr]->cellCountK()))
{
cellK -= static_cast<int>(grids[gridNr]->cellCountK());
}
data.m_gridCellIndex = grids[gridNr]->cellIndexFromIJK(cellI , cellJ , cellK);
data.m_isOpen = open;
data.m_branchId = branch;
data.m_segmentId = segment;
cellK -= static_cast<int>(grids[gridNr]->cellCountK());
}
data.m_gridIndex = gridNr;
data.m_gridCellIndex = grids[gridNr]->cellIndexFromIJK(cellI , cellJ , cellK);
data.m_isOpen = open;
}
}
}
@ -955,7 +979,7 @@ void RifReaderEclipseOutput::readWellCells(const ecl_grid_type* mainEclGrid)
wellResFrame.m_wellResultBranches.resize(branchIdx + 1);
RigWellResultBranch& wellSegment = wellResFrame.m_wellResultBranches[branchIdx];
wellSegment.m_branchNumber = branchIdx;
wellSegment.m_branchIndex = branchIdx;
int connectionCount = well_conn_collection_get_size(connections);
size_t existingConnCount = wellSegment.m_wellCells.size();
@ -966,30 +990,25 @@ void RifReaderEclipseOutput::readWellCells(const ecl_grid_type* mainEclGrid)
well_conn_type* ert_connection = well_conn_collection_iget(connections, connIdx);
RigWellResultCell& data = wellSegment.m_wellCells[existingConnCount + connIdx];
data.m_gridIndex = gridNr;
int cellI = well_conn_get_i( ert_connection );
int cellJ = well_conn_get_j( ert_connection );
int cellK = well_conn_get_k( ert_connection );
bool isCellOpen = well_conn_open( ert_connection );
// TODO: Are these available for this type of well?
int segmentId = well_conn_get_segment( ert_connection );
// 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
if (cellK >= static_cast<int>(grids[gridNr]->cellCountK()))
{
int cellI = well_conn_get_i( ert_connection );
int cellJ = well_conn_get_j( ert_connection );
int cellK = well_conn_get_k( ert_connection );
bool isCellOpen = well_conn_open( ert_connection );
// TODO: Are these available for this type of well?
int segmentId = well_conn_get_segment( ert_connection );
int branchId = branchIdx;
// 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
if (cellK >= static_cast<int>(grids[gridNr]->cellCountK()))
{
cellK -= static_cast<int>(grids[gridNr]->cellCountK());
}
data.m_gridCellIndex = grids[gridNr]->cellIndexFromIJK(cellI , cellJ , cellK);
data.m_isOpen = isCellOpen;
data.m_branchId = branchId;
data.m_segmentId = segmentId;
cellK -= static_cast<int>(grids[gridNr]->cellCountK());
}
data.m_gridIndex = gridNr;
data.m_gridCellIndex = grids[gridNr]->cellIndexFromIJK(cellI , cellJ , cellK);
data.m_isOpen = isCellOpen;
}
}
}

View File

@ -185,15 +185,15 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector
RigCaseData* rigReservoir = m_rimReservoirView->eclipseCase()->reservoirData();
RigSingleWellResultsData* wellResults = m_rimWell->wellResults();
const RigWellResultFrame& staticWellFrame = m_rimWell->wellResults()->m_staticWellCells;
// Make sure we have computed the static representation of the well
if (staticWellFrame.m_wellResultBranches.size() == 0)
if (wellResults->m_staticWellCells.m_wellResultBranches.size() == 0)
{
wellResults->computeStaticWellCellPath();
}
if (staticWellFrame.m_wellResultBranches.size() == 0) return;
const RigWellResultFrame& staticWellFrame = wellResults->m_staticWellCells;
if (staticWellFrame.m_wellResultBranches.size() == 0) return;
// Initialize the return arrays
pipeBranchesCLCoords.clear();
pipeBranchesCellIds.clear();
@ -230,7 +230,7 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector
const RigWellResultCell* prevResCell = NULL;
// Use well head if branch head is not specified
if (resBranches[0].m_branchHead.m_gridCellIndex == cvf::UNDEFINED_SIZE_T)
if (!wellResults->isMultiSegmentWell())
{
// Create a new branch from wellhead
@ -251,20 +251,40 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector
if (resBranches[brIdx].m_wellCells.size() == 0)
continue; // Skip empty branches. Do not know why they exist, but they make problems.
if (resBranches[brIdx].m_branchHead.m_gridCellIndex != cvf::UNDEFINED_SIZE_T)
if (wellResults->isMultiSegmentWell())
{
// Create a new branch and use branch head as previous result cell
pipeBranchesCLCoords.push_back(std::vector<cvf::Vec3d>());
pipeBranchesCellIds.push_back(std::vector <RigWellResultCell>());
prevResCell = &(resBranches[brIdx].m_branchHead);
if (resBranches[brIdx].m_useBranchHeadAsCenterLineIntersectionTop)
{
// Intersection evaluation is done when all center lines are computed,
// as the center lines are used to compute the intersections
const RigCell& whCell = rigReservoir->cellFromWellResultCell(resBranches[brIdx].m_branchHead);
cvf::Vec3d branchHeadStartPos = whCell.faceCenter(cvf::StructGridInterface::NEG_K);
// Insert well head if this is branch head, as we have all information we need
if (isIdentical(&resBranches[brIdx].m_branchHead, whResCell))
{
prevResCell = whResCell;
pipeBranchesCLCoords.back().push_back(branchHeadStartPos);
pipeBranchesCellIds.back().push_back(*prevResCell);
pipeBranchesCLCoords.back().push_back(whStartPos);
pipeBranchesCellIds.back().push_back(*prevResCell);
pipeBranchesCLCoords.back().push_back(whIntermediate);
pipeBranchesCellIds.back().push_back(*prevResCell);
}
}
else
{
// Create a new branch and use branch head as previous result cell
prevResCell = &(resBranches[brIdx].m_branchHead);
const RigCell& whCell = rigReservoir->cellFromWellResultCell(resBranches[brIdx].m_branchHead);
cvf::Vec3d branchHeadStartPos = whCell.faceCenter(cvf::StructGridInterface::NEG_K);
pipeBranchesCLCoords.back().push_back(branchHeadStartPos);
pipeBranchesCellIds.back().push_back(*prevResCell);
}
}
// Loop over all the resultCells in the branch
@ -281,7 +301,14 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector
// Check if this and the previous cells has shared faces
cvf::StructGridInterface::FaceType sharedFace;
if (rigReservoir->findSharedSourceFace(sharedFace, resCell, *prevResCell))
if (resBranches[brIdx].m_useBranchHeadAsCenterLineIntersectionTop && cIdx == 0)
{
// Insert cell center of first cell
// Intersection point to connect to is inserted further down in this function
branchCLCoords.push_back(cell.center());
branchCellIds.push_back(resCell);
}
else if (rigReservoir->findSharedSourceFace(sharedFace, resCell, *prevResCell))
{
branchCLCoords.push_back(cell.faceCenter(sharedFace));
branchCellIds.push_back(resCell);
@ -316,13 +343,15 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector
if ((intoThisCell - outOfPrevCell).lengthSquared() > 1e-3)
{
branchCLCoords.push_back(outOfPrevCell);
branchCellIds.push_back(RigWellResultCell());
branchCellIds.push_back(*prevResCell);
}
branchCLCoords.push_back(intoThisCell);
branchCellIds.push_back(resCell);
}
else
{
CVF_ASSERT(!wellResults->isMultiSegmentWell());
// This cell is further from the previous cell than from the well head,
// thus we interpret it as a new branch.
@ -349,15 +378,120 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector
}
prevResCell = &resCell;
}
if (wellResults->isMultiSegmentWell())
{
// All MSW branches are completed using the point 0.5 past the center of last cell
const RigCell& prevCell = rigReservoir->cellFromWellResultCell(*prevResCell);
cvf::Vec3d centerPrevCell = prevCell.center();
pipeBranchesCLCoords.back().push_back(pipeBranchesCLCoords.back().back() + 1.5*(centerPrevCell - pipeBranchesCLCoords.back().back()) );
}
}
// For the last cell, add the point 0.5 past the center of that cell
const RigCell& prevCell = rigReservoir->cellFromWellResultCell(*prevResCell);
cvf::Vec3d centerPrevCell = prevCell.center();
pipeBranchesCLCoords.back().push_back(pipeBranchesCLCoords.back().back() + 1.5*(centerPrevCell - pipeBranchesCLCoords.back().back()) );
if (!wellResults->isMultiSegmentWell())
{
// For the last cell, add the point 0.5 past the center of that cell
const RigCell& prevCell = rigReservoir->cellFromWellResultCell(*prevResCell);
cvf::Vec3d centerPrevCell = prevCell.center();
pipeBranchesCLCoords.back().push_back(pipeBranchesCLCoords.back().back() + 1.5*(centerPrevCell - pipeBranchesCLCoords.back().back()) );
}
if (wellResults->isMultiSegmentWell())
{
// Compute intersection points for multi segment wells connected to segments of other branches
for (size_t brIdx = 0; brIdx < resBranches.size(); brIdx++)
{
const RigWellResultBranch& branchToConnect = resBranches[brIdx];
if (branchToConnect.m_useBranchHeadAsCenterLineIntersectionTop)
{
// Find intersection grid cell in branch to connect to
cvf::Vec3d intersectionPoint = cvf::Vec3d::UNDEFINED;
int outletErtBranchId = branchToConnect.m_outletErtBranchId;
for (size_t outletBranchIdx = 0; outletBranchIdx < resBranches.size(); outletBranchIdx++)
{
if (resBranches[outletBranchIdx].m_ertBranchId == outletErtBranchId)
{
RigWellResultCell outletResultCell = resBranches[outletBranchIdx].m_branchHead;
// Find generated pipe branch this cell resides in
for (size_t i = 0; i < pipeBranchesCellIds.size(); i++)
{
for (size_t j = 0; j < pipeBranchesCellIds[i].size(); j++)
{
const RigWellResultCell& candidate = pipeBranchesCellIds[i][j];
if (isIdentical(&candidate, &outletResultCell))
{
// Find the coordinate pair at the intersection between two cell IDs
while (j + 1 < pipeBranchesCellIds[i].size() && isIdentical(&pipeBranchesCellIds[i][j + 1], &outletResultCell))
{
j++;
}
if (j + 1 >= pipeBranchesCLCoords[i].size())
{
// Use the last point in the center line
intersectionPoint = pipeBranchesCLCoords[i][j];
}
else
{
cvf::Vec3d lineStart = pipeBranchesCLCoords[i][j];
cvf::Vec3d lineEnd = pipeBranchesCLCoords[i][j + 1];
cvf::Plane depthPlane;
depthPlane.setFromPointAndNormal(cvf::Vec3d(0.0, 0.0, -branchToConnect.m_connectionDepthOnOutletBranch), cvf::Vec3d::Z_AXIS);
cvf::Vec3d linePlaneIntersect;
if (depthPlane.intersect(lineStart, lineEnd, &linePlaneIntersect))
{
intersectionPoint = linePlaneIntersect;
}
}
}
}
}
}
}
if (!intersectionPoint.isUndefined())
{
// Find generated pipe branch this cell resides in
// and insert intersection point at start of list
bool foundBranchToInsertInto = false;
size_t i = 0;
while(!foundBranchToInsertInto && i < pipeBranchesCellIds.size())
{
size_t j = 0;
while(!foundBranchToInsertInto && j < pipeBranchesCellIds[i].size())
{
const RigWellResultCell& candidate = pipeBranchesCellIds[i][j];
if (isIdentical(&candidate, &branchToConnect.m_wellCells[0]))
{
pipeBranchesCellIds[i].insert(pipeBranchesCellIds[i].begin(), candidate);
pipeBranchesCLCoords[i].insert(pipeBranchesCLCoords[i].begin(), intersectionPoint);
foundBranchToInsertInto = true;
}
j++;
}
i++;
}
}
else
{
// Could not detect intersection, use well head as fall back?
// Currently, if nothing is found, the end of the branch closest to well head is not connected to main branch
}
}
}
}
}
CVF_ASSERT(pipeBranchesCellIds.size() == pipeBranchesCLCoords.size());

View File

@ -118,7 +118,7 @@ void RigSingleWellResultsData::computeStaticWellCellPath()
for (size_t bIdx = 0; bIdx < m_wellCellsTimeSteps[0].m_wellResultBranches.size(); ++bIdx)
{
size_t branchNumber = m_wellCellsTimeSteps[0].m_wellResultBranches[bIdx].m_branchNumber;
size_t branchNumber = m_wellCellsTimeSteps[0].m_wellResultBranches[bIdx].m_branchIndex;
std::vector<RigWellResultCell>& frameCells = m_wellCellsTimeSteps[0].m_wellResultBranches[bIdx].m_wellCells;
std::list< RigWellResultCell >& branch = staticWellBranches[branchNumber];
@ -137,7 +137,7 @@ void RigSingleWellResultsData::computeStaticWellCellPath()
for (size_t bIdx = 0; bIdx < m_wellCellsTimeSteps[tIdx].m_wellResultBranches.size(); ++bIdx)
{
size_t branchNumber = m_wellCellsTimeSteps[tIdx].m_wellResultBranches[bIdx].m_branchNumber;
size_t branchNumber = m_wellCellsTimeSteps[tIdx].m_wellResultBranches[bIdx].m_branchIndex;
std::vector<RigWellResultCell>& resBranch = m_wellCellsTimeSteps[tIdx].m_wellResultBranches[bIdx].m_wellCells;
std::list< RigWellResultCell >& stBranch = staticWellBranches[branchNumber];
@ -252,12 +252,15 @@ void RigSingleWellResultsData::computeStaticWellCellPath()
for (bIt = staticWellBranches.begin(); bIt != staticWellBranches.end(); ++bIt)
{
RigWellResultBranch rigBranch;
rigBranch.m_branchNumber = bIt->first;
// Copy from first time step
RigWellResultBranch rigBranch = m_wellCellsTimeSteps[0].m_wellResultBranches[bIt->first];
rigBranch.m_branchIndex = bIt->first;
// Clear well cells, and insert the collection of well cells for the static situation
rigBranch.m_wellCells.clear();
std::list< RigWellResultCell >& branch = bIt->second;
std::list< RigWellResultCell >::iterator cIt;
for (cIt = branch.begin(); cIt != branch.end(); ++cIt)
{
RigWellResultCell rwc = *cIt;
@ -269,3 +272,19 @@ void RigSingleWellResultsData::computeStaticWellCellPath()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigSingleWellResultsData::setMultiSegmentWell(bool isMultiSegmentWell)
{
m_isMultiSegmentWell = isMultiSegmentWell;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigSingleWellResultsData::isMultiSegmentWell() const
{
return m_isMultiSegmentWell;
}

View File

@ -31,15 +31,11 @@ struct RigWellResultCell
RigWellResultCell() :
m_gridIndex(cvf::UNDEFINED_SIZE_T),
m_gridCellIndex(cvf::UNDEFINED_SIZE_T),
m_branchId(-1),
m_segmentId(-1),
m_isOpen(false)
{ }
size_t m_gridIndex;
size_t m_gridCellIndex; //< Index to cell which is included in the well
int m_branchId;
int m_segmentId;
bool m_isOpen; //< Marks the well as open or closed as of Eclipse simulation
};
@ -47,10 +43,13 @@ struct RigWellResultCell
struct RigWellResultBranch
{
RigWellResultBranch() :
m_branchNumber(cvf::UNDEFINED_SIZE_T)
m_branchIndex(cvf::UNDEFINED_SIZE_T),
m_ertBranchId(-1),
m_useBranchHeadAsCenterLineIntersectionTop(false)
{}
size_t m_branchNumber;
size_t m_branchIndex;
int m_ertBranchId;
std::vector<RigWellResultCell> m_wellCells;
@ -58,11 +57,13 @@ struct RigWellResultBranch
// For standard wells, this is always well head.
RigWellResultCell m_branchHead;
bool m_useBranchHeadAsCenterLineIntersectionTop;
// If the outlet segment does not have any connections, it is not possible to populate branch head
// Instead, use the intersection segment outlet branch index and the depth of this segment to identify intersection point
// when computing centerline coords in RivWellPipesPartMgr
size_t m_intersectionSegmentOutletBranchIndex;
double m_intersectionSegmentOutletDepth;
int m_outletErtBranchId;
double m_connectionDepthOnOutletBranch;
};
class RigWellResultFrame
@ -113,6 +114,11 @@ public:
class RigSingleWellResultsData : public cvf::Object
{
public:
RigSingleWellResultsData() { m_isMultiSegmentWell = false; }
void setMultiSegmentWell(bool isMultiSegmentWell);
bool isMultiSegmentWell() const;
bool hasWellResult(size_t resultTimeStepIndex) const;
size_t firstResultTimeStep() const;
@ -124,6 +130,7 @@ public:
public:
QString m_wellName;
bool m_isMultiSegmentWell;
std::vector<size_t> m_resultTimeStepIndexToWellTimeStepIndex; // Well result timesteps may differ from result timesteps
std::vector< RigWellResultFrame > m_wellCellsTimeSteps;