mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#2061 Added calculation and display of intersection markers in RelPerm plot to show the selected cell's SWAT SGAS values
This commit is contained in:
parent
e83b3a8c02
commit
0872728d17
@ -226,7 +226,7 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(const std::vector<RigFlow
|
|||||||
plot->detachItems(QwtPlotItem::Rtti_PlotCurve);
|
plot->detachItems(QwtPlotItem::Rtti_PlotCurve);
|
||||||
plot->detachItems(QwtPlotItem::Rtti_PlotMarker);
|
plot->detachItems(QwtPlotItem::Rtti_PlotMarker);
|
||||||
|
|
||||||
bool enableRightYAxis = false;
|
bool shouldEableRightYAxis = false;
|
||||||
|
|
||||||
for (size_t i = 0; i < curveArr.size(); i++)
|
for (size_t i = 0; i < curveArr.size(); i++)
|
||||||
{
|
{
|
||||||
@ -250,39 +250,53 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(const std::vector<RigFlow
|
|||||||
|
|
||||||
qwtCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
|
qwtCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
|
||||||
|
|
||||||
|
// Curves containing capillary pressure are plotted on the right y axis and are marked with small circles
|
||||||
const bool plotCurveOnRightAxis = (curve.ident == RigFlowDiagSolverInterface::RelPermCurve::PCOW) || (curve.ident == RigFlowDiagSolverInterface::RelPermCurve::PCOG);
|
const bool plotCurveOnRightAxis = (curve.ident == RigFlowDiagSolverInterface::RelPermCurve::PCOW) || (curve.ident == RigFlowDiagSolverInterface::RelPermCurve::PCOG);
|
||||||
if (plotCurveOnRightAxis)
|
if (plotCurveOnRightAxis)
|
||||||
{
|
{
|
||||||
QwtSymbol* curveSymbol = new QwtSymbol(QwtSymbol::Ellipse);
|
QwtSymbol* curveSymbol = new QwtSymbol(QwtSymbol::Ellipse);
|
||||||
curveSymbol->setSize(10, 10);
|
curveSymbol->setSize(6, 6);
|
||||||
curveSymbol->setPen(curvePen);
|
curveSymbol->setPen(curvePen);
|
||||||
curveSymbol->setBrush(Qt::NoBrush);
|
curveSymbol->setBrush(Qt::NoBrush);
|
||||||
qwtCurve->setSymbol(curveSymbol);
|
qwtCurve->setSymbol(curveSymbol);
|
||||||
|
|
||||||
qwtCurve->setYAxis(QwtPlot::yRight);
|
qwtCurve->setYAxis(QwtPlot::yRight);
|
||||||
enableRightYAxis = true;
|
shouldEableRightYAxis = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
qwtCurve->attach(plot);
|
qwtCurve->attach(plot);
|
||||||
|
|
||||||
|
|
||||||
|
// Add markers to indicate where SWAT and/or SGAS saturation intersects the respective curves
|
||||||
|
if (swat != HUGE_VAL)
|
||||||
|
{
|
||||||
|
if (curve.ident == RigFlowDiagSolverInterface::RelPermCurve::KRW ||
|
||||||
|
curve.ident == RigFlowDiagSolverInterface::RelPermCurve::KROW ||
|
||||||
|
curve.ident == RigFlowDiagSolverInterface::RelPermCurve::PCOW)
|
||||||
|
{
|
||||||
|
addCurveConstSaturationIntersectionMarker(curve, swat, Qt::blue, plotCurveOnRightAxis, plot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sgas != HUGE_VAL)
|
||||||
|
{
|
||||||
|
if (curve.ident == RigFlowDiagSolverInterface::RelPermCurve::KRG ||
|
||||||
|
curve.ident == RigFlowDiagSolverInterface::RelPermCurve::KROG ||
|
||||||
|
curve.ident == RigFlowDiagSolverInterface::RelPermCurve::PCOG)
|
||||||
|
{
|
||||||
|
addCurveConstSaturationIntersectionMarker(curve, sgas, Qt::red, plotCurveOnRightAxis, plot);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Add vertical marker lines to indicate cell SWAT and/or SGAS saturations
|
||||||
if (swat != HUGE_VAL)
|
if (swat != HUGE_VAL)
|
||||||
{
|
{
|
||||||
QwtPlotMarker* marker = new QwtPlotMarker("SWAT");
|
addVerticalSaturationMarkerLine(swat, "SWAT", Qt::blue, plot);
|
||||||
marker->setXValue(swat);
|
|
||||||
marker->setLineStyle(QwtPlotMarker::VLine);
|
|
||||||
marker->setLinePen(QPen(Qt::blue, 1, Qt::DashLine));
|
|
||||||
marker->attach(plot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sgas != HUGE_VAL)
|
if (sgas != HUGE_VAL)
|
||||||
{
|
{
|
||||||
QwtPlotMarker* marker = new QwtPlotMarker("SGAS");
|
addVerticalSaturationMarkerLine(sgas, "SGAS", Qt::red, plot);
|
||||||
marker->setXValue(sgas);
|
|
||||||
marker->setLineStyle(QwtPlotMarker::VLine);
|
|
||||||
marker->setLinePen(QPen(Qt::red, 1, Qt::DashLine));
|
|
||||||
marker->attach(plot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -297,7 +311,7 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(const std::vector<RigFlow
|
|||||||
plot->setAxisTitle(QwtPlot::yLeft, "Kr");
|
plot->setAxisTitle(QwtPlot::yLeft, "Kr");
|
||||||
plot->setAxisTitle(QwtPlot::yRight, "Pc");
|
plot->setAxisTitle(QwtPlot::yRight, "Pc");
|
||||||
|
|
||||||
plot->enableAxis(QwtPlot::yRight, enableRightYAxis);
|
plot->enableAxis(QwtPlot::yRight, shouldEableRightYAxis);
|
||||||
|
|
||||||
plot->replot();
|
plot->replot();
|
||||||
|
|
||||||
@ -305,6 +319,7 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(const std::vector<RigFlow
|
|||||||
//plot->setAxisScale(QwtPlot::yLeft, 0, 1);
|
//plot->setAxisScale(QwtPlot::yLeft, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -337,6 +352,87 @@ QString RiuRelativePermeabilityPlotPanel::determineXAxisTitleFromCurveCollection
|
|||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
/// Add a vertical labeled marker line at the specified saturation value
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RiuRelativePermeabilityPlotPanel::addVerticalSaturationMarkerLine(double saturationValue, QString label, QColor color, QwtPlot* plot)
|
||||||
|
{
|
||||||
|
QwtPlotMarker* lineMarker = new QwtPlotMarker;
|
||||||
|
lineMarker->setXValue(saturationValue);
|
||||||
|
lineMarker->setLineStyle(QwtPlotMarker::VLine);
|
||||||
|
lineMarker->setLinePen(QPen(color, 1, Qt::DashLine));
|
||||||
|
lineMarker->setLabel(label);
|
||||||
|
lineMarker->setLabelAlignment(Qt::AlignTop | Qt::AlignRight);
|
||||||
|
lineMarker->setLabelOrientation(Qt::Vertical);
|
||||||
|
|
||||||
|
lineMarker->attach(plot);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
/// Add a marker at the intersection of the passed curve and the constant saturation value
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RiuRelativePermeabilityPlotPanel::addCurveConstSaturationIntersectionMarker(const RigFlowDiagSolverInterface::RelPermCurve& curve, double saturationValue, QColor markerColor, bool plotCurveOnRightAxis, QwtPlot* plot)
|
||||||
|
{
|
||||||
|
const double yVal = interpolatedCurveYValue(curve.xVals, curve.yVals, saturationValue);
|
||||||
|
if (yVal != HUGE_VAL)
|
||||||
|
{
|
||||||
|
QwtPlotMarker* pointMarker = new QwtPlotMarker;
|
||||||
|
pointMarker->setValue(saturationValue, yVal);
|
||||||
|
|
||||||
|
QwtSymbol* symbol = new QwtSymbol(QwtSymbol::Ellipse);
|
||||||
|
symbol->setSize(13, 13);
|
||||||
|
symbol->setPen(QPen(markerColor, 2));
|
||||||
|
symbol->setBrush(Qt::NoBrush);
|
||||||
|
pointMarker->setSymbol(symbol);
|
||||||
|
pointMarker->attach(plot);
|
||||||
|
|
||||||
|
if (plotCurveOnRightAxis)
|
||||||
|
{
|
||||||
|
pointMarker->setYAxis(QwtPlot::yRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
/// Assumes that all the x-values are ordered in increasing order
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RiuRelativePermeabilityPlotPanel::interpolatedCurveYValue(const std::vector<double>& xVals, const std::vector<double>& yVals, double x)
|
||||||
|
{
|
||||||
|
if (xVals.size() == 0) return HUGE_VAL;
|
||||||
|
if (x < xVals.front()) return HUGE_VAL;
|
||||||
|
if (x > xVals.back()) return HUGE_VAL;
|
||||||
|
|
||||||
|
// Find first element greater or equal to the passed x-value
|
||||||
|
std::vector<double>::const_iterator it = std::upper_bound(xVals.begin(), xVals.end(), x);
|
||||||
|
|
||||||
|
// Due to checks above, we should never come up empty, but to safeguard against NaNs etc
|
||||||
|
if (it == xVals.end())
|
||||||
|
{
|
||||||
|
return HUGE_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Corner case - exact match on first element
|
||||||
|
if (it == xVals.begin())
|
||||||
|
{
|
||||||
|
return yVals.front();
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t idx1 = it - xVals.begin();
|
||||||
|
CVF_ASSERT(idx1 > 0);
|
||||||
|
const size_t idx0 = idx1 - 1;
|
||||||
|
|
||||||
|
const double x0 = xVals[idx0];
|
||||||
|
const double y0 = yVals[idx0];
|
||||||
|
const double x1 = xVals[idx1];
|
||||||
|
const double y1 = yVals[idx1];
|
||||||
|
CVF_ASSERT(x1 > x0);
|
||||||
|
|
||||||
|
const double t = (x1 - x0) > 0 ? (x - x0)/(x1 - x0) : 0;
|
||||||
|
const double y = y0 + t*(y1 - y0);
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -50,6 +50,9 @@ private:
|
|||||||
static void plotCurvesInQwt(const std::vector<RigFlowDiagSolverInterface::RelPermCurve>& curveArr, double swat, double sgas, QString cellReferenceText, QwtPlot* plot);
|
static void plotCurvesInQwt(const std::vector<RigFlowDiagSolverInterface::RelPermCurve>& curveArr, double swat, double sgas, QString cellReferenceText, QwtPlot* plot);
|
||||||
static QColor curveColorFromIdent(RigFlowDiagSolverInterface::RelPermCurve::Ident ident);
|
static QColor curveColorFromIdent(RigFlowDiagSolverInterface::RelPermCurve::Ident ident);
|
||||||
static QString determineXAxisTitleFromCurveCollection(const std::vector<RigFlowDiagSolverInterface::RelPermCurve>& curveArr);
|
static QString determineXAxisTitleFromCurveCollection(const std::vector<RigFlowDiagSolverInterface::RelPermCurve>& curveArr);
|
||||||
|
static void addVerticalSaturationMarkerLine(double saturationValue, QString label, QColor color, QwtPlot* plot);
|
||||||
|
static void addCurveConstSaturationIntersectionMarker(const RigFlowDiagSolverInterface::RelPermCurve& curve, double saturationValue, QColor markerColor, bool plotCurveOnRightAxis, QwtPlot* plot);
|
||||||
|
static double interpolatedCurveYValue(const std::vector<double>& xVals, const std::vector<double>& yVals, double x);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotButtonInButtonGroupClicked(int);
|
void slotButtonInButtonGroupClicked(int);
|
||||||
|
@ -336,7 +336,7 @@ void RiuSelectionChangedHandler::updateRelativePermeabilityPlot(const RiuSelecti
|
|||||||
size_t activeCellIndex = CellLookupHelper::mapToActiveCellIndex(eclipseResultCase->eclipseCaseData(), eclipseSelectionItem->m_gridIndex, eclipseSelectionItem->m_gridLocalCellIndex);
|
size_t activeCellIndex = CellLookupHelper::mapToActiveCellIndex(eclipseResultCase->eclipseCaseData(), eclipseSelectionItem->m_gridIndex, eclipseSelectionItem->m_gridLocalCellIndex);
|
||||||
if (activeCellIndex != cvf::UNDEFINED_SIZE_T)
|
if (activeCellIndex != cvf::UNDEFINED_SIZE_T)
|
||||||
{
|
{
|
||||||
cvf::Trace::show("Updating RelPerm plot for active cell index: %d", static_cast<int>(activeCellIndex));
|
//cvf::Trace::show("Updating RelPerm plot for active cell index: %d", static_cast<int>(activeCellIndex));
|
||||||
|
|
||||||
std::vector<RigFlowDiagSolverInterface::RelPermCurve> relPermCurveArr = eclipseResultCase->flowDiagSolverInterface()->calculateRelPermCurvesForActiveCell(activeCellIndex);
|
std::vector<RigFlowDiagSolverInterface::RelPermCurve> relPermCurveArr = eclipseResultCase->flowDiagSolverInterface()->calculateRelPermCurvesForActiveCell(activeCellIndex);
|
||||||
QString cellRefText = CellLookupHelper::cellReferenceText(eclipseResultCase->eclipseCaseData(), eclipseSelectionItem->m_gridIndex, eclipseSelectionItem->m_gridLocalCellIndex);
|
QString cellRefText = CellLookupHelper::cellReferenceText(eclipseResultCase->eclipseCaseData(), eclipseSelectionItem->m_gridIndex, eclipseSelectionItem->m_gridLocalCellIndex);
|
||||||
@ -347,7 +347,7 @@ void RiuSelectionChangedHandler::updateRelativePermeabilityPlot(const RiuSelecti
|
|||||||
cvf::ref<RigResultAccessor> sgasAccessor = RigResultAccessorFactory::createFromNameAndType(eclipseResultCase->eclipseCaseData(), eclipseSelectionItem->m_gridIndex, RiaDefines::MATRIX_MODEL, timeStepIndex, "SGAS", RiaDefines::DYNAMIC_NATIVE);
|
cvf::ref<RigResultAccessor> sgasAccessor = RigResultAccessorFactory::createFromNameAndType(eclipseResultCase->eclipseCaseData(), eclipseSelectionItem->m_gridIndex, RiaDefines::MATRIX_MODEL, timeStepIndex, "SGAS", RiaDefines::DYNAMIC_NATIVE);
|
||||||
const double cellSWAT = swatAccessor.notNull() ? swatAccessor->cellScalar(eclipseSelectionItem->m_gridLocalCellIndex) : HUGE_VAL;
|
const double cellSWAT = swatAccessor.notNull() ? swatAccessor->cellScalar(eclipseSelectionItem->m_gridLocalCellIndex) : HUGE_VAL;
|
||||||
const double cellSGAS = sgasAccessor.notNull() ? sgasAccessor->cellScalar(eclipseSelectionItem->m_gridLocalCellIndex) : HUGE_VAL;
|
const double cellSGAS = sgasAccessor.notNull() ? sgasAccessor->cellScalar(eclipseSelectionItem->m_gridLocalCellIndex) : HUGE_VAL;
|
||||||
cvf::Trace::show("cellSWAT = %f cellSGAS = %f", cellSWAT, cellSGAS);
|
//cvf::Trace::show("cellSWAT = %f cellSGAS = %f", cellSWAT, cellSGAS);
|
||||||
|
|
||||||
relPermPlotPanel->setPlotData(relPermCurveArr, cellSWAT, cellSGAS, cellRefText);
|
relPermPlotPanel->setPlotData(relPermCurveArr, cellSWAT, cellSGAS, cellRefText);
|
||||||
mustClearPlot = false;
|
mustClearPlot = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user