diff --git a/ApplicationCode/ProjectDataModel/Flow/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/Flow/CMakeLists_files.cmake index e0d6fb0abe..4bfb57b9db 100644 --- a/ApplicationCode/ProjectDataModel/Flow/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/Flow/CMakeLists_files.cmake @@ -9,6 +9,7 @@ ${CEE_CURRENT_LIST_DIR}RimFlowDiagSolution.h ${CEE_CURRENT_LIST_DIR}RimFlowPlotCollection.h ${CEE_CURRENT_LIST_DIR}RimWellAllocationPlot.h ${CEE_CURRENT_LIST_DIR}RimTotalWellAllocationPlot.h +${CEE_CURRENT_LIST_DIR}RimTofAccumulatedPhaseFractionsPlot.h ${CEE_CURRENT_LIST_DIR}RimWellFlowRateCurve.h ${CEE_CURRENT_LIST_DIR}RimWellAllocationPlotLegend.h ${CEE_CURRENT_LIST_DIR}RimFlowCharacteristicsPlot.h @@ -19,6 +20,7 @@ ${CEE_CURRENT_LIST_DIR}RimFlowDiagSolution.cpp ${CEE_CURRENT_LIST_DIR}RimFlowPlotCollection.cpp ${CEE_CURRENT_LIST_DIR}RimWellAllocationPlot.cpp ${CEE_CURRENT_LIST_DIR}RimTotalWellAllocationPlot.cpp +${CEE_CURRENT_LIST_DIR}RimTofAccumulatedPhaseFractionsPlot.cpp ${CEE_CURRENT_LIST_DIR}RimWellFlowRateCurve.cpp ${CEE_CURRENT_LIST_DIR}RimWellAllocationPlotLegend.cpp ${CEE_CURRENT_LIST_DIR}RimFlowCharacteristicsPlot.cpp diff --git a/ApplicationCode/ProjectDataModel/Flow/RimTofAccumulatedPhaseFractionsPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimTofAccumulatedPhaseFractionsPlot.cpp new file mode 100644 index 0000000000..20d22dc76f --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Flow/RimTofAccumulatedPhaseFractionsPlot.cpp @@ -0,0 +1,216 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimTofAccumulatedPhaseFractionsPlot.h" + +#include "RiaApplication.h" + +#include "RimEclipseView.h" +#include "RimEclipseWell.h" +#include "RimEclipseWellCollection.h" +#include "RimWellAllocationPlot.h" + +#include "RigSingleWellResultsData.h" +#include "RigTofAccumulatedPhaseFractionsCalculator.h" + +#include "RimWellLogPlot.h" +#include "RimWellLogTrack.h" + +#include "RiuMainPlotWindow.h" +#include "RiuTofAccumulatedPhaseFractionsPlot.h" +#include "RiuWellAllocationPlot.h" + +#include "cvfColor3.h" + + +CAF_PDM_SOURCE_INIT(RimTofAccumulatedPhaseFractionsPlot, "TofAccumulatedPhaseFractionsPlot"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimTofAccumulatedPhaseFractionsPlot::RimTofAccumulatedPhaseFractionsPlot() +{ + CAF_PDM_InitObject("Cumulative Saturation by Time of Flight", ":/WellAllocPie16x16.png", "", ""); + + CAF_PDM_InitField(&m_userName, "PlotDescription", QString("Cumulative Saturation by Time of Flight"), "Name", "", "", ""); + m_userName.uiCapability()->setUiReadOnly(true); + + CAF_PDM_InitField(&m_showPlotTitle, "ShowPlotTitle", true, "Show Plot Title", "", "", ""); + m_showWindow = false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimTofAccumulatedPhaseFractionsPlot::~RimTofAccumulatedPhaseFractionsPlot() +{ + removeMdiWindowFromMdiArea(); + + deleteViewWidget(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTofAccumulatedPhaseFractionsPlot::deleteViewWidget() +{ + if (m_tofAccumulatedPhaseFractionsPlotWidget) + { + m_tofAccumulatedPhaseFractionsPlotWidget->deleteLater(); + m_tofAccumulatedPhaseFractionsPlotWidget = nullptr; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTofAccumulatedPhaseFractionsPlot::reloadFromWell() +{ + loadDataAndUpdate(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseResultCase* RimTofAccumulatedPhaseFractionsPlot::resultCase() +{ + RimWellAllocationPlot* allocationPlot; + firstAncestorOrThisOfTypeAsserted(allocationPlot); + + return allocationPlot->rimCase(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimTofAccumulatedPhaseFractionsPlot::tracerName() +{ + RimWellAllocationPlot* allocationPlot; + firstAncestorOrThisOfTypeAsserted(allocationPlot); + + return allocationPlot->wellName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimTofAccumulatedPhaseFractionsPlot::timeStep() +{ + RimWellAllocationPlot* allocationPlot; + firstAncestorOrThisOfTypeAsserted(allocationPlot); + + return static_cast(allocationPlot->timeStep()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* RimTofAccumulatedPhaseFractionsPlot::viewWidget() +{ + return m_tofAccumulatedPhaseFractionsPlotWidget; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTofAccumulatedPhaseFractionsPlot::zoomAll() +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTofAccumulatedPhaseFractionsPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + RimViewWindow::fieldChangedByUi(changedField, oldValue, newValue); + + if (changedField == &m_userName || + changedField == &m_showPlotTitle) + { + updateMdiWindowTitle(); + } + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QImage RimTofAccumulatedPhaseFractionsPlot::snapshotWindowContent() +{ + QImage image; + + // TODO + + return image; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTofAccumulatedPhaseFractionsPlot::setDescription(const QString& description) +{ + m_userName = description; + this->updateMdiWindowTitle(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimTofAccumulatedPhaseFractionsPlot::description() const +{ + return m_userName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTofAccumulatedPhaseFractionsPlot::loadDataAndUpdate() +{ + updateMdiWindowVisibility(); + + if (m_tofAccumulatedPhaseFractionsPlotWidget) + { + + RigTofAccumulatedPhaseFractionsCalculator calc(resultCase(), tracerName(), timeStep()); + + const std::vector& xValues = calc.sortedUniqueTOFValues(); + const std::vector& watValues = calc.accumulatedPhaseFractionsSwat(); + const std::vector& oilValues = calc.accumulatedPhaseFractionsSoil(); + const std::vector& gasValues = calc.accumulatedPhaseFractionsSgas(); + + m_tofAccumulatedPhaseFractionsPlotWidget->setSamples(xValues, watValues, oilValues, gasValues); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* RimTofAccumulatedPhaseFractionsPlot::createViewWidget(QWidget* mainWindowParent) +{ + if (!m_tofAccumulatedPhaseFractionsPlotWidget) + { + m_tofAccumulatedPhaseFractionsPlotWidget = new RiuTofAccumulatedPhaseFractionsPlot(this, mainWindowParent); + } + return m_tofAccumulatedPhaseFractionsPlotWidget; +} + + diff --git a/ApplicationCode/ProjectDataModel/Flow/RimTofAccumulatedPhaseFractionsPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimTofAccumulatedPhaseFractionsPlot.h new file mode 100644 index 0000000000..5f8f305dfe --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Flow/RimTofAccumulatedPhaseFractionsPlot.h @@ -0,0 +1,90 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + + +#include "RimViewWindow.h" + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +#include + +#include + +class RiuWellAllocationPlot; +class RimEclipseWell; +class RimWellLogPlot; +class RiuTofAccumulatedPhaseFractionsPlot; +class RimEclipseResultCase; + +namespace caf { + class PdmOptionItemInfo; +} + +namespace cvf { + class Color3f; +} + + +//================================================================================================== +/// +/// +//================================================================================================== +class RimTofAccumulatedPhaseFractionsPlot : public RimViewWindow +{ + CAF_PDM_HEADER_INIT; + +public: + RimTofAccumulatedPhaseFractionsPlot(); + virtual ~RimTofAccumulatedPhaseFractionsPlot(); + + void setDescription(const QString& description); + QString description() const; + + // RimViewWindow overrides + + virtual QWidget* viewWidget() override; + virtual void zoomAll() override; + virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; + virtual void deleteViewWidget() override; + + void reloadFromWell(); + + RimEclipseResultCase* resultCase(); + QString tracerName(); + size_t timeStep(); + +protected: + // RimViewWindow overrides + + virtual void loadDataAndUpdate() override; + virtual QImage snapshotWindowContent() override; + + // Overridden PDM methods + virtual caf::PdmFieldHandle* userDescriptionField() { return &m_userName; } + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + +private: + caf::PdmField m_showPlotTitle; + caf::PdmField m_userName; + + QPointer m_tofAccumulatedPhaseFractionsPlotWidget; +}; diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp index 88d747e6ea..532e79e344 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp @@ -41,6 +41,7 @@ #include "RimWellLogPlot.h" #include "RimWellLogTrack.h" #include "RimWellAllocationPlotLegend.h" +#include "RimTofAccumulatedPhaseFractionsPlot.h" #include "RiuMainPlotWindow.h" #include "RiuWellAllocationPlot.h" @@ -102,6 +103,10 @@ RimWellAllocationPlot::RimWellAllocationPlot() m_wellAllocationPlotLegend.uiCapability()->setUiHidden(true); m_wellAllocationPlotLegend = new RimWellAllocationPlotLegend; + CAF_PDM_InitFieldNoDefault(&m_tofAccumulatedPhaseFractionsPlot, "TofAccumulatedPhaseFractionsPlot", "TOF Accumulated Phase Fractions", "", "", ""); + m_tofAccumulatedPhaseFractionsPlot.uiCapability()->setUiHidden(true); + m_tofAccumulatedPhaseFractionsPlot = new RimTofAccumulatedPhaseFractionsPlot; + this->setAsPlotMdiWindow(); } @@ -114,6 +119,7 @@ RimWellAllocationPlot::~RimWellAllocationPlot() delete m_accumulatedWellFlowPlot(); delete m_totalWellAllocationPlot(); + delete m_tofAccumulatedPhaseFractionsPlot(); deleteViewWidget(); } @@ -311,6 +317,10 @@ void RimWellAllocationPlot::updateFromWell() m_totalWellAllocationPlot->updateConnectedEditors(); accumulatedWellFlowPlot()->updateConnectedEditors(); + + m_tofAccumulatedPhaseFractionsPlot->reloadFromWell(); + m_tofAccumulatedPhaseFractionsPlot->updateConnectedEditors(); + if (m_wellAllocationPlotWidget) m_wellAllocationPlotWidget->updateGeometry(); } @@ -523,6 +533,14 @@ RimTotalWellAllocationPlot* RimWellAllocationPlot::totalWellFlowPlot() return m_totalWellAllocationPlot(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimTofAccumulatedPhaseFractionsPlot * RimWellAllocationPlot::tofAccumulatedPhaseFractionsPlot() +{ + return m_tofAccumulatedPhaseFractionsPlot(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.h index b8261e7d05..2f28e2e7ff 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.h @@ -35,6 +35,7 @@ class RimWellAllocationPlotLegend; class RimWellLogPlot; class RiuWellAllocationPlot; class RimWellLogTrack; +class RimTofAccumulatedPhaseFractionsPlot; class RigSingleWellResultsData; namespace cvf { @@ -72,6 +73,7 @@ public: RimWellLogPlot* accumulatedWellFlowPlot(); RimTotalWellAllocationPlot* totalWellFlowPlot(); + RimTofAccumulatedPhaseFractionsPlot* tofAccumulatedPhaseFractionsPlot(); caf::PdmObject* plotLegend(); RimEclipseResultCase* rimCase(); int timeStep(); @@ -134,4 +136,5 @@ private: caf::PdmChildField m_accumulatedWellFlowPlot; caf::PdmChildField m_totalWellAllocationPlot; caf::PdmChildField m_wellAllocationPlotLegend; + caf::PdmChildField m_tofAccumulatedPhaseFractionsPlot; }; diff --git a/ApplicationCode/ReservoirDataModel/RigTofAccumulatedPhaseFractionsCalculator.cpp b/ApplicationCode/ReservoirDataModel/RigTofAccumulatedPhaseFractionsCalculator.cpp index 1c3d0f7575..ac829db45b 100644 --- a/ApplicationCode/ReservoirDataModel/RigTofAccumulatedPhaseFractionsCalculator.cpp +++ b/ApplicationCode/ReservoirDataModel/RigTofAccumulatedPhaseFractionsCalculator.cpp @@ -55,7 +55,7 @@ RigTofAccumulatedPhaseFractionsCalculator::RigTofAccumulatedPhaseFractionsCalcul const std::vector* swatResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexSwat, timestep)); const std::vector* soilResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexSoil, timestep)); const std::vector* sgasResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexSgas, timestep)); - const std::vector* porvResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexPorv, timestep)); + const std::vector* porvResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexPorv, 0)); RimFlowDiagSolution* flowDiagSolution = caseToApply->defaultFlowDiagSolution(); @@ -77,10 +77,10 @@ RigTofAccumulatedPhaseFractionsCalculator::RigTofAccumulatedPhaseFractionsCalcul swatResults, soilResults, sgasResults, + m_tofInIncreasingOrder, m_accumulatedPhaseFractionSwat, m_accumulatedPhaseFractionSoil, - m_accumulatedPhaseFractionSgas, - m_tofInIncreasingOrder); + m_accumulatedPhaseFractionSgas); } //-------------------------------------------------------------------------------------------------- @@ -98,10 +98,16 @@ void RigTofAccumulatedPhaseFractionsCalculator::sortTofAndCalculateAccPhaseFract std::vector& accumulatedPhaseFractionSgas) { + if (tofData == nullptr || fractionData == nullptr) + { + return; + } + std::map > tofAndIndexMap; for (int i = 0; i < static_cast(tofData->size()); i++) { + if ((*tofData)[i] == HUGE_VAL) continue; std::vector vectorOfIndexes; vectorOfIndexes.push_back(i); diff --git a/ApplicationCode/UserInterface/CMakeLists_files.cmake b/ApplicationCode/UserInterface/CMakeLists_files.cmake index 8658fd36fb..b74b3e449f 100644 --- a/ApplicationCode/UserInterface/CMakeLists_files.cmake +++ b/ApplicationCode/UserInterface/CMakeLists_files.cmake @@ -33,6 +33,7 @@ ${CEE_CURRENT_LIST_DIR}RiuSelectionChangedHandler.h ${CEE_CURRENT_LIST_DIR}RiuSelectionManager.h ${CEE_CURRENT_LIST_DIR}RiuSimpleHistogramWidget.h ${CEE_CURRENT_LIST_DIR}RiuSummaryQwtPlot.h +${CEE_CURRENT_LIST_DIR}RiuTofAccumulatedPhaseFractionsPlot.h ${CEE_CURRENT_LIST_DIR}RiuToolTipMenu.h ${CEE_CURRENT_LIST_DIR}RiuTreeViewEventFilter.h ${CEE_CURRENT_LIST_DIR}RiuViewer.h @@ -79,6 +80,7 @@ ${CEE_CURRENT_LIST_DIR}RiuSelectionChangedHandler.cpp ${CEE_CURRENT_LIST_DIR}RiuSelectionManager.cpp ${CEE_CURRENT_LIST_DIR}RiuSimpleHistogramWidget.cpp ${CEE_CURRENT_LIST_DIR}RiuSummaryQwtPlot.cpp +${CEE_CURRENT_LIST_DIR}RiuTofAccumulatedPhaseFractionsPlot.cpp ${CEE_CURRENT_LIST_DIR}RiuToolTipMenu.cpp ${CEE_CURRENT_LIST_DIR}RiuTreeViewEventFilter.cpp ${CEE_CURRENT_LIST_DIR}RiuViewer.cpp @@ -119,6 +121,7 @@ ${CEE_CURRENT_LIST_DIR}RiuWellLogPlot.h ${CEE_CURRENT_LIST_DIR}RiuWellLogTrack.h ${CEE_CURRENT_LIST_DIR}RiuRecentFileActionProvider.h ${CEE_CURRENT_LIST_DIR}RiuSummaryQwtPlot.h +${CEE_CURRENT_LIST_DIR}RiuTofAccumulatedPhaseFractionsPlot.h ${CEE_CURRENT_LIST_DIR}RiuQwtScalePicker.h ${CEE_CURRENT_LIST_DIR}RiuQwtPlotWheelZoomer.h ${CEE_CURRENT_LIST_DIR}RiuEditPerforationCollectionWidget.h diff --git a/ApplicationCode/UserInterface/RiuNightchartsWidget.cpp b/ApplicationCode/UserInterface/RiuNightchartsWidget.cpp index 31557fa5e6..0acb4d4119 100644 --- a/ApplicationCode/UserInterface/RiuNightchartsWidget.cpp +++ b/ApplicationCode/UserInterface/RiuNightchartsWidget.cpp @@ -121,7 +121,7 @@ QSize RiuNightchartsWidget::sizeHint() const if (m_showPie) { - int maxPieSize = 180; + int maxPieSize = 350; widthHint = widthHint + maxPieSize; heightHint = heightHint > maxPieSize ? heightHint : maxPieSize; diff --git a/ApplicationCode/UserInterface/RiuTofAccumulatedPhaseFractionsPlot.cpp b/ApplicationCode/UserInterface/RiuTofAccumulatedPhaseFractionsPlot.cpp new file mode 100644 index 0000000000..9544918ee3 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuTofAccumulatedPhaseFractionsPlot.cpp @@ -0,0 +1,281 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiuTofAccumulatedPhaseFractionsPlot.h" + +#include "RimContextCommandBuilder.h" +#include "RimTofAccumulatedPhaseFractionsPlot.h" + +#include "RiuMainWindow.h" + +#include "cafSelectionManager.h" + +#include "cvfAssert.h" + +#include "qwt_legend.h" +#include "qwt_plot_grid.h" + +#include +#include +#include +#include + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuTofAccumulatedPhaseFractionsPlot::RiuTofAccumulatedPhaseFractionsPlot(RimTofAccumulatedPhaseFractionsPlot* plotDefinition, QWidget* parent) + : QwtPlot(parent), m_watCurve(nullptr), m_oilCurve(nullptr), m_gasCurve(nullptr) +{ + Q_ASSERT(plotDefinition); + m_plotDefinition = plotDefinition; + + QPalette newPalette(palette()); + newPalette.setColor(QPalette::Background, Qt::white); + setPalette(newPalette); + + setAutoFillBackground(true); + setDefaults(); + setTitle("Cumulative Saturation by Time of Flight"); + + m_watCurve = new QwtPlotCurve; + setCurveColor(m_watCurve, QColor(0, 83, 138)); + m_watCurve->setZ(0.9); + m_watCurve->setTitle("Water"); + m_watCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true); + + m_oilCurve = new QwtPlotCurve; + setCurveColor(m_oilCurve, QColor(127, 24, 13)); + m_oilCurve->setZ(0.8); + m_oilCurve->setTitle("Oil"); + m_oilCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true); + + m_gasCurve = new QwtPlotCurve; + setCurveColor(m_gasCurve, QColor(59, 84, 23)); + m_gasCurve->setZ(0.7); + m_gasCurve->setTitle("Gas"); + m_gasCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true); + + m_watCurve->attach(this); + m_oilCurve->attach(this); + m_gasCurve->attach(this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuTofAccumulatedPhaseFractionsPlot::~RiuTofAccumulatedPhaseFractionsPlot() +{ + if (m_plotDefinition) + { + m_plotDefinition->handleMdiWindowClosed(); + } + + if (m_watCurve) + { + m_watCurve->detach(); + delete m_watCurve; + m_watCurve = nullptr; + } + + if (m_oilCurve) + { + m_oilCurve->detach(); + delete m_oilCurve; + m_oilCurve = nullptr; + } + + if (m_gasCurve) + { + m_gasCurve->detach(); + delete m_gasCurve; + m_gasCurve = nullptr; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QSize RiuTofAccumulatedPhaseFractionsPlot::sizeHint() const +{ + return QSize(350, 250); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RiuTofAccumulatedPhaseFractionsPlot::heightForWidth(int w) const +{ + return static_cast(static_cast(w) / 1.1); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimTofAccumulatedPhaseFractionsPlot* RiuTofAccumulatedPhaseFractionsPlot::ownerPlotDefinition() +{ + return m_plotDefinition; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimViewWindow* RiuTofAccumulatedPhaseFractionsPlot::ownerViewWindow() const +{ + return m_plotDefinition; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuTofAccumulatedPhaseFractionsPlot::setSamples(std::vector xSamples, + std::vector watValues, + std::vector oilValues, + std::vector gasValues) +{ + m_xValues.clear(); + m_watValues.clear(); + m_oilValues.clear(); + m_gasValues.clear(); + + m_watValues.swap(watValues); + for (size_t i = 0; i < xSamples.size(); ++i) + { + m_xValues.push_back(xSamples[i] / 365.2425); + m_oilValues.push_back(oilValues[i] + m_watValues[i]); + m_gasValues.push_back(gasValues[i] + m_oilValues[i]); + } + m_watCurve->setSamples(m_xValues.data(), m_watValues.data(), static_cast(m_xValues.size())); + m_oilCurve->setSamples(m_xValues.data(), m_oilValues.data(), static_cast(m_xValues.size())); + m_gasCurve->setSamples(m_xValues.data(), m_gasValues.data(), static_cast(m_xValues.size())); + + auto maxXVal = std::max_element(m_xValues.begin(), m_xValues.end()); + + if (maxXVal != m_xValues.end()) + { + setAxisScale(QwtPlot::xBottom, 0, *maxXVal); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuTofAccumulatedPhaseFractionsPlot::setDefaults() +{ + setCommonPlotBehaviour(this); + setAxisTitle(QwtPlot::xBottom, "Years"); + + enableAxis(QwtPlot::xBottom, true); + enableAxis(QwtPlot::yLeft, true); + setAxisScale(QwtPlot::yLeft, 0, 1, 0.2); + enableAxis(QwtPlot::xTop, false); + enableAxis(QwtPlot::yRight, false); + + setAxisMaxMinor(QwtPlot::xBottom, 2); + setAxisMaxMinor(QwtPlot::yLeft, 3); + + QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + sizePolicy.setHeightForWidth(true); + setSizePolicy(sizePolicy); + updateGeometry(); + + // The legend will be deleted in the destructor of the plot or when + // another legend is inserted. + QwtLegend* legend = new QwtLegend(this); + this->insertLegend(legend, BottomLegend); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuTofAccumulatedPhaseFractionsPlot::setCommonPlotBehaviour(QwtPlot* plot) +{ + // Plot background and frame look + + QPalette newPalette(plot->palette()); + newPalette.setColor(QPalette::Background, Qt::white); + plot->setPalette(newPalette); + + plot->setAutoFillBackground(true); + plot->setCanvasBackground(Qt::white); + + QFrame* canvasFrame = dynamic_cast(plot->canvas()); + if (canvasFrame) + { + canvasFrame->setFrameShape(QFrame::NoFrame); + } + + // Grid + + QwtPlotGrid* grid = new QwtPlotGrid; + grid->attach(plot); + QPen gridPen(Qt::SolidLine); + gridPen.setColor(Qt::lightGray); + grid->setPen(gridPen); + + // Axis number font + QFont axisFont = plot->axisFont(QwtPlot::xBottom); + axisFont.setPixelSize(11); + + plot->setAxisFont(QwtPlot::xBottom, axisFont); + plot->setAxisFont(QwtPlot::xTop, axisFont); + plot->setAxisFont(QwtPlot::yLeft, axisFont); + plot->setAxisFont(QwtPlot::yRight, axisFont); + + // Axis title font + QwtText axisTitle = plot->axisTitle(QwtPlot::xBottom); + QFont axisTitleFont = axisTitle.font(); + axisTitleFont.setPixelSize(11); + axisTitleFont.setBold(false); + axisTitle.setFont(axisTitleFont); + axisTitle.setRenderFlags(Qt::AlignRight); + + plot->setAxisTitle(QwtPlot::xBottom, axisTitle); + plot->setAxisTitle(QwtPlot::xTop, axisTitle); + plot->setAxisTitle(QwtPlot::yLeft, axisTitle); + plot->setAxisTitle(QwtPlot::yRight, axisTitle); + + // Enable mouse tracking and event filter + + plot->canvas()->setMouseTracking(true); + plot->canvas()->installEventFilter(plot); +// plot->plotLayout()->setAlignCanvasToScales(true); + +// new RiuQwtCurvePointTracker(plot, true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuTofAccumulatedPhaseFractionsPlot::setCurveColor(QwtPlotCurve* curve, QColor color) +{ + curve->setBrush(QBrush(color)); + + QLinearGradient gradient; + gradient.setCoordinateMode(QGradient::StretchToDeviceMode); + gradient.setColorAt(0, color.darker(110)); + gradient.setColorAt(0.15, color); + gradient.setColorAt(0.25, color); + gradient.setColorAt(0.4, color.darker(110)); + gradient.setColorAt(0.6, color); + gradient.setColorAt(0.8, color.darker(110)); + gradient.setColorAt(1, color); + curve->setBrush(gradient); +} diff --git a/ApplicationCode/UserInterface/RiuTofAccumulatedPhaseFractionsPlot.h b/ApplicationCode/UserInterface/RiuTofAccumulatedPhaseFractionsPlot.h new file mode 100644 index 0000000000..d7a07b9687 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuTofAccumulatedPhaseFractionsPlot.h @@ -0,0 +1,78 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmPointer.h" + +#include "qwt_plot.h" +#include "qwt_plot_curve.h" + +#include +#include +#include + + +#include "RiuInterfaceToViewWindow.h" + +class RimTofAccumulatedPhaseFractionsPlot; + +//================================================================================================== +// +// RiuTofAccumulatedPhaseFractionsPlot +// +//================================================================================================== +class RiuTofAccumulatedPhaseFractionsPlot : public QwtPlot, public RiuInterfaceToViewWindow +{ + Q_OBJECT + +public: + RiuTofAccumulatedPhaseFractionsPlot(RimTofAccumulatedPhaseFractionsPlot* plotDefinition, QWidget* parent = NULL); + virtual ~RiuTofAccumulatedPhaseFractionsPlot(); + + RimTofAccumulatedPhaseFractionsPlot* ownerPlotDefinition(); + virtual RimViewWindow* ownerViewWindow() const override; + + void setSamples(std::vector xSamples, + std::vector watValues, + std::vector oilValues, + std::vector gasValues); + +protected: + virtual QSize sizeHint() const override; + virtual int heightForWidth(int w) const override; + +private: + void setDefaults(); + static void setCommonPlotBehaviour(QwtPlot* plot); + void setCurveColor(QwtPlotCurve* curve, QColor color); + +private: + caf::PdmPointer m_plotDefinition; + + QwtPlotCurve* m_watCurve; + QwtPlotCurve* m_oilCurve; + QwtPlotCurve* m_gasCurve; + + std::vector m_watValues; + std::vector m_oilValues; + std::vector m_gasValues; + std::vector m_xValues; +}; + diff --git a/ApplicationCode/UserInterface/RiuWellAllocationPlot.cpp b/ApplicationCode/UserInterface/RiuWellAllocationPlot.cpp index 95fc7e0f45..c7b7b21e2b 100644 --- a/ApplicationCode/UserInterface/RiuWellAllocationPlot.cpp +++ b/ApplicationCode/UserInterface/RiuWellAllocationPlot.cpp @@ -25,6 +25,7 @@ #include "RimWellAllocationPlot.h" #include "RimWellLogPlot.h" #include "RimWellLogTrack.h" +#include "RimTofAccumulatedPhaseFractionsPlot.h" #include "RiuContextMenuLauncher.h" #include "RiuNightchartsWidget.h" @@ -89,7 +90,8 @@ RiuWellAllocationPlot::RiuWellAllocationPlot(RimWellAllocationPlot* plotDefiniti new RiuPlotObjectPicker(totalFlowAllocationWidget, m_plotDefinition->totalWellFlowPlot()); new RiuContextMenuLauncher(totalFlowAllocationWidget, commandIds); - rightColumnLayout->addWidget(totalFlowAllocationWidget); + rightColumnLayout->addWidget(totalFlowAllocationWidget, Qt::AlignTop); + rightColumnLayout->addWidget(m_plotDefinition->tofAccumulatedPhaseFractionsPlot()->createViewWidget(this), Qt::AlignTop); rightColumnLayout->addStretch(); QWidget* wellFlowWidget = m_plotDefinition->accumulatedWellFlowPlot()->createViewWidget(this);