From 90c791a2daf7acba1876906b0a7203bf86a8451f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Wed, 25 Jan 2017 22:49:25 +0100 Subject: [PATCH] #1112 Finally the first iteration of the actual calculation of accumulated flow pr connection. No Flow Diagnostics yet, and we wait for the real flow rates. --- .../Flow/RimWellAllocationPlot.cpp | 147 +++++++++++++++++- .../RigSingleWellResultsData.h | 2 +- 2 files changed, 145 insertions(+), 4 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp index fdf341d81c..1c6743aec3 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp @@ -43,6 +43,133 @@ CAF_PDM_SOURCE_INIT(RimWellAllocationPlot, "WellAllocationPlot"); +//================================================================================================== +/// +/// +//================================================================================================== + +class RigAccWellFlowCalculator +{ + +public: + RigAccWellFlowCalculator(const std::vector< std::vector >& pipeBranchesCLCoords, + const std::vector< std::vector >& pipeBranchesCellIds): + m_pipeBranchesCLCoords(pipeBranchesCLCoords), m_pipeBranchesCellIds(pipeBranchesCellIds) + { + m_accConnectionFlowPrBranch.resize(m_pipeBranchesCellIds.size()); + + calculateAccumulatedFlowPrConnection(0,1); + } + + // Returned pair is connection number from top of well with accumulated flow + + const std::vector >& accumulatedFlowPrConnection(size_t branchIdx) + { + return m_accConnectionFlowPrBranch[branchIdx]; + } + +private: + + + + const std::vector >& calculateAccumulatedFlowPrConnection(size_t branchIdx, size_t startConnectionNumberFromTop) + { + std::vector >& accConnectionFlow = m_accConnectionFlowPrBranch[branchIdx]; + + const std::vector& branchCells = m_pipeBranchesCellIds[branchIdx]; + int clSegIdx = static_cast( branchCells.size()) - 1; + double accFlow = 0.0; + + size_t prevGridIdx = -1; + size_t prevGridCellIdx = -1; + + std::vector resPointToConnectionIndexFromBottom; + resPointToConnectionIndexFromBottom.resize(branchCells.size(), -1); + + size_t connIdxFromBottom = 0; + + while (clSegIdx >= 0) + { + resPointToConnectionIndexFromBottom[clSegIdx] = connIdxFromBottom; + + if ( branchCells[clSegIdx].m_gridIndex != prevGridIdx + && branchCells[clSegIdx].m_gridCellIndex != prevGridIdx ) + { + ++connIdxFromBottom; + } + + prevGridIdx = branchCells[clSegIdx].m_gridIndex ; + prevGridCellIdx = branchCells[clSegIdx].m_gridCellIndex; + + --clSegIdx; + } + + size_t prevConnIndx = -1; + clSegIdx = static_cast( branchCells.size()) - 1; + + while (clSegIdx >= 0) + { + // Skip point if referring to the same cell as in the previous point did + { + if (resPointToConnectionIndexFromBottom[clSegIdx] == prevConnIndx) + { + --clSegIdx; + continue; + } + + prevConnIndx = resPointToConnectionIndexFromBottom[clSegIdx]; + } + + size_t connNumFromTop = connecionIdxFromTop(resPointToConnectionIndexFromBottom, clSegIdx) + startConnectionNumberFromTop; + + accFlow += branchCells[clSegIdx].m_flowRate; + std::vector downstreamBranches = findDownstreamBranchIdxs(branchCells[clSegIdx]); + for (size_t dsBidx : downstreamBranches ) + { + if ( dsBidx != branchIdx && m_accConnectionFlowPrBranch[dsBidx].size() == 0) // Not this branch or already calculated + { + const std::pair & brancFlowPair = calculateAccumulatedFlowPrConnection(dsBidx, connNumFromTop).back(); + accFlow += brancFlowPair.second; + } + } + + accConnectionFlow.push_back(std::make_pair(connNumFromTop, accFlow)); + + --clSegIdx; + } + + return m_accConnectionFlowPrBranch[branchIdx]; + } + + static size_t connecionIdxFromTop( std::vector resPointToConnectionIndexFromBottom, size_t clSegIdx) + { + return resPointToConnectionIndexFromBottom.front() - resPointToConnectionIndexFromBottom[clSegIdx]; + } + + std::vector findDownstreamBranchIdxs(const RigWellResultPoint& connectionPoint) + { + std::vector downStreamBranchIdxs; + + for (size_t bIdx = 0; bIdx < m_pipeBranchesCellIds.size(); ++bIdx) + { + if ( m_pipeBranchesCellIds[bIdx][0].m_gridIndex == connectionPoint.m_gridIndex + && m_pipeBranchesCellIds[bIdx][0].m_gridCellIndex == connectionPoint.m_gridCellIndex) + { + downStreamBranchIdxs.push_back(bIdx); + } + } + return downStreamBranchIdxs; + } + + + const std::vector< std::vector >& m_pipeBranchesCLCoords; + const std::vector< std::vector >& m_pipeBranchesCellIds; + + std::vector< std::vector > > m_accConnectionFlowPrBranch; + +}; + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -144,7 +271,8 @@ void RimWellAllocationPlot::updateFromWell() pipeBranchesCellIds); accumulatedWellFlowPlot()->setDescription("Accumulated Well Flow (" + m_wellName + ")"); - + + RigAccWellFlowCalculator wfCalculator(pipeBranchesCLCoords, pipeBranchesCellIds); // Delete existing tracks { @@ -171,6 +299,7 @@ void RimWellAllocationPlot::updateFromWell() accumulatedWellFlowPlot()->addTrack(plotTrack); + #if 0 std::vector curveCoords; std::vector flowRate; @@ -199,9 +328,21 @@ void RimWellAllocationPlot::updateFromWell() } RigSimulationWellCoordsAndMD helper(curveCoords); - + #endif + + const std::vector >& flowPrConnection = wfCalculator.accumulatedFlowPrConnection(brIdx); + + std::vector connNumbers; + std::vector accFlow; + + for (const std::pair & flowPair: flowPrConnection) + { + connNumbers.push_back(flowPair.first); + accFlow.push_back(flowPair.second); + } + RimWellFlowRateCurve* curve = new RimWellFlowRateCurve; - curve->setFlowValues(helper.measuredDepths(), flowRate); + curve->setFlowValues(connNumbers, accFlow); plotTrack->addCurve(curve); diff --git a/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.h b/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.h index c03179d870..6e3d7a6ea7 100644 --- a/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.h +++ b/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.h @@ -42,7 +42,7 @@ struct RigWellResultPoint m_bottomPosition(cvf::Vec3d::UNDEFINED), m_flowRate(0.0) { } - + bool isPointValid() const { return m_bottomPosition != cvf::Vec3d::UNDEFINED;