Added first cut extraction and plotting of RelPerm plots. Also added skeleton implementation of extraction and plotting of PVT plots. #1991, #1992, #1992, #2014

This commit is contained in:
Bjørn Erik Jensen 2017-10-27 09:38:24 +02:00 committed by sigurdp
parent 3ef2ec3f33
commit 71caab54ec
11 changed files with 937 additions and 14 deletions

View File

@ -28,6 +28,9 @@
#include "RigFlowDiagInterfaceTools.h"
#include "opm/flowdiagnostics/DerivedQuantities.hpp"
#include "opm/utility/ECLSaturationFunc.hpp"
#include "opm/utility/ECLPvtCurveCollection.hpp"
#include "RimEclipseCase.h"
#include "RimEclipseResultCase.h"
#include "RimFlowDiagSolution.h"
@ -119,6 +122,9 @@ public:
m_hasUnifiedRestartFile = false;
m_poreVolume = m_eclGraph->poreVolume();
m_eclSaturationFunc.reset(new Opm::ECLSaturationFunc(*m_eclGraph, initData));
//m_eclPvtCurveCollection.reset(new Opm::ECLPVT::ECLPvtCurveCollection(*m_eclGraph, initData));
}
std::unique_ptr<Opm::ECLGraph> m_eclGraph;
@ -127,6 +133,9 @@ public:
bool m_hasUnifiedRestartFile;
std::vector<Opm::ECLRestartData> m_singleRestartDataTimeSteps;
std::unique_ptr<Opm::ECLRestartData> m_unifiedRestartData;
std::unique_ptr<Opm::ECLSaturationFunc> m_eclSaturationFunc;
// std::unique_ptr<Opm::ECLPVT::ECLPvtCurveCollection> m_eclPvtCurveCollection;
};
@ -219,22 +228,18 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
caf::ProgressInfo progressInfo(8, "Calculating Flow Diagnostics");
if ( m_opmFlowDiagStaticData.isNull() )
{
progressInfo.setProgressDescription("Grid access");
// Get set of files
QString gridFileName = m_eclipseCase->gridFileName();
std::string initFileName = getInitFileName();
if (initFileName.empty()) return result;
m_opmFlowDiagStaticData = new RigOpmFlowDiagStaticData(gridFileName.toStdString(), initFileName);
if (!ensureStaticDataObjectInstanceCreated())
{
return result;
}
progressInfo.incrementProgress();
progressInfo.setProgressDescription("Calculating Connectivities");
CVF_ASSERT(m_opmFlowDiagStaticData.notNull());
const Opm::FlowDiagnostics::ConnectivityGraph connGraph =
Opm::FlowDiagnostics::ConnectivityGraph{ static_cast<int>(m_opmFlowDiagStaticData->m_eclGraph->numCells()),
m_opmFlowDiagStaticData->m_eclGraph->neighbours() };
@ -250,6 +255,7 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
// Look for unified restart file
QStringList m_filesWithSameBaseName;
QString gridFileName = m_eclipseCase->gridFileName();
if ( !RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(gridFileName, &m_filesWithSameBaseName) ) return result;
QString restartFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_UNIFIED_RESTART_FILE);
@ -528,6 +534,24 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
return result; // Relying on implicit move constructor
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFlowDiagSolverInterface::ensureStaticDataObjectInstanceCreated()
{
if (m_opmFlowDiagStaticData.isNull())
{
// Get set of files
QString gridFileName = m_eclipseCase->gridFileName();
std::string initFileName = getInitFileName();
if (initFileName.empty()) return false;
m_opmFlowDiagStaticData = new RigOpmFlowDiagStaticData(gridFileName.toStdString(), initFileName);
}
return m_opmFlowDiagStaticData.notNull() ? true : false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -569,6 +593,102 @@ RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagSolverInte
return result;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigFlowDiagSolverInterface::RelPermCurve> RigFlowDiagSolverInterface::calculateRelPermCurvesForActiveCell(size_t activeCellIndex)
{
std::vector<RelPermCurve> retCurveArr;
if (!ensureStaticDataObjectInstanceCreated())
{
return retCurveArr;
}
CVF_ASSERT(m_opmFlowDiagStaticData.notNull());
CVF_ASSERT(m_opmFlowDiagStaticData->m_eclSaturationFunc);
const Opm::ECLSaturationFunc::RawCurve krw { Opm::ECLSaturationFunc::RawCurve::Function::RelPerm, Opm::ECLSaturationFunc::RawCurve::SubSystem::OilWater, Opm::ECLPhaseIndex::Aqua }; // water rel-perm in oil-water system
const Opm::ECLSaturationFunc::RawCurve krg { Opm::ECLSaturationFunc::RawCurve::Function::RelPerm, Opm::ECLSaturationFunc::RawCurve::SubSystem::OilGas, Opm::ECLPhaseIndex::Vapour }; // gas rel-perm in oil-gas system
const Opm::ECLSaturationFunc::RawCurve krow { Opm::ECLSaturationFunc::RawCurve::Function::RelPerm, Opm::ECLSaturationFunc::RawCurve::SubSystem::OilWater, Opm::ECLPhaseIndex::Liquid }; // oil rel-perm in oil-water system
const Opm::ECLSaturationFunc::RawCurve krog { Opm::ECLSaturationFunc::RawCurve::Function::RelPerm, Opm::ECLSaturationFunc::RawCurve::SubSystem::OilGas, Opm::ECLPhaseIndex::Liquid }; // oil rel-perm in oil-gas system
std::vector<std::pair<RelPermCurve::Ident, std::string>> curveIdentNameArr;
std::vector<Opm::ECLSaturationFunc::RawCurve> satFuncRequests;
curveIdentNameArr.push_back(std::make_pair(RelPermCurve::KRW, "KRW")); satFuncRequests.push_back(krw);
curveIdentNameArr.push_back(std::make_pair(RelPermCurve::KRG, "KRG")); satFuncRequests.push_back(krg);
curveIdentNameArr.push_back(std::make_pair(RelPermCurve::KROW, "KROW")); satFuncRequests.push_back(krow);
curveIdentNameArr.push_back(std::make_pair(RelPermCurve::KROG, "KROG")); satFuncRequests.push_back(krog);
const bool useEPS = true;
std::vector<Opm::FlowDiagnostics::Graph> graphArr = m_opmFlowDiagStaticData->m_eclSaturationFunc->getSatFuncCurve(satFuncRequests, static_cast<int>(activeCellIndex), useEPS);
for (size_t i = 0; i < graphArr.size(); i++)
{
const Opm::FlowDiagnostics::Graph& srcGraph = graphArr[i];
if (srcGraph.first.size() > 0)
{
const RelPermCurve::Ident curveIdent = curveIdentNameArr[i].first;
const std::string curveName = curveIdentNameArr[i].second;
std::vector<double> xVals = srcGraph.first;
const std::vector<double>& yVals = srcGraph.second;
// According to Issue https://github.com/OPM/ResInsight/issues/2014,
// we need to modify the x values to be 1 - x
if (curveIdent == RelPermCurve::KROW || curveIdent == RelPermCurve::KROG)
{
for (size_t i = 0; i < xVals.size(); i++)
{
xVals[i] = 1.0 - xVals[i];
}
}
retCurveArr.push_back({ curveIdent, curveName, xVals, yVals});
}
}
//{
// // Dummy test data until we can get real data
// std::vector<double> dummyX { 0.1, 0.3, 0.5, 0.7, 0.9 };
// std::vector<double> dummyY { 0.1, 0.3, 0.3, 1.7, 1.9 };
// retCurveArr.push_back({ RelPermCurve::PCOG, "PCOG", dummyX, dummyX });
// retCurveArr.push_back({ RelPermCurve::PCOW, "PCOW", dummyX, dummyY });
//}
return retCurveArr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigFlowDiagSolverInterface::PvtCurve> RigFlowDiagSolverInterface::calculatePvtFvfCurvesForActiveCell(size_t activeCellIndex)
{
std::vector<PvtCurve> retCurveArr;
if (!ensureStaticDataObjectInstanceCreated())
{
return retCurveArr;
}
//CVF_ASSERT(m_opmFlowDiagStaticData.notNull());
//CVF_ASSERT(m_opmFlowDiagStaticData->m_eclPvtCurveCollection);
//{
// Opm::FlowDiagnostics::Graph graph = m_opmFlowDiagStaticData->m_eclPvtCurveCollection->getPvtCurve(Opm::ECLPVT::RawCurve::FVF, Opm::ECLPhaseIndex::Vapour, static_cast<int>(activeCellIndex));
// retCurveDataArr.push_back({ "FVF_Gas", graph.first, graph.second });
//}
//{
// Opm::FlowDiagnostics::Graph graph = m_opmFlowDiagStaticData->m_eclPvtCurveCollection->getPvtCurve(Opm::ECLPVT::RawCurve::FVF, Opm::ECLPhaseIndex::Liquid, static_cast<int>(activeCellIndex));
// retCurveDataArr.push_back({ "FVF_Oil", graph.first, graph.second });
//}
//{
// Opm::FlowDiagnostics::Graph graph = m_opmFlowDiagStaticData->m_eclPvtCurveCollection->getPvtCurve(Opm::ECLPVT::RawCurve::FVF, Opm::ECLPhaseIndex::Aqua, static_cast<int>(activeCellIndex));
// retCurveDataArr.push_back({ "FVF_Water", graph.first, graph.second });
//}
return retCurveArr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -585,7 +705,6 @@ std::string RigFlowDiagSolverInterface::getInitFileName() const
return initFileName.toStdString();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -75,6 +75,26 @@ public:
double m_lorenzCoefficient;
};
struct RelPermCurve
{
enum Ident { KRW, KRG, KROW, KROG, PCOW, PCOG };
Ident ident;
std::string name;
std::vector<double> xVals;
std::vector<double> yVals;
};
struct PvtCurve
{
enum Ident { FVT_OIL, FVT_GAS, FVT_WATER };
Ident ident;
std::string name;
std::vector<double> xVals;
std::vector<double> yVals;
};
public:
explicit RigFlowDiagSolverInterface(RimEclipseResultCase * eclipseCase);
virtual ~RigFlowDiagSolverInterface();
@ -89,8 +109,12 @@ public:
const std::vector<size_t>& selected_cell_indices,
double max_pv_fraction);
std::vector<RelPermCurve> calculateRelPermCurvesForActiveCell(size_t activeCellIndex);
std::vector<PvtCurve> calculatePvtFvfCurvesForActiveCell(size_t activeCellIndex);
private:
std::string getInitFileName() const;
bool ensureStaticDataObjectInstanceCreated();
RimEclipseResultCase * m_eclipseCase;

View File

@ -20,11 +20,13 @@ ${CEE_CURRENT_LIST_DIR}RiuMultiCaseImportDialog.h
${CEE_CURRENT_LIST_DIR}RiuProcessMonitor.h
${CEE_CURRENT_LIST_DIR}RiuProjectPropertyView.h
${CEE_CURRENT_LIST_DIR}RiuPropertyViewTabWidget.h
${CEE_CURRENT_LIST_DIR}RiuPvtPlotPanel.h
${CEE_CURRENT_LIST_DIR}RiuQwtScalePicker.h
${CEE_CURRENT_LIST_DIR}RiuQwtCurvePointTracker.h
${CEE_CURRENT_LIST_DIR}RiuQwtPlotWheelZoomer.h
${CEE_CURRENT_LIST_DIR}RiuQwtPlotZoomer.h
${CEE_CURRENT_LIST_DIR}RiuRecentFileActionProvider.h
${CEE_CURRENT_LIST_DIR}RiuRelativePermeabilityPlotPanel.h
${CEE_CURRENT_LIST_DIR}RiuResultInfoPanel.h
${CEE_CURRENT_LIST_DIR}RiuResultQwtPlot.h
${CEE_CURRENT_LIST_DIR}RiuResultTextBuilder.h
@ -76,10 +78,12 @@ ${CEE_CURRENT_LIST_DIR}RiuMultiCaseImportDialog.cpp
${CEE_CURRENT_LIST_DIR}RiuProcessMonitor.cpp
${CEE_CURRENT_LIST_DIR}RiuProjectPropertyView.cpp
${CEE_CURRENT_LIST_DIR}RiuPropertyViewTabWidget.cpp
${CEE_CURRENT_LIST_DIR}RiuPvtPlotPanel.cpp
${CEE_CURRENT_LIST_DIR}RiuQwtScalePicker.cpp
${CEE_CURRENT_LIST_DIR}RiuQwtCurvePointTracker.cpp
${CEE_CURRENT_LIST_DIR}RiuQwtPlotWheelZoomer.cpp
${CEE_CURRENT_LIST_DIR}RiuRecentFileActionProvider.cpp
${CEE_CURRENT_LIST_DIR}RiuRelativePermeabilityPlotPanel.cpp
${CEE_CURRENT_LIST_DIR}RiuResultInfoPanel.cpp
${CEE_CURRENT_LIST_DIR}RiuResultQwtPlot.cpp
${CEE_CURRENT_LIST_DIR}RiuResultTextBuilder.cpp
@ -126,6 +130,7 @@ list(APPEND QT_MOC_HEADERS
${CEE_CURRENT_LIST_DIR}RiuMainWindowBase.h
${CEE_CURRENT_LIST_DIR}RiuMainWindow.h
${CEE_CURRENT_LIST_DIR}RiuMainPlotWindow.h
${CEE_CURRENT_LIST_DIR}RiuRelativePermeabilityPlotPanel.h
${CEE_CURRENT_LIST_DIR}RiuResultInfoPanel.h
${CEE_CURRENT_LIST_DIR}RiuViewer.h
${CEE_CURRENT_LIST_DIR}RiuProcessMonitor.h

View File

@ -46,6 +46,8 @@
#include "RiuToolTipMenu.h"
#include "RiuTreeViewEventFilter.h"
#include "RiuViewer.h"
#include "RiuRelativePermeabilityPlotPanel.h"
#include "RiuPvtPlotPanel.h"
#include "cafAnimationToolBar.h"
#include "cafCmdExecCommandManager.h"
@ -98,6 +100,8 @@ RiuMainWindow* RiuMainWindow::sm_mainWindowInstance = NULL;
RiuMainWindow::RiuMainWindow()
: m_pdmRoot(NULL),
m_mainViewer(NULL),
m_relPermPlotPanel(NULL),
m_pvtPlotPanel(NULL),
m_windowMenu(NULL),
m_blockSlotSubWindowActivated(false)
{
@ -169,6 +173,8 @@ void RiuMainWindow::cleanupGuiCaseClose()
setResultInfo("");
m_resultQwtPlot->deleteAllCurves();
if (m_relPermPlotPanel) m_relPermPlotPanel->clearPlot();
if (m_pvtPlotPanel) m_pvtPlotPanel->clearPlot();
if (m_pdmUiPropertyView)
{
@ -615,6 +621,28 @@ void RiuMainWindow::createDockPanels()
addDockWidget(Qt::BottomDockWidgetArea, dockPanel);
}
{
QDockWidget* dockPanel = new QDockWidget("Relative Permeability Plot", this);
dockPanel->setObjectName("dockRelativePermeabilityPlotPanel");
dockPanel->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea);
m_relPermPlotPanel = new RiuRelativePermeabilityPlotPanel(dockPanel);
dockPanel->setWidget(m_relPermPlotPanel);
addDockWidget(Qt::BottomDockWidgetArea, dockPanel);
dockPanel->hide();
}
{
QDockWidget* dockPanel = new QDockWidget("PVT Plot", this);
dockPanel->setObjectName("dockPvtPlotPanel");
dockPanel->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea);
m_pvtPlotPanel = new RiuPvtPlotPanel(dockPanel);
dockPanel->setWidget(m_pvtPlotPanel);
addDockWidget(Qt::BottomDockWidgetArea, dockPanel);
dockPanel->hide();
}
{
QDockWidget* dockWidget = new QDockWidget("Messages", this);
dockWidget->setObjectName("dockMessages");
@ -838,6 +866,22 @@ RiuResultQwtPlot* RiuMainWindow::resultPlot()
return m_resultQwtPlot;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuRelativePermeabilityPlotPanel* RiuMainWindow::relativePermeabilityPlotPanel()
{
return m_relPermPlotPanel;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPvtPlotPanel* RiuMainWindow::pvtPlotPanel()
{
return m_pvtPlotPanel;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -43,6 +43,8 @@ class RiuProcessMonitor;
class RiuResultInfoPanel;
class RiuResultQwtPlot;
class RiuViewer;
class RiuRelativePermeabilityPlotPanel;
class RiuPvtPlotPanel;
struct RimMdiWindowGeometry;
@ -111,8 +113,10 @@ public:
QMdiSubWindow* findMdiSubWindow(QWidget* viewer);
QList<QMdiSubWindow*> subWindowList(QMdiArea::WindowOrder order);
RiuResultQwtPlot* resultPlot();
RiuMessagePanel* messagePanel();
RiuResultQwtPlot* resultPlot();
RiuRelativePermeabilityPlotPanel* relativePermeabilityPlotPanel();
RiuPvtPlotPanel* pvtPlotPanel();
RiuMessagePanel* messagePanel();
void showProcessMonitorDockPanel();
@ -167,8 +171,10 @@ private:
RiuProcessMonitor* m_processMonitor;
QPointer<RiuMessagePanel> m_messagePanel;
RiuResultQwtPlot* m_resultQwtPlot;
RiuResultQwtPlot* m_resultQwtPlot;
RiuRelativePermeabilityPlotPanel* m_relPermPlotPanel;
RiuPvtPlotPanel* m_pvtPlotPanel;
QMenu* m_windowMenu;

View File

@ -0,0 +1,156 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuPvtPlotPanel.h"
#include "RiuSummaryQwtPlot.h"
#include "RigFlowDiagSolverInterface.h"
#include "cvfBase.h"
#include "cvfAssert.h"
//#include "cvfTrace.h"
#include "qwt_plot.h"
#include "qwt_plot_curve.h"
#include "qwt_legend.h"
#include <QDockWidget>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QComboBox>
#include <QLabel>
//==================================================================================================
//
//
//
//==================================================================================================
class MyQwtPlot : public QwtPlot
{
public:
MyQwtPlot(QWidget* parent) : QwtPlot(parent) {}
virtual QSize sizeHint() const { return QSize(100, 100); }
virtual QSize minimumSizeHint() const { return QSize(0, 0); }
};
//==================================================================================================
///
/// \class RiuPvtPlotPanel
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPvtPlotPanel::RiuPvtPlotPanel(QDockWidget* parent)
: QWidget(parent)
{
m_phaseComboBox = new QComboBox(this);
m_phaseComboBox->setEditable(false);
m_phaseComboBox->addItem("Oil", QVariant("oil"));
m_phaseComboBox->addItem("Gas", QVariant("gas"));
m_phaseComboBox->addItem("Water", QVariant("water"));
QHBoxLayout* comboLayout = new QHBoxLayout();
comboLayout->addWidget(new QLabel("Phase"));
comboLayout->addWidget(m_phaseComboBox);
comboLayout->addStretch(1);
m_fvfPlot = new MyQwtPlot(this);
m_viscosityPlot = new MyQwtPlot(this);
setPlotDefaults(m_fvfPlot);
setPlotDefaults(m_viscosityPlot);
m_fvfPlot->setTitle("Formation Volume Factor - N/A");
m_viscosityPlot->setTitle("Viscosity - N/A");
QHBoxLayout* plotLayout = new QHBoxLayout();
plotLayout->addWidget(m_fvfPlot);
plotLayout->addWidget(m_viscosityPlot);
QVBoxLayout* mainLayout = new QVBoxLayout();
mainLayout->addLayout(comboLayout);
mainLayout->addLayout(plotLayout);
setLayout(mainLayout);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPvtPlotPanel::~RiuPvtPlotPanel()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPvtPlotPanel::setPlotDefaults(QwtPlot* plot)
{
RiuSummaryQwtPlot::setCommonPlotBehaviour(plot);
plot->enableAxis(QwtPlot::xBottom, true);
plot->enableAxis(QwtPlot::yLeft, true);
plot->enableAxis(QwtPlot::xTop, false);
plot->enableAxis(QwtPlot::yRight, false);
plot->setAxisMaxMinor(QwtPlot::xBottom, 2);
plot->setAxisMaxMinor(QwtPlot::yLeft, 3);
QwtLegend* legend = new QwtLegend(plot);
plot->insertLegend(legend, QwtPlot::BottomLegend);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPvtPlotPanel::setPlotData(QString cellReferenceText)
{
//cvf::Trace::show("RiuPvtPlotPanel::setPlotData()");
m_cellReferenceText = cellReferenceText;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPvtPlotPanel::clearPlot()
{
//cvf::Trace::show("RiuPvtPlotPanel::clearPlot()");
if (m_cellReferenceText.isEmpty())
{
return;
}
m_cellReferenceText.clear();
//m_fvfPlot->detachItems(QwtPlotItem::Rtti_PlotItem, true);
//m_viscosityPlot->detachItems(QwtPlotItem::Rtti_PlotItem, true);
//m_fvfPlot->replot();
//m_viscosityPlot->replot();
}

View File

@ -0,0 +1,55 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QWidget>
class RigFlowDiagSolverInterface;
class QDockWidget;
class QwtPlot;
class QComboBox;
//==================================================================================================
//
//
//
//==================================================================================================
class RiuPvtPlotPanel : public QWidget
{
public:
RiuPvtPlotPanel(QDockWidget* parent);
virtual ~RiuPvtPlotPanel();
void setPlotData(QString cellReferenceText);
void clearPlot();
private:
static void setPlotDefaults(QwtPlot* plot);
private:
QComboBox* m_phaseComboBox;
QwtPlot* m_fvfPlot;
QwtPlot* m_viscosityPlot;
QString m_cellReferenceText;
};

View File

@ -0,0 +1,294 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuRelativePermeabilityPlotPanel.h"
#include "RiuSummaryQwtPlot.h"
#include "RiuQwtPlotWheelZoomer.h"
#include "RiuQwtPlotZoomer.h"
#include "RigFlowDiagSolverInterface.h"
#include "cvfBase.h"
#include "cvfAssert.h"
//#include "cvfTrace.h"
#include "qwt_plot.h"
#include "qwt_plot_curve.h"
#include "qwt_legend.h"
#include "qwt_symbol.h"
#include <QDockWidget>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QCheckBox>
#include <QGroupBox>
#include <QButtonGroup>
//==================================================================================================
//
//
//
//==================================================================================================
class MyQwtPlot : public QwtPlot
{
public:
MyQwtPlot(QWidget* parent) : QwtPlot(parent) {}
virtual QSize sizeHint() const { return QSize(100, 100); }
virtual QSize minimumSizeHint() const { return QSize(0, 0); }
};
//==================================================================================================
///
/// \class RiuRelativePermeabilityPlotPanel
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuRelativePermeabilityPlotPanel::RiuRelativePermeabilityPlotPanel(QDockWidget* parent)
: QWidget(parent)
{
m_qwtPlot = new MyQwtPlot(this);
setPlotDefaults(m_qwtPlot);
m_selectedCurvesButtonGroup = new QButtonGroup(this);
m_selectedCurvesButtonGroup->setExclusive(false);
m_selectedCurvesButtonGroup->addButton(new QCheckBox("KRW"), RigFlowDiagSolverInterface::RelPermCurve::KRW);
m_selectedCurvesButtonGroup->addButton(new QCheckBox("KRG"), RigFlowDiagSolverInterface::RelPermCurve::KRG);
m_selectedCurvesButtonGroup->addButton(new QCheckBox("KROW"), RigFlowDiagSolverInterface::RelPermCurve::KROW);
m_selectedCurvesButtonGroup->addButton(new QCheckBox("KROG"), RigFlowDiagSolverInterface::RelPermCurve::KROG);
m_selectedCurvesButtonGroup->addButton(new QCheckBox("PCOW"), RigFlowDiagSolverInterface::RelPermCurve::PCOW);
m_selectedCurvesButtonGroup->addButton(new QCheckBox("PCOG"), RigFlowDiagSolverInterface::RelPermCurve::PCOG);
QGroupBox* groupBox = new QGroupBox("Curves");
QVBoxLayout* groupBoxLayout = new QVBoxLayout;
groupBox->setLayout(groupBoxLayout);
QList<QAbstractButton*> checkButtonList = m_selectedCurvesButtonGroup->buttons();
for (int i = 0; i < checkButtonList.size(); i++)
{
checkButtonList[i]->setChecked(true);
groupBoxLayout->addWidget(checkButtonList[i]);
}
// Uncheck and disable PCOW and PCOG until we have data for these
checkButtonList[4]->setDisabled(true);
checkButtonList[4]->setChecked(false);
checkButtonList[5]->setDisabled(true);
checkButtonList[5]->setChecked(false);
QVBoxLayout* leftLayout = new QVBoxLayout;
leftLayout->addWidget(groupBox);
leftLayout->addStretch(1);
QHBoxLayout* mainLayout = new QHBoxLayout();
mainLayout->addLayout(leftLayout);
mainLayout->addWidget(m_qwtPlot);
setLayout(mainLayout);
connect(m_selectedCurvesButtonGroup, SIGNAL(buttonClicked(int)), SLOT(slotButtonInButtonGroupClicked(int)));
plotUiSelectedCurves();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuRelativePermeabilityPlotPanel::~RiuRelativePermeabilityPlotPanel()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuRelativePermeabilityPlotPanel::setPlotDefaults(QwtPlot* plot)
{
RiuSummaryQwtPlot::setCommonPlotBehaviour(plot);
plot->enableAxis(QwtPlot::xBottom, true);
plot->enableAxis(QwtPlot::yLeft, true);
plot->enableAxis(QwtPlot::xTop, false);
plot->enableAxis(QwtPlot::yRight, false);
plot->setAxisMaxMinor(QwtPlot::xBottom, 2);
plot->setAxisMaxMinor(QwtPlot::yLeft, 3);
QwtLegend* legend = new QwtLegend(plot);
plot->insertLegend(legend, QwtPlot::BottomLegend);
//new RiuQwtPlotWheelZoomer(plot);
//{
// // Rubber-band zoom
// RiuQwtPlotZoomer* plotZoomer = new RiuQwtPlotZoomer(plot->canvas());
// plotZoomer->setRubberBandPen(QColor(Qt::black));
// plotZoomer->setTrackerMode(QwtPicker::AlwaysOff);
// plotZoomer->setTrackerPen(QColor(Qt::black));
// plotZoomer->initMousePattern(1);
//}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuRelativePermeabilityPlotPanel::setPlotData(const std::vector<RigFlowDiagSolverInterface::RelPermCurve>& relPermCurves, QString cellReferenceText)
{
//cvf::Trace::show("Set RelPerm plot data");
m_allCurvesArr = relPermCurves;
m_cellReferenceText = cellReferenceText;
plotUiSelectedCurves();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuRelativePermeabilityPlotPanel::clearPlot()
{
//cvf::Trace::show("Clear RelPerm plot data");
if (m_allCurvesArr.empty() && m_cellReferenceText.isEmpty())
{
return;
}
m_allCurvesArr.clear();
m_cellReferenceText.clear();
plotCurvesInQwt(m_allCurvesArr, m_cellReferenceText, m_qwtPlot);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuRelativePermeabilityPlotPanel::plotUiSelectedCurves()
{
std::vector<RigFlowDiagSolverInterface::RelPermCurve> selectedCurves;
for (size_t i = 0; i < m_allCurvesArr.size(); i++)
{
const RigFlowDiagSolverInterface::RelPermCurve::Ident curveIdent = m_allCurvesArr[i].ident;
if (m_selectedCurvesButtonGroup->button(curveIdent) && m_selectedCurvesButtonGroup->button(curveIdent)->isChecked())
{
selectedCurves.push_back(m_allCurvesArr[i]);
}
}
plotCurvesInQwt(selectedCurves, m_cellReferenceText, m_qwtPlot);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(const std::vector<RigFlowDiagSolverInterface::RelPermCurve>& curveArr, QString cellReferenceText, QwtPlot* plot)
{
plot->detachItems(QwtPlotItem::Rtti_PlotCurve);
bool enableRightYAxis = false;
for (size_t i = 0; i < curveArr.size(); i++)
{
const RigFlowDiagSolverInterface::RelPermCurve& curve = curveArr[i];
QwtPlotCurve* qwtCurve = new QwtPlotCurve(curve.name.c_str());
CVF_ASSERT(curve.xVals.size() == curve.yVals.size());
qwtCurve->setSamples(curve.xVals.data(), curve.yVals.data(), static_cast<int>(curve.xVals.size()));
qwtCurve->setTitle(curve.name.c_str());
qwtCurve->setStyle(QwtPlotCurve::Lines);
QwtPlot::Axis yAxis = QwtPlot::yLeft;
bool plotOnRightAxis = false;
Qt::GlobalColor curveClr = Qt::magenta;
switch (curve.ident)
{
case RigFlowDiagSolverInterface::RelPermCurve::KRW: curveClr = Qt::blue; break;
case RigFlowDiagSolverInterface::RelPermCurve::KRG: curveClr = Qt::red; break;
case RigFlowDiagSolverInterface::RelPermCurve::KROW: curveClr = Qt::darkGreen; break;
case RigFlowDiagSolverInterface::RelPermCurve::KROG: curveClr = Qt::green; break;
case RigFlowDiagSolverInterface::RelPermCurve::PCOW: curveClr = Qt::darkGreen; plotOnRightAxis = true; break;
case RigFlowDiagSolverInterface::RelPermCurve::PCOG: curveClr = Qt::green; plotOnRightAxis = true; break;
}
QPen curvePen;
curvePen.setColor(curveClr);
qwtCurve->setPen(curvePen);
qwtCurve->setLegendAttribute(QwtPlotCurve::LegendShowLine, true);
qwtCurve->setLegendAttribute(QwtPlotCurve::LegendShowSymbol, true);
qwtCurve->setLegendAttribute(QwtPlotCurve::LegendShowBrush, true);
qwtCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
if (plotOnRightAxis)
{
QwtSymbol* curveSymbol = new QwtSymbol(QwtSymbol::Ellipse);
curveSymbol->setSize(10, 10);
curveSymbol->setPen(curvePen);
curveSymbol->setBrush(Qt::NoBrush);
qwtCurve->setSymbol(curveSymbol);
qwtCurve->setYAxis(QwtPlot::yRight);
enableRightYAxis = true;
}
qwtCurve->attach(plot);
}
QString title = "Relative Permeability";
if (!cellReferenceText.isEmpty())
{
title += ", " + cellReferenceText;
}
plot->setTitle(title);
plot->setAxisTitle(QwtPlot::xBottom, "Saturation");
plot->setAxisTitle(QwtPlot::yLeft, "Kr");
plot->setAxisTitle(QwtPlot::yRight, "Pc");
plot->enableAxis(QwtPlot::yRight, enableRightYAxis);
plot->replot();
//plot->setAxisScale(QwtPlot::xBottom, 0, 1);
//plot->setAxisScale(QwtPlot::yLeft, 0, 1);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuRelativePermeabilityPlotPanel::slotButtonInButtonGroupClicked(int)
{
plotUiSelectedCurves();
}

View File

@ -0,0 +1,60 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFlowDiagSolverInterface.h"
#include <QWidget>
class QDockWidget;
class QButtonGroup;
class QwtPlot;
//==================================================================================================
//
//
//
//==================================================================================================
class RiuRelativePermeabilityPlotPanel : public QWidget
{
Q_OBJECT
public:
RiuRelativePermeabilityPlotPanel(QDockWidget* parent);
virtual ~RiuRelativePermeabilityPlotPanel();
void setPlotData(const std::vector<RigFlowDiagSolverInterface::RelPermCurve>& relPermCurves, QString cellReferenceText);
void clearPlot();
private:
void plotUiSelectedCurves();
static void setPlotDefaults(QwtPlot* plot);
static void plotCurvesInQwt(const std::vector<RigFlowDiagSolverInterface::RelPermCurve>& curveArr, QString cellReferenceText, QwtPlot* plot);
private slots:
void slotButtonInButtonGroupClicked(int);
private:
std::vector<RigFlowDiagSolverInterface::RelPermCurve> m_allCurvesArr;
QString m_cellReferenceText;
QwtPlot* m_qwtPlot;
QButtonGroup* m_selectedCurvesButtonGroup;
};

View File

@ -27,6 +27,8 @@
#include "RigFemPartResultsCollection.h"
#include "RigGeoMechCaseData.h"
#include "RigTimeHistoryResultAccessor.h"
#include "RigGridBase.h"
#include "RigActiveCellInfo.h"
#include "RiuFemTimeHistoryResultAccessor.h"
#include "RimEclipseCase.h"
@ -36,17 +38,85 @@
#include "RimGeoMechResultDefinition.h"
#include "RimGeoMechView.h"
#include "RimProject.h"
#include "RimEclipseResultCase.h"
#include "RiuFemResultTextBuilder.h"
#include "RiuMainWindow.h"
#include "RiuResultQwtPlot.h"
#include "RiuResultTextBuilder.h"
#include "RiuSelectionManager.h"
#include "RiuRelativePermeabilityPlotPanel.h"
#include "RiuPvtPlotPanel.h"
//#include "cvfTrace.h"
#include <QStatusBar>
#include <assert.h>
//==================================================================================================
//
//
//
//==================================================================================================
class CellLookupHelper
{
public:
static size_t mapToActiveCellIndex(const RigEclipseCaseData* eclipseCaseData, size_t gridIndex, size_t gridLocalCellIndex)
{
const size_t gridCount = eclipseCaseData ? eclipseCaseData->gridCount() : 0;
const RigGridBase* grid = gridIndex < gridCount ? eclipseCaseData->grid(gridIndex) : NULL;
if (grid && gridLocalCellIndex < grid->cellCount())
{
// Note!!
// Which type of porosity model to choose? Currently hard-code to MATRIX_MODEL
const RigActiveCellInfo* activeCellInfo = eclipseCaseData->activeCellInfo(RiaDefines::MATRIX_MODEL);
CVF_ASSERT(activeCellInfo);
const size_t reservoirCellIndex = grid->reservoirCellIndex(gridLocalCellIndex);
const size_t activeCellIndex = activeCellInfo->cellResultIndex(reservoirCellIndex);
return activeCellIndex;
}
return cvf::UNDEFINED_SIZE_T;
}
static QString cellReferenceText(const RigEclipseCaseData* eclipseCaseData, size_t gridIndex, size_t gridLocalCellIndex)
{
const size_t gridCount = eclipseCaseData ? eclipseCaseData->gridCount() : 0;
const RigGridBase* grid = gridIndex < gridCount ? eclipseCaseData->grid(gridIndex) : NULL;
if (grid && gridLocalCellIndex < grid->cellCount())
{
size_t i = 0;
size_t j = 0;
size_t k = 0;
if (grid->ijkFromCellIndex(gridLocalCellIndex, &i, &j, &k))
{
// Adjust to 1-based Eclipse indexing
i++;
j++;
k++;
QString retText = QString("Grid index %1, Cell : [%2, %3, %4]").arg(gridIndex).arg(i).arg(j).arg(k);
return retText;
}
}
return QString();
}
};
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -69,6 +139,9 @@ void RiuSelectionChangedHandler::handleSelectionDeleted() const
{
RiuMainWindow::instance()->resultPlot()->deleteAllCurves();
updateRelativePermeabilityPlot(NULL);
updatePvtPlot(NULL);
updateResultInfo(NULL);
scheduleUpdateForAllVisibleViews();
@ -81,6 +154,9 @@ void RiuSelectionChangedHandler::handleItemAppended(const RiuSelectionItem* item
{
addCurveFromSelectionItem(item);
updateRelativePermeabilityPlot(item);
updatePvtPlot(item);
updateResultInfo(item);
scheduleUpdateForAllVisibleViews();
@ -233,6 +309,88 @@ void RiuSelectionChangedHandler::addCurveFromSelectionItem(const RiuSelectionIte
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSelectionChangedHandler::updateRelativePermeabilityPlot(const RiuSelectionItem* selectionItem) const
{
RiuRelativePermeabilityPlotPanel* relPermPlotPanel = RiuMainWindow::instance()->relativePermeabilityPlotPanel();
if (!relPermPlotPanel)
{
return;
}
bool mustClearPlot = true;
if (relPermPlotPanel->isVisible() && selectionItem && selectionItem->type() == RiuSelectionItem::ECLIPSE_SELECTION_OBJECT)
{
const RiuEclipseSelectionItem* eclipseSelectionItem = static_cast<const RiuEclipseSelectionItem*>(selectionItem);
RimEclipseResultCase* eclipseResultCase = dynamic_cast<RimEclipseResultCase*>(eclipseSelectionItem->m_view->eclipseCase());
if (eclipseResultCase && eclipseResultCase->flowDiagSolverInterface())
{
size_t activeCellIndex = CellLookupHelper::mapToActiveCellIndex(eclipseResultCase->eclipseCaseData(), eclipseSelectionItem->m_gridIndex, eclipseSelectionItem->m_gridLocalCellIndex);
if (activeCellIndex != cvf::UNDEFINED_SIZE_T)
{
//cvf::Trace::show("Updating RelPerm plot for active cell index: %d", static_cast<int>(activeCellIndex));
std::vector<RigFlowDiagSolverInterface::RelPermCurve> relPermCurveArr = eclipseResultCase->flowDiagSolverInterface()->calculateRelPermCurvesForActiveCell(activeCellIndex);
QString cellRefText = CellLookupHelper::cellReferenceText(eclipseResultCase->eclipseCaseData(), eclipseSelectionItem->m_gridIndex, eclipseSelectionItem->m_gridLocalCellIndex);
relPermPlotPanel->setPlotData(relPermCurveArr, cellRefText);
mustClearPlot = false;
}
}
}
if (mustClearPlot)
{
relPermPlotPanel->clearPlot();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSelectionChangedHandler::updatePvtPlot(const RiuSelectionItem* selectionItem) const
{
RiuPvtPlotPanel* pvtPlotPanel = RiuMainWindow::instance()->pvtPlotPanel();
if (!pvtPlotPanel)
{
return;
}
bool mustClearPlot = true;
if (pvtPlotPanel->isVisible() && selectionItem && selectionItem->type() == RiuSelectionItem::ECLIPSE_SELECTION_OBJECT)
{
const RiuEclipseSelectionItem* eclipseSelectionItem = static_cast<const RiuEclipseSelectionItem*>(selectionItem);
RimEclipseResultCase* eclipseResultCase = dynamic_cast<RimEclipseResultCase*>(eclipseSelectionItem->m_view->eclipseCase());
if (eclipseResultCase && eclipseResultCase->flowDiagSolverInterface())
{
size_t activeCellIndex = CellLookupHelper::mapToActiveCellIndex(eclipseResultCase->eclipseCaseData(), eclipseSelectionItem->m_gridIndex, eclipseSelectionItem->m_gridLocalCellIndex);
if (activeCellIndex != cvf::UNDEFINED_SIZE_T)
{
//cvf::Trace::show("Update PVT plot for active cell index: %d", static_cast<int>(activeCellIndex));
//std::vector<RigFlowDiagSolverInterface::PvtCurve> fvfCurveArr = eclipseResultCase->flowDiagSolverInterface()->calculatePvtFvfCurvesForActiveCell(activeCellIndex);
//cvf::Trace::show("Got %d fvf curves", static_cast<int>(fvfCurveArr.size()));
QString cellRefText = CellLookupHelper::cellReferenceText(eclipseResultCase->eclipseCaseData(), eclipseSelectionItem->m_gridIndex, eclipseSelectionItem->m_gridLocalCellIndex);
pvtPlotPanel->setPlotData(cellRefText);
mustClearPlot = false;
}
}
}
if (mustClearPlot)
{
pvtPlotPanel->clearPlot();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -40,6 +40,8 @@ private:
void addCurveFromSelectionItem(const RiuSelectionItem* itemAdded) const;
void addCurveFromSelectionItem(const RiuEclipseSelectionItem* selectionItem) const;
void addCurveFromSelectionItem(const RiuGeoMechSelectionItem* selectionItem) const;
void updateRelativePermeabilityPlot(const RiuSelectionItem* selectionItem) const;
void updatePvtPlot(const RiuSelectionItem* selectionItem) const;
void scheduleUpdateForAllVisibleViews() const;
void updateResultInfo(const RiuSelectionItem* itemAdded) const;