#4136 Export of Flow Characteristics : Create text for export and add context menu

This commit is contained in:
Magne Sjaastad 2019-06-23 15:18:17 +02:00
parent 79df075fe4
commit 7879fe186d
5 changed files with 200 additions and 26 deletions

View File

@ -1,23 +1,24 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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>
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RicShowPlotDataFeature.h"
#include "RiaFeatureCommandContext.h"
#include "RiaGuiApplication.h"
#include "RimGridCrossPlot.h"
@ -36,7 +37,6 @@
#include <QAction>
CAF_CMD_SOURCE_INIT(RicShowPlotDataFeature, "RicShowPlotDataFeature");
//--------------------------------------------------------------------------------------------------
@ -166,11 +166,17 @@ private:
///
///
/// RicShowPlotDataFeature
///
///
///
///
//--------------------------------------------------------------------------------------------------
bool RicShowPlotDataFeature::isCommandEnabled()
{
QString content = RiaFeatureCommandContext::instance()->contentString();
if (!content.isEmpty())
{
return true;
}
auto selectedSummaryPlots = caf::selectedObjectsByType<RimSummaryPlot*>();
if (selectedSummaryPlots.size() > 0)
{
@ -195,15 +201,29 @@ bool RicShowPlotDataFeature::isCommandEnabled()
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RicShowPlotDataFeature::onActionTriggered(bool isChecked)
{
QString content = RiaFeatureCommandContext::instance()->contentString();
if (!content.isEmpty())
{
QString title = "Data Content";
{
QString titleCandidate = RiaFeatureCommandContext::instance()->titleString();
if (!titleCandidate.isEmpty()) titleCandidate = titleCandidate;
}
RicShowPlotDataFeature::showTextWindow(title, content);
return;
}
this->disableModelChangeContribution();
std::vector<RimSummaryPlot*> selectedSummaryPlots = caf::selectedObjectsByType<RimSummaryPlot*>();
std::vector<RimWellLogPlot*> wellLogPlots = caf::selectedObjectsByType<RimWellLogPlot*>();
std::vector<RimGridCrossPlot*> crossPlots = caf::selectedObjectsByType<RimGridCrossPlot*>();
std::vector<RimWellLogPlot*> wellLogPlots = caf::selectedObjectsByType<RimWellLogPlot*>();
std::vector<RimGridCrossPlot*> crossPlots = caf::selectedObjectsByType<RimGridCrossPlot*>();
if (selectedSummaryPlots.size() == 0 && wellLogPlots.size() == 0 && crossPlots.size() == 0)
{
CVF_ASSERT(false);
@ -223,7 +243,7 @@ void RicShowPlotDataFeature::onActionTriggered(bool isChecked)
for (RimWellLogPlot* wellLogPlot : wellLogPlots)
{
QString title = wellLogPlot->description();
QString text = wellLogPlot->asciiDataForPlotExport();
QString text = wellLogPlot->asciiDataForPlotExport();
RicShowPlotDataFeature::showTextWindow(title, text);
}
@ -235,7 +255,7 @@ void RicShowPlotDataFeature::onActionTriggered(bool isChecked)
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RicShowPlotDataFeature::setupActionLook(QAction* actionToSetup)
{
@ -244,7 +264,7 @@ void RicShowPlotDataFeature::setupActionLook(QAction* actionToSetup)
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RicShowPlotDataFeature::showTabbedTextWindow(RiuTabbedTextProvider* textProvider)
{

View File

@ -18,6 +18,8 @@
#include "RimFlowCharacteristicsPlot.h"
#include "RifEclipseDataTableFormatter.h"
#include "RigActiveCellInfo.h"
#include "RigEclipseCaseData.h"
#include "RigFlowDiagResults.h"
@ -555,19 +557,22 @@ void RimFlowCharacteristicsPlot::onLoadDataAndUpdate()
if (m_flowDiagSolution && m_flowCharPlotWidget)
{
RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults();
std::vector<int> calculatedTimesteps = flowResult->calculatedTimeSteps(RigFlowDiagResultAddress::PHASE_ALL);
RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults();
if (m_timeStepSelectionType == SELECTED)
{
for (int tsIdx : m_selectedTimeSteps())
{
m_flowDiagSolution()->flowDiagResults()->maxAbsPairFlux(tsIdx);
}
calculatedTimesteps = m_selectedTimeSteps();
}
std::vector<int> calculatedTimesteps = flowResult->calculatedTimeSteps(RigFlowDiagResultAddress::PHASE_ALL);
m_currentlyPlottedTimeSteps = calculatedTimesteps;
if (m_timeStepSelectionType == SELECTED)
{
for (int tsIdx : m_selectedTimeSteps())
{
m_flowDiagSolution()->flowDiagResults()->maxAbsPairFlux(tsIdx);
}
calculatedTimesteps = m_selectedTimeSteps();
}
m_currentlyPlottedTimeSteps = calculatedTimesteps;
}
std::vector<QDateTime> timeStepDates = m_case->timeStepDates();
QStringList timeStepStrings = m_case->timeStepStrings();
@ -586,7 +591,7 @@ void RimFlowCharacteristicsPlot::onLoadDataAndUpdate()
std::map<int, RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame> timeStepToFlowResultMap;
for (int timeStepIdx : calculatedTimesteps)
for (int timeStepIdx : m_currentlyPlottedTimeSteps)
{
if (m_cellFilter() == RigFlowDiagResults::CELLS_VISIBLE)
{
@ -622,9 +627,11 @@ void RimFlowCharacteristicsPlot::onLoadDataAndUpdate()
lorenzVals[timeStepIdx] = timeStepToFlowResultMap[timeStepIdx].m_lorenzCoefficient;
}
m_timeStepToFlowResultMap = timeStepToFlowResultMap;
m_flowCharPlotWidget->setLorenzCurve(timeStepStrings, timeStepDates, lorenzVals);
for (int timeStepIdx : calculatedTimesteps)
for (int timeStepIdx : m_currentlyPlottedTimeSteps)
{
const auto& flowCharResults = timeStepToFlowResultMap[timeStepIdx];
@ -652,6 +659,120 @@ void RimFlowCharacteristicsPlot::viewGeometryUpdated()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double interpolate(std::vector<double>& xData, std::vector<double>& yData, double x, bool extrapolate)
{
size_t itemCount = xData.size();
size_t index = 0;
if (x >= xData[itemCount - 2])
{
index = itemCount - 2;
}
else
{
while (x > xData[index + 1])
index++;
}
double xLeft = xData[index];
double yLeft = yData[index];
double xRight = xData[index + 1];
double yRight = yData[index + 1];
if (!extrapolate)
{
if (x < xLeft) yRight = yLeft;
if (x > xRight) yLeft = yRight;
}
double dydx = (yRight - yLeft) / (xRight - xLeft);
return yLeft + dydx * (x - xLeft);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFlowCharacteristicsPlot::curveDataAsText() const
{
QString tableText;
QTextStream stream(&tableText);
RifEclipseDataTableFormatter formatter(stream);
std::vector<RifEclipseOutputTableColumn> header = {
RifEclipseOutputTableColumn("Date"),
RifEclipseOutputTableColumn("Storage Capacity"),
RifEclipseOutputTableColumn("Flow Capacity"),
RifEclipseOutputTableColumn("Sweep Efficiency"),
RifEclipseOutputTableColumn("Dimensionless Time"),
RifEclipseOutputTableColumn("Lorentz Coefficient"),
};
formatter.header(header);
std::vector<QDateTime> timeStepDates = m_case->timeStepDates();
std::vector<double> storageCapacitySamplingValues = {0.08, 0.1, 0.2, 0.3, 0.4};
size_t sampleCount = storageCapacitySamplingValues.size();
for (const auto& timeIndex : m_currentlyPlottedTimeSteps)
{
QString dateString = timeStepDates[timeIndex].toString("yyyy-MM-DD");
auto a = m_timeStepToFlowResultMap.find(timeIndex);
if (a != m_timeStepToFlowResultMap.end())
{
auto storageCapacityValues = a->second.m_storageCapFlowCapCurve.first;
auto flowCapacityValues = a->second.m_storageCapFlowCapCurve.second;
bool extrapolate = false;
std::vector<double> flowCapacitySamplingValues;
for (const auto storageCapacity : storageCapacitySamplingValues)
{
{
double flowCapacity = interpolate(storageCapacityValues, flowCapacityValues, storageCapacity, extrapolate);
flowCapacitySamplingValues.push_back(flowCapacity);
}
}
auto dimensionLessTimeValues = a->second.m_dimensionlessTimeSweepEfficiencyCurve.first;
auto sweepEffValues = a->second.m_dimensionlessTimeSweepEfficiencyCurve.second;
std::vector<double> dimensionLessTimeSamplingValues;
std::vector<double> sweepEffSamplingValues;
double range = dimensionLessTimeValues.back() - dimensionLessTimeValues[0];
double step = range / sampleCount;
for (size_t i = 0; i < sampleCount; i++)
{
double dimensionLessTimeValue = i * step;
dimensionLessTimeSamplingValues.push_back(dimensionLessTimeValue);
double sweepEffValue = interpolate(dimensionLessTimeValues, sweepEffValues, dimensionLessTimeValue, extrapolate);
sweepEffSamplingValues.push_back(sweepEffValue);
}
auto lorentz = a->second.m_lorenzCoefficient;
for (size_t i = 0; i < sampleCount; i++)
{
formatter.add(dateString);
formatter.add(storageCapacitySamplingValues[i]);
formatter.add(flowCapacitySamplingValues[i]);
formatter.add(sweepEffSamplingValues[i]);
formatter.add(dimensionLessTimeSamplingValues[i]);
formatter.add(lorentz);
formatter.rowCompleted();
}
}
}
formatter.tableCompleted();
return tableText;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -67,6 +67,8 @@ public:
void deleteViewWidget() override;
void viewGeometryUpdated();
QString curveDataAsText() const;
enum TimeSelectionType
{
ALL_AVAILABLE,
@ -107,6 +109,7 @@ private:
caf::PdmField<int> m_maxTof;
std::vector<int> m_currentlyPlottedTimeSteps;
std::map<int, RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame> m_timeStepToFlowResultMap;
QPointer<RiuFlowCharacteristicsPlot> m_flowCharPlotWidget;
};

View File

@ -20,6 +20,7 @@
#include "RiaApplication.h"
#include "RiaColorTables.h"
#include "RiaFeatureCommandContext.h"
#include "RiaFontCache.h"
#include "RiaPreferences.h"
@ -34,6 +35,8 @@
#include "cvfBase.h"
#include "cvfColor3.h"
#include "cafCmdFeatureMenuBuilder.h"
#include "qwt_date.h"
#include "qwt_legend.h"
#include "qwt_plot.h"
@ -316,7 +319,33 @@ QSize RiuFlowCharacteristicsPlot::minimumSizeHint() const
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RiuFlowCharacteristicsPlot::contextMenuEvent(QContextMenuEvent* event)
{
if (m_plotDefinition)
{
QString curveDataAsText = m_plotDefinition->curveDataAsText();
QString dialogTitle = "Flow Characteristics";
RiaFeatureCommandContextTextHelper helper(dialogTitle, curveDataAsText);
caf::CmdFeatureMenuBuilder menuBuilder;
menuBuilder << "RicShowPlotDataFeature";
QMenu menu;
menuBuilder.appendToMenu(&menu);
if (menu.actions().size() > 0)
{
menu.exec(event->globalPos());
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuFlowCharacteristicsPlot::sizeHint() const
{

View File

@ -68,6 +68,7 @@ public:
protected:
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
void contextMenuEvent(QContextMenuEvent* event) override;
private:
void setDefaults();