From 070d9c893bec464863afc3b25effd89a7b53cbc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Fri, 17 Feb 2017 15:48:42 +0100 Subject: [PATCH] #1209 Added calculation of none-accumulated flows as preparation for #1171 and #1120. Missing handling of wells with inconsistent flow. --- .../Flow/RimWellAllocationPlot.cpp | 28 ++- .../Flow/RimWellAllocationPlot.h | 3 + .../RigAccWellFlowCalculator.cpp | 165 ++++++++++++------ .../RigAccWellFlowCalculator.h | 32 ++-- 4 files changed, 157 insertions(+), 71 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp index 5975a2dc92..c4075dcf55 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp @@ -52,6 +52,19 @@ CAF_PDM_SOURCE_INIT(RimWellAllocationPlot, "WellAllocationPlot"); /// //-------------------------------------------------------------------------------------------------- +namespace caf +{ + +template<> +void AppEnum::setUp() +{ + addItem(RimWellAllocationPlot::ACCUMULATED, "ACCUMULATED", "Well Flow"); + addItem(RimWellAllocationPlot::INFLOW, "INFLOW", "In Flow"); + setDefault(RimWellAllocationPlot::ACCUMULATED); + +} +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -70,6 +83,8 @@ RimWellAllocationPlot::RimWellAllocationPlot() CAF_PDM_InitField(&m_timeStep, "PlotTimeStep", 0, "Time Step", "", "", ""); CAF_PDM_InitField(&m_wellName, "WellName", QString("None"), "Well", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_flowDiagSolution, "FlowDiagSolution", "Flow Diag Solution", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_flowType, "FlowType", "Flow Type", "", "", ""); + CAF_PDM_InitField(&m_groupSmallContributions, "GroupSmallContributions", true, "Group Small Contributions", "", "", ""); CAF_PDM_InitField(&m_smallContributionsThreshold, "SmallContributionsThreshold", 0.005, "Threshold", "", "", ""); @@ -238,13 +253,19 @@ void RimWellAllocationPlot::updateFromWell() std::vector tracerNames = wfCalculator->tracerNames(); for (const QString& tracerName: tracerNames) { - const std::vector& accFlow = wfCalculator->accumulatedTracerFlowPrConnection(tracerName, brIdx); + const std::vector& accFlow = m_flowType == ACCUMULATED ? + wfCalculator->accumulatedTracerFlowPrConnection(tracerName, brIdx): + wfCalculator->tracerFlowPrConnection(tracerName, brIdx); + addStackedCurve(tracerName, connNumbers, accFlow, plotTrack); } } else { - const std::vector& accFlow = wfCalculator->accumulatedTotalFlowPrConnection(brIdx); + const std::vector& accFlow = m_flowType == ACCUMULATED ? + wfCalculator->accumulatedFlowPrConnection(brIdx): + wfCalculator->flowPrConnection(brIdx); + addStackedCurve("Total", connNumbers, accFlow, plotTrack); } @@ -597,7 +618,8 @@ void RimWellAllocationPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedF || changedField == &m_timeStep || changedField == &m_flowDiagSolution || changedField == &m_groupSmallContributions - || changedField == &m_smallContributionsThreshold ) + || changedField == &m_smallContributionsThreshold + || changedField == &m_flowType ) { loadDataAndUpdate(); } diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.h index 5ea657520d..a6d0636b59 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.h @@ -49,6 +49,8 @@ namespace caf { class RimWellAllocationPlot : public RimViewWindow { CAF_PDM_HEADER_INIT; +public: + enum FlowType { ACCUMULATED, INFLOW}; public: RimWellAllocationPlot(); @@ -115,6 +117,7 @@ private: caf::PdmPtrField m_flowDiagSolution; caf::PdmField m_groupSmallContributions; caf::PdmField m_smallContributionsThreshold; + caf::PdmField > m_flowType; QPointer m_wellAllocationPlotWidget; diff --git a/ApplicationCode/ReservoirDataModel/RigAccWellFlowCalculator.cpp b/ApplicationCode/ReservoirDataModel/RigAccWellFlowCalculator.cpp index 81adad8444..59da784404 100644 --- a/ApplicationCode/ReservoirDataModel/RigAccWellFlowCalculator.cpp +++ b/ApplicationCode/ReservoirDataModel/RigAccWellFlowCalculator.cpp @@ -60,7 +60,7 @@ RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vecto m_cellIndexCalculator(cellIndexCalculator), m_smallContributionsThreshold(smallContribThreshold) { - m_accConnectionFlowPrBranch.resize(m_pipeBranchesCellIds.size()); + m_connectionFlowPrBranch.resize(m_pipeBranchesCellIds.size()); if (isWellFlowConsistent(isProducer)) { @@ -95,7 +95,7 @@ RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vecto m_cellIndexCalculator(RigEclCellIndexCalculator(nullptr, nullptr)), m_smallContributionsThreshold(smallContribThreshold) { - m_accConnectionFlowPrBranch.resize(m_pipeBranchesCellIds.size()); + m_connectionFlowPrBranch.resize(m_pipeBranchesCellIds.size()); m_tracerNames.push_back(RIG_FLOW_TOTAL_NAME); @@ -105,21 +105,53 @@ RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vecto //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::vector& RigAccWellFlowCalculator::accumulatedTotalFlowPrConnection(size_t branchIdx) +const std::vector& RigAccWellFlowCalculator::accumulatedFlowPrConnection(size_t branchIdx) const { - CVF_ASSERT(m_accConnectionFlowPrBranch[branchIdx].accFlowPrTracer.find(RIG_FLOW_TOTAL_NAME) != m_accConnectionFlowPrBranch[branchIdx].accFlowPrTracer.end()); - - return m_accConnectionFlowPrBranch[branchIdx].accFlowPrTracer[RIG_FLOW_TOTAL_NAME]; + return accumulatedTracerFlowPrConnection(RIG_FLOW_TOTAL_NAME, branchIdx); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::vector& RigAccWellFlowCalculator::accumulatedTracerFlowPrConnection(const QString& tracerName, size_t branchIdx) +const std::vector& RigAccWellFlowCalculator::accumulatedTracerFlowPrConnection(const QString& tracerName, size_t branchIdx) const { - CVF_ASSERT(m_accConnectionFlowPrBranch[branchIdx].accFlowPrTracer.find(tracerName) != m_accConnectionFlowPrBranch[branchIdx].accFlowPrTracer.end()); + auto flowPrTracerIt = m_connectionFlowPrBranch[branchIdx].accFlowPrTracer.find(tracerName); + if ( flowPrTracerIt != m_connectionFlowPrBranch[branchIdx].accFlowPrTracer.end()) + { + return flowPrTracerIt->second; + } + else + { + CVF_ASSERT(false); + static std::vector dummy; + return dummy; + } +} - return m_accConnectionFlowPrBranch[branchIdx].accFlowPrTracer[tracerName]; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigAccWellFlowCalculator::flowPrConnection(size_t branchIdx) const +{ + return tracerFlowPrConnection(RIG_FLOW_TOTAL_NAME, branchIdx); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigAccWellFlowCalculator::tracerFlowPrConnection(const QString& tracerName, size_t branchIdx) const +{ + auto flowPrTracerIt = m_connectionFlowPrBranch[branchIdx].flowPrTracer.find(tracerName); + if ( flowPrTracerIt != m_connectionFlowPrBranch[branchIdx].flowPrTracer.end()) + { + return flowPrTracerIt->second; + } + else + { + CVF_ASSERT(false); + static std::vector dummy; + return dummy; + } } //-------------------------------------------------------------------------------------------------- @@ -127,13 +159,13 @@ const std::vector& RigAccWellFlowCalculator::accumulatedTracerFlowPrConn //-------------------------------------------------------------------------------------------------- const std::vector& RigAccWellFlowCalculator::connectionNumbersFromTop(size_t branchIdx) const { - return m_accConnectionFlowPrBranch[branchIdx].depthValuesFromTop; + return m_connectionFlowPrBranch[branchIdx].depthValuesFromTop; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector > RigAccWellFlowCalculator::totalWellFlowPrTracer() +std::vector > RigAccWellFlowCalculator::totalWellFlowPrTracer() const { std::vector tracerNames = this->tracerNames(); std::vector > tracerWithValues; @@ -151,7 +183,7 @@ std::vector > RigAccWellFlowCalculator::totalWellFlow //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector > RigAccWellFlowCalculator::totalTracerFractions() +std::vector > RigAccWellFlowCalculator::totalTracerFractions() const { std::vector > totalFlows = totalWellFlowPrTracer(); @@ -174,7 +206,7 @@ std::vector > RigAccWellFlowCalculator::totalTracerFr //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RigAccWellFlowCalculator::isWellFlowConsistent( bool isProducer) +bool RigAccWellFlowCalculator::isWellFlowConsistent( bool isProducer) const { bool isConsistent = true; for (const std::vector & branch : m_pipeBranchesCellIds) @@ -205,11 +237,7 @@ void RigAccWellFlowCalculator::calculateAccumulatedFlowPrConnection(size_t branc size_t prevConnIndx = -1; int clSegIdx = static_cast(branchCells.size()) - 1; - std::map >& accConnFlowFractionsPrTracer = m_accConnectionFlowPrBranch[branchIdx].accFlowPrTracer; - std::vector& connNumbersFromTop = m_accConnectionFlowPrBranch[branchIdx].depthValuesFromTop; - - std::vector accFlow; - accFlow.resize(m_tracerNames.size(), 0.0); + std::vector accFlowPrTracer(m_tracerNames.size(), 0.0); while ( clSegIdx >= 0 ) { @@ -225,6 +253,7 @@ void RigAccWellFlowCalculator::calculateAccumulatedFlowPrConnection(size_t branc } // Accumulate the connection-cell's fraction flows + std::vector flowPrTracer(m_tracerNames.size(), 0.0); if ( m_tracerCellFractionValues ) { @@ -239,19 +268,25 @@ void RigAccWellFlowCalculator::calculateAccumulatedFlowPrConnection(size_t branc double cellTracerFraction = (*tracerFractionIt.second)[resCellIndex]; if (cellTracerFraction != HUGE_VAL && cellTracerFraction == cellTracerFraction) { - accFlow[tracerIdx] += cellTracerFraction * branchCells[clSegIdx].flowRate(); + double tracerFlow = cellTracerFraction * branchCells[clSegIdx].flowRate(); + flowPrTracer[tracerIdx] = tracerFlow; + accFlowPrTracer[tracerIdx] += tracerFlow; + totalTracerFractionInCell += cellTracerFraction; } tracerIdx++; } - double reservoirFraction = 1.0 - totalTracerFractionInCell; - accFlow[tracerIdx] += reservoirFraction * branchCells[clSegIdx].flowRate(); + double reservoirFraction = 1.0 - totalTracerFractionInCell; + double reservoirTracerFlow = reservoirFraction * branchCells[clSegIdx].flowRate(); + flowPrTracer[tracerIdx] = reservoirTracerFlow; + accFlowPrTracer[tracerIdx] += reservoirTracerFlow; } } else { - accFlow[0] += branchCells[clSegIdx].flowRate(); + accFlowPrTracer[0] += branchCells[clSegIdx].flowRate(); + flowPrTracer[0] = branchCells[clSegIdx].flowRate(); } // Add the total accumulated (fraction) flows from any branches connected to this cell @@ -261,39 +296,47 @@ void RigAccWellFlowCalculator::calculateAccumulatedFlowPrConnection(size_t branc std::vector downstreamBranches = findDownstreamBranchIdxs(branchCells[clSegIdx]); for ( size_t dsBidx : downstreamBranches ) { - if ( dsBidx != branchIdx && m_accConnectionFlowPrBranch[dsBidx].depthValuesFromTop.size() == 0 ) // Not this branch or already calculated + if ( dsBidx != branchIdx && m_connectionFlowPrBranch[dsBidx].depthValuesFromTop.size() == 0 ) // Not this branch or already calculated { calculateAccumulatedFlowPrConnection(dsBidx, connNumFromTop); - BranchFlow& accConnFlowFractionsDsBranch = m_accConnectionFlowPrBranch[dsBidx]; + BranchFlow& accConnFlowFractionsDsBranch = m_connectionFlowPrBranch[dsBidx]; size_t tracerIdx = 0; for ( const auto & tracerName: m_tracerNames ) { - accFlow[tracerIdx] += accConnFlowFractionsDsBranch.accFlowPrTracer[tracerName].back(); + accFlowPrTracer[tracerIdx] += accConnFlowFractionsDsBranch.accFlowPrTracer[tracerName].back(); tracerIdx++; } } } // Push back the accumulated result into the storage - - size_t tracerIdx = 0; - for ( const auto & tracerName: m_tracerNames ) { - accConnFlowFractionsPrTracer[tracerName].push_back(accFlow[tracerIdx]); - tracerIdx++; + std::vector& connNumbersFromTop = m_connectionFlowPrBranch[branchIdx].depthValuesFromTop; + std::map >& branchAccFlowPrTracer = m_connectionFlowPrBranch[branchIdx].accFlowPrTracer; + std::map >& branchFlowPrTracer = m_connectionFlowPrBranch[branchIdx].flowPrTracer; + + size_t tracerIdx = 0; + for ( const auto & tracerName: m_tracerNames ) + { + branchAccFlowPrTracer[tracerName].push_back(accFlowPrTracer[tracerIdx]); + branchFlowPrTracer[tracerName].push_back(flowPrTracer[tracerIdx]); + tracerIdx++; + } + + + connNumbersFromTop.push_back(connNumFromTop); } - connNumbersFromTop.push_back(connNumFromTop); - --clSegIdx; + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RigAccWellFlowCalculator::wrpToConnectionIndexFromBottom(const std::vector &branchCells) +std::vector RigAccWellFlowCalculator::wrpToConnectionIndexFromBottom(const std::vector &branchCells) const { std::vector resPointToConnectionIndexFromBottom; resPointToConnectionIndexFromBottom.resize(branchCells.size(), -1); @@ -335,7 +378,7 @@ std::vector RigAccWellFlowCalculator::wrpToConnectionIndexFromBottom(con //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigAccWellFlowCalculator::connectionIndexFromTop(const std::vector& resPointToConnectionIndexFromBottom, size_t clSegIdx) +size_t RigAccWellFlowCalculator::connectionIndexFromTop(const std::vector& resPointToConnectionIndexFromBottom, size_t clSegIdx) { return resPointToConnectionIndexFromBottom.front() - resPointToConnectionIndexFromBottom[clSegIdx]; } @@ -343,7 +386,7 @@ size_t RigAccWellFlowCalculator::connectionIndexFromTop(const std::vector RigAccWellFlowCalculator::findDownstreamBranchIdxs(const RigWellResultPoint& connectionPoint) +std::vector RigAccWellFlowCalculator::findDownstreamBranchIdxs(const RigWellResultPoint& connectionPoint) const { std::vector downStreamBranchIdxs; @@ -412,27 +455,10 @@ void RigAccWellFlowCalculator::groupSmallContributions() // Concatenate the values for each branch, erasing the tracers being grouped, replaced with the concatenated values - for ( BranchFlow& brRes : m_accConnectionFlowPrBranch ) + for ( BranchFlow& brRes : m_connectionFlowPrBranch ) { - std::vector groupedConnectionValues( brRes.depthValuesFromTop.size(), 0.0); - - for ( const QString& tracername:tracersToGroup ) - { - auto it = brRes.accFlowPrTracer.find(tracername); - - if ( it != brRes.accFlowPrTracer.end() ) - { - const std::vector& tracerVals = it->second; - for ( size_t cIdx = 0; cIdx < groupedConnectionValues.size(); ++cIdx ) - { - groupedConnectionValues[cIdx] += tracerVals[cIdx]; - } - } - - brRes.accFlowPrTracer.erase(it); - } - - brRes.accFlowPrTracer[RIG_TINY_TRACER_GROUP_NAME] = groupedConnectionValues; + groupSmallTracers( brRes.accFlowPrTracer, tracersToGroup); + groupSmallTracers( brRes.flowPrTracer, tracersToGroup); } // Remove the grouped tracer names from the tracerName list, and replace with the "Others" name @@ -454,3 +480,32 @@ void RigAccWellFlowCalculator::groupSmallContributions() } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigAccWellFlowCalculator::groupSmallTracers(std::map> &branchFlowSet, std::vector tracersToGroup) +{ + if ( branchFlowSet.empty() ) return; + + size_t depthCount = branchFlowSet.begin()->second.size(); + std::vector groupedAccFlowValues(depthCount, 0.0); + + for ( const QString& tracername:tracersToGroup ) + { + auto it = branchFlowSet.find(tracername); + + if ( it != branchFlowSet.end() ) + { + const std::vector& tracerVals = it->second; + for ( size_t cIdx = 0; cIdx < groupedAccFlowValues.size(); ++cIdx ) + { + groupedAccFlowValues[cIdx] += tracerVals[cIdx]; + } + } + + branchFlowSet.erase(it); + } + + branchFlowSet[RIG_TINY_TRACER_GROUP_NAME] = groupedAccFlowValues; +} + diff --git a/ApplicationCode/ReservoirDataModel/RigAccWellFlowCalculator.h b/ApplicationCode/ReservoirDataModel/RigAccWellFlowCalculator.h index 45b4872052..451470367c 100644 --- a/ApplicationCode/ReservoirDataModel/RigAccWellFlowCalculator.h +++ b/ApplicationCode/ReservoirDataModel/RigAccWellFlowCalculator.h @@ -68,26 +68,32 @@ public: const std::vector< std::vector >& pipeBranchesCellIds, double smallContribThreshold); - const std::vector& accumulatedTotalFlowPrConnection( size_t branchIdx);// const; - const std::vector& accumulatedTracerFlowPrConnection(const QString& tracerName, size_t branchIdx);// const; + const std::vector& accumulatedFlowPrConnection( size_t branchIdx) const; + const std::vector& accumulatedTracerFlowPrConnection(const QString& tracerName, size_t branchIdx) const; + const std::vector& flowPrConnection( size_t branchIdx) const; + const std::vector& tracerFlowPrConnection(const QString& tracerName, size_t branchIdx) const; const std::vector& connectionNumbersFromTop(size_t branchIdx) const; const std::vector& tracerNames() const { return m_tracerNames;} - std::vector > totalTracerFractions(); + std::vector > totalTracerFractions() const; private: - bool isWellFlowConsistent(bool isProducer); void calculateAccumulatedFlowPrConnection( size_t branchIdx, size_t startConnectionNumberFromTop); - std::vector wrpToConnectionIndexFromBottom( const std::vector &branchCells); - static size_t connectionIndexFromTop( const std::vector& resPointToConnectionIndexFromBottom, size_t clSegIdx); - std::vector findDownstreamBranchIdxs( const RigWellResultPoint& connectionPoint); - - std::vector > totalWellFlowPrTracer() ; void sortTracers(); - void groupSmallContributions(); + void groupSmallTracers(std::map> &branchFlowSet, + std::vector tracersToGroup); + + bool isWellFlowConsistent(bool isProducer) const; + std::vector wrpToConnectionIndexFromBottom( const std::vector &branchCells) const; + static size_t connectionIndexFromTop( const std::vector& resPointToConnectionIndexFromBottom, size_t clSegIdx) ; + std::vector findDownstreamBranchIdxs( const RigWellResultPoint& connectionPoint) const; + + std::vector > totalWellFlowPrTracer() const; + + const std::vector< std::vector >& m_pipeBranchesCLCoords; const std::vector< std::vector >& m_pipeBranchesCellIds; const std::map* >* m_tracerCellFractionValues; @@ -102,9 +108,9 @@ private: std::map > flowPrTracer; }; - std::vector< BranchFlow > m_accConnectionFlowPrBranch; - std::vector< BranchFlow > m_accPseudoLengthFlowPrBranch; - std::vector< BranchFlow > m_accTvdFlowPrBranch; + std::vector< BranchFlow > m_connectionFlowPrBranch; + std::vector< BranchFlow > m_pseudoLengthFlowPrBranch; + std::vector< BranchFlow > m_tvdFlowPrBranch; };