mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-09 23:16:00 -06:00
#4136 Export of Flow Characteristics : Create text for export and add context menu
This commit is contained in:
parent
79df075fe4
commit
7879fe186d
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -68,6 +68,7 @@ public:
|
||||
protected:
|
||||
QSize sizeHint() const override;
|
||||
QSize minimumSizeHint() const override;
|
||||
void contextMenuEvent(QContextMenuEvent* event) override;
|
||||
|
||||
private:
|
||||
void setDefaults();
|
||||
|
Loading…
Reference in New Issue
Block a user