diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp index ae49638eb6..bddef3cd95 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp @@ -152,6 +152,8 @@ void RimWellAllocationPlot::updateFromWell() if (!wellResults) return; + // Set up the Accumulated Well Flow Calculator + std::vector< std::vector > pipeBranchesCLCoords; std::vector< std::vector > pipeBranchesCellIds; @@ -206,6 +208,8 @@ void RimWellAllocationPlot::updateFromWell() } + // Create tracks and curves from the calculated data + size_t branchCount = pipeBranchesCLCoords.size(); for (size_t brIdx = 0; brIdx < branchCount; ++brIdx) { @@ -220,8 +224,6 @@ void RimWellAllocationPlot::updateFromWell() accumulatedWellFlowPlot()->addTrack(plotTrack); - - if ( m_flowDiagSolution ) { std::vector connNumbers; @@ -233,9 +235,7 @@ void RimWellAllocationPlot::updateFromWell() std::vector tracerNames = wfCalculator->tracerNames(); for (const QString& tracerName: tracerNames) { - std::vector accFlow; - - accFlow = wfCalculator->accumulatedTracerFlowPrConnection(tracerName, brIdx); + const std::vector& accFlow = wfCalculator->accumulatedTracerFlowPrConnection(tracerName, brIdx); RimWellFlowRateCurve* curve = new RimWellFlowRateCurve; curve->setFlowValues(tracerName, connNumbers, accFlow); @@ -247,12 +247,12 @@ void RimWellAllocationPlot::updateFromWell() else { std::vector connNumbers; - std::vector accFlow; + { + const std::vector& connNumbersSize_t = wfCalculator->connectionNumbersFromTop(brIdx); + for ( size_t conNumb : connNumbersSize_t ) connNumbers.push_back(static_cast(conNumb)); + } - accFlow = wfCalculator->accumulatedTotalFlowPrConnection(brIdx); - - const std::vector& connNumbersSize_t = wfCalculator->connectionNumbersFromTop(brIdx); - for ( size_t conNumb : connNumbersSize_t ) connNumbers.push_back(static_cast(conNumb)); + const std::vector& accFlow = wfCalculator->accumulatedTotalFlowPrConnection(brIdx); RimWellFlowRateCurve* curve = new RimWellFlowRateCurve; curve->setFlowValues("Total", connNumbers, accFlow); diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.cpp index b9ff26b170..29692a465d 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.cpp @@ -24,6 +24,8 @@ #include "qwt_plot.h" #include "RimWellLogPlot.h" +#include "WellLogCommands/RicWellLogPlotCurveFeatureImpl.h" +#include "RimWellLogTrack.h" @@ -40,6 +42,7 @@ CAF_PDM_SOURCE_INIT(RimWellFlowRateCurve, "RimWellFlowRateCurve"); RimWellFlowRateCurve::RimWellFlowRateCurve() { CAF_PDM_InitObject("Flow Rate Curve", "", "", ""); + m_curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable(); } //-------------------------------------------------------------------------------------------------- @@ -96,15 +99,9 @@ void RimWellFlowRateCurve::onLoadDataAndUpdate() if (isCurveVisible()) { - RimWellLogPlot* wellLogPlot; - firstAncestorOrThisOfType(wellLogPlot); - CVF_ASSERT(wellLogPlot); - m_qwtPlotCurve->setTitle(createCurveAutoName()); - RimDefines::DepthUnitType displayUnit = RimDefines::UNIT_METER; - m_qwtPlotCurve->setSamples(m_curveData->xPlotValues().data(), m_curveData->measuredDepthPlotValues(displayUnit).data(), static_cast(m_curveData->xPlotValues().size())); - m_qwtPlotCurve->setLineSegmentStartStopIndices(m_curveData->polylineStartStopIndices()); + updateStackedPlotData(); updateZoomInParentPlot(); @@ -112,6 +109,64 @@ void RimWellFlowRateCurve::onLoadDataAndUpdate() } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellFlowRateCurve::updateCurveAppearance() +{ + RimWellLogCurve::updateCurveAppearance(); + + m_qwtPlotCurve->setStyle(QwtPlotCurve::Steps); + QColor curveQColor = QColor (m_curveColor.value().rByte(), m_curveColor.value().gByte(), m_curveColor.value().bByte()); + m_qwtPlotCurve->setBrush(QBrush( curveQColor)); + + QPen curvePen = m_qwtPlotCurve->pen(); + curvePen.setColor(curveQColor.darker()); + m_qwtPlotCurve->setPen(curvePen); + m_qwtPlotCurve->setOrientation(Qt::Horizontal); + m_qwtPlotCurve->setBaseline(0.0); + m_qwtPlotCurve->setCurveAttribute(QwtPlotCurve::Inverted, true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellFlowRateCurve::updateStackedPlotData() +{ + RimWellLogTrack* wellLogTrack; + firstAncestorOrThisOfType(wellLogTrack); + + RimDefines::DepthUnitType displayUnit = RimDefines::UNIT_METER; + + std::vector depthValues = m_curveData->measuredDepthPlotValues(displayUnit); + if (depthValues.size()) depthValues.insert(depthValues.begin(), depthValues[0]); // Insert the first depth position again, to make room for a real 0 value + std::vector stackedValues(depthValues.size(), 0.0); + + std::vector stackedCurves = wellLogTrack->visibleStackedCurves(); + double zPos = -0.1; + for ( RimWellFlowRateCurve * stCurve: stackedCurves ) + { + std::vector values = stCurve->curveData()->xPlotValues(); + for ( size_t i = 0; i < values.size(); ++i ) + { + stackedValues[i+1] += values[i]; + } + + if ( stCurve == this ) break; + zPos -= 1.0; + } + + + m_qwtPlotCurve->setSamples(stackedValues.data(), depthValues.data(), static_cast(depthValues.size())); + + std::vector< std::pair > polyLineStartStopIndices = m_curveData->polylineStartStopIndices(); + polyLineStartStopIndices.front().second += 1; + m_qwtPlotCurve->setLineSegmentStartStopIndices(polyLineStartStopIndices); + + m_qwtPlotCurve->setZ(zPos); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.h b/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.h index d92cbe2347..1fc4b02ee2 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.h @@ -39,6 +39,7 @@ public: virtual ~RimWellFlowRateCurve(); void setFlowValues(const QString& tracerName , const std::vector& measuredDepths, const std::vector& flowRates); + void updateStackedPlotData(); virtual QString wellName() const override; virtual QString wellLogChannelName() const override; @@ -46,6 +47,7 @@ public: protected: virtual QString createCurveAutoName() override; virtual void onLoadDataAndUpdate() override; + virtual void updateCurveAppearance() override; private: RimWellAllocationPlot* wellAllocationPlot() const; diff --git a/ApplicationCode/ProjectDataModel/RimPlotCurve.h b/ApplicationCode/ProjectDataModel/RimPlotCurve.h index 599431c181..775f076cb4 100644 --- a/ApplicationCode/ProjectDataModel/RimPlotCurve.h +++ b/ApplicationCode/ProjectDataModel/RimPlotCurve.h @@ -86,7 +86,7 @@ protected: virtual void onLoadDataAndUpdate() = 0; void updateCurvePresentation(); - void updateCurveAppearance(); + virtual void updateCurveAppearance(); void updateOptionSensitivity(); diff --git a/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp b/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp index 486b8bc51f..8da63e6517 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp @@ -34,6 +34,7 @@ #include "qwt_scale_engine.h" #include +#include "RimWellFlowRateCurve.h" #define RI_LOGPLOTTRACK_MINX_DEFAULT -10.0 #define RI_LOGPLOTTRACK_MAXX_DEFAULT 100.0 @@ -311,6 +312,9 @@ void RimWellLogTrack::updateXZoomAndParentPlotDepthZoom() //-------------------------------------------------------------------------------------------------- void RimWellLogTrack::updateXZoom() { + std::vector stackCurves = visibleStackedCurves(); + for (RimWellFlowRateCurve* stCurve: stackCurves) stCurve->updateStackedPlotData(); + if (!m_isAutoScaleXEnabled()) { m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax); @@ -459,3 +463,21 @@ void RimWellLogTrack::setLogarithmicScale(bool enable) updateAxisScaleEngine(); computeAndSetXRangeMinForLogarithmicScale(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellLogTrack::visibleStackedCurves() +{ + std::vector stackedCurves; + for (RimWellLogCurve* curve: curves) + { + if (curve && curve->isCurveVisible() ) + { + RimWellFlowRateCurve* wfrCurve = dynamic_cast(curve); + if (wfrCurve) stackedCurves.push_back(wfrCurve); + } + } + + return stackedCurves; +} diff --git a/ApplicationCode/ProjectDataModel/RimWellLogTrack.h b/ApplicationCode/ProjectDataModel/RimWellLogTrack.h index fb23a715ea..2d834791da 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogTrack.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogTrack.h @@ -29,6 +29,7 @@ class RimWellLogCurve; class RiuWellLogTrack; +class RimWellFlowRateCurve; class QwtPlotCurve; @@ -66,6 +67,7 @@ public: void setLogarithmicScale(bool enable); + std::vector visibleStackedCurves(); protected: // Overridden PDM methods virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); diff --git a/ApplicationCode/ReservoirDataModel/RigAccWellFlowCalculator.cpp b/ApplicationCode/ReservoirDataModel/RigAccWellFlowCalculator.cpp index 08ab74d23f..259ff0bade 100644 --- a/ApplicationCode/ReservoirDataModel/RigAccWellFlowCalculator.cpp +++ b/ApplicationCode/ReservoirDataModel/RigAccWellFlowCalculator.cpp @@ -120,7 +120,11 @@ void RigAccWellFlowCalculator::calculateAccumulatedFlowPrConnection(size_t branc size_t tracerIdx = 0; for ( const auto & tracerFractionIt: (*m_tracerCellFractionValues) ) { - accFlow[tracerIdx] += (*tracerFractionIt.second)[resCellIndex] * branchCells[clSegIdx].flowRate(); + double cellTracerFraction = (*tracerFractionIt.second)[resCellIndex]; + if (cellTracerFraction != HUGE_VAL && cellTracerFraction == cellTracerFraction) + { + accFlow[tracerIdx] += (*tracerFractionIt.second)[resCellIndex] * branchCells[clSegIdx].flowRate(); + } tracerIdx++; } }