mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-08 23:23:01 -06:00
818 lines
32 KiB
C++
818 lines
32 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 "RimWellAllocationPlot.h"
|
|
|
|
#include "RiaApplication.h"
|
|
|
|
#include "RigAccWellFlowCalculator.h"
|
|
#include "RigEclipseCaseData.h"
|
|
#include "RigFlowDiagResultAddress.h"
|
|
#include "RigFlowDiagResults.h"
|
|
#include "RigSimulationWellCenterLineCalculator.h"
|
|
#include "RigSimulationWellCoordsAndMD.h"
|
|
#include "RigSingleWellResultsData.h"
|
|
|
|
#include "RimEclipseCase.h"
|
|
#include "RimEclipseCellColors.h"
|
|
#include "RimEclipseResultCase.h"
|
|
#include "RimEclipseView.h"
|
|
#include "RimEclipseWellCollection.h"
|
|
#include "RimFlowDiagSolution.h"
|
|
#include "RimProject.h"
|
|
#include "RimSimWellInView.h"
|
|
#include "RimTofAccumulatedPhaseFractionsPlot.h"
|
|
#include "RimTotalWellAllocationPlot.h"
|
|
#include "RimWellAllocationPlotLegend.h"
|
|
#include "RimWellFlowRateCurve.h"
|
|
#include "RimWellLogPlot.h"
|
|
#include "RimWellLogTrack.h"
|
|
|
|
#include "RiuMainPlotWindow.h"
|
|
#include "RiuWellAllocationPlot.h"
|
|
#include "RiuWellLogTrack.h"
|
|
|
|
CAF_PDM_SOURCE_INIT(RimWellAllocationPlot, "WellAllocationPlot");
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
namespace caf
|
|
{
|
|
|
|
template<>
|
|
void AppEnum<RimWellAllocationPlot::FlowType>::setUp()
|
|
{
|
|
addItem(RimWellAllocationPlot::ACCUMULATED, "ACCUMULATED", "Accumulated");
|
|
addItem(RimWellAllocationPlot::INFLOW, "INFLOW", "Inflow Rates");
|
|
setDefault(RimWellAllocationPlot::ACCUMULATED);
|
|
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimWellAllocationPlot::RimWellAllocationPlot()
|
|
{
|
|
CAF_PDM_InitObject("Well Allocation Plot", ":/WellAllocPlot16x16.png", "", "");
|
|
|
|
CAF_PDM_InitField(&m_userName, "PlotDescription", QString("Flow Diagnostics Plot"), "Name", "", "", "");
|
|
m_userName.uiCapability()->setUiReadOnly(true);
|
|
|
|
CAF_PDM_InitField(&m_showPlotTitle, "ShowPlotTitle", true, "Show Plot Title", "", "", "");
|
|
|
|
CAF_PDM_InitFieldNoDefault(&m_case, "CurveCase", "Case", "", "", "");
|
|
m_case.uiCapability()->setUiTreeChildrenHidden(true);
|
|
|
|
CAF_PDM_InitField(&m_timeStep, "PlotTimeStep", 0, "Time Step", "", "", "");
|
|
CAF_PDM_InitField(&m_wellName, "WellName", QString("None"), "Well", "", "", "");
|
|
CAF_PDM_InitFieldNoDefault(&m_flowDiagSolution, "FlowDiagSolution", "Plot Type", "", "", "");
|
|
CAF_PDM_InitFieldNoDefault(&m_flowType, "FlowType", "Flow Type", "", "", "");
|
|
CAF_PDM_InitField(&m_groupSmallContributions, "GroupSmallContributions", true, "Group Small Contributions", "", "", "");
|
|
CAF_PDM_InitField(&m_smallContributionsThreshold, "SmallContributionsThreshold", 0.005, "Threshold", "", "", "");
|
|
CAF_PDM_InitFieldNoDefault(&m_accumulatedWellFlowPlot, "AccumulatedWellFlowPlot", "Accumulated Well Flow", "", "", "");
|
|
m_accumulatedWellFlowPlot.uiCapability()->setUiHidden(true);
|
|
m_accumulatedWellFlowPlot = new RimWellLogPlot;
|
|
m_accumulatedWellFlowPlot->setDepthUnit(RiaDefines::UNIT_NONE);
|
|
m_accumulatedWellFlowPlot->setDepthType(RimWellLogPlot::CONNECTION_NUMBER);
|
|
m_accumulatedWellFlowPlot->setTrackLegendsVisible(false);
|
|
m_accumulatedWellFlowPlot->uiCapability()->setUiIcon(QIcon(":/WellFlowPlot16x16.png"));
|
|
|
|
CAF_PDM_InitFieldNoDefault(&m_totalWellAllocationPlot, "TotalWellFlowPlot", "Total Well Flow", "", "", "");
|
|
m_totalWellAllocationPlot.uiCapability()->setUiHidden(true);
|
|
m_totalWellAllocationPlot = new RimTotalWellAllocationPlot;
|
|
|
|
CAF_PDM_InitFieldNoDefault(&m_wellAllocationPlotLegend, "WellAllocLegend", "Legend", "", "", "");
|
|
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();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimWellAllocationPlot::~RimWellAllocationPlot()
|
|
{
|
|
removeMdiWindowFromMdiArea();
|
|
|
|
delete m_accumulatedWellFlowPlot();
|
|
delete m_totalWellAllocationPlot();
|
|
delete m_tofAccumulatedPhaseFractionsPlot();
|
|
|
|
deleteViewWidget();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellAllocationPlot::setFromSimulationWell(RimSimWellInView* simWell)
|
|
{
|
|
RimEclipseView* eclView;
|
|
simWell->firstAncestorOrThisOfType(eclView);
|
|
RimEclipseResultCase* eclCase;
|
|
simWell->firstAncestorOrThisOfType(eclCase);
|
|
|
|
m_case = eclCase;
|
|
m_wellName = simWell->wellResults()->m_wellName;
|
|
m_timeStep = eclView->currentTimeStep();
|
|
|
|
// Use the active flow diag solutions, or the first one as default
|
|
m_flowDiagSolution = eclView->cellResult()->flowDiagSolution();
|
|
if ( !m_flowDiagSolution )
|
|
{
|
|
m_flowDiagSolution = m_case->defaultFlowDiagSolution();
|
|
}
|
|
|
|
loadDataAndUpdate();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellAllocationPlot::deleteViewWidget()
|
|
{
|
|
if (m_wellAllocationPlotWidget)
|
|
{
|
|
m_wellAllocationPlotWidget->deleteLater();
|
|
m_wellAllocationPlotWidget = nullptr;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellAllocationPlot::updateFromWell()
|
|
{
|
|
// Delete existing tracks
|
|
{
|
|
std::vector<RimWellLogTrack*> tracks;
|
|
accumulatedWellFlowPlot()->descendantsIncludingThisOfType(tracks);
|
|
|
|
for (RimWellLogTrack* t : tracks)
|
|
{
|
|
accumulatedWellFlowPlot()->removeTrack(t);
|
|
delete t;
|
|
}
|
|
}
|
|
|
|
CVF_ASSERT(accumulatedWellFlowPlot()->trackCount() == 0);
|
|
|
|
QString description;
|
|
if (m_flowType() == ACCUMULATED) description = "Accumulated Flow";
|
|
if (m_flowType() == INFLOW) description = "Inflow Rates";
|
|
|
|
accumulatedWellFlowPlot()->setDescription(description + " (" + m_wellName + ")");
|
|
|
|
if (!m_case) return;
|
|
|
|
const RigSingleWellResultsData* wellResults = m_case->eclipseCaseData()->findWellResult(m_wellName);
|
|
|
|
if (!wellResults) return;
|
|
|
|
// Set up the Accumulated Well Flow Calculator
|
|
|
|
std::vector< std::vector <cvf::Vec3d> > pipeBranchesCLCoords;
|
|
std::vector< std::vector <RigWellResultPoint> > pipeBranchesCellIds;
|
|
|
|
RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineFromWellFrame(m_case->eclipseCaseData(),
|
|
wellResults,
|
|
m_timeStep,
|
|
true,
|
|
true,
|
|
pipeBranchesCLCoords,
|
|
pipeBranchesCellIds);
|
|
|
|
std::map<QString, const std::vector<double>* > tracerFractionCellValues = findRelevantTracerCellFractions(wellResults);
|
|
|
|
std::unique_ptr< RigAccWellFlowCalculator > wfCalculator;
|
|
|
|
double smallContributionThreshold = 0.0;
|
|
if (m_groupSmallContributions()) smallContributionThreshold = m_smallContributionsThreshold;
|
|
|
|
if ( tracerFractionCellValues.size() )
|
|
{
|
|
bool isProducer = ( wellResults->wellProductionType(m_timeStep) == RigWellResultFrame::PRODUCER
|
|
|| wellResults->wellProductionType(m_timeStep) == RigWellResultFrame::UNDEFINED_PRODUCTION_TYPE );
|
|
RigEclCellIndexCalculator cellIdxCalc(m_case->eclipseCaseData()->mainGrid(), m_case->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL));
|
|
wfCalculator.reset(new RigAccWellFlowCalculator(pipeBranchesCLCoords,
|
|
pipeBranchesCellIds,
|
|
tracerFractionCellValues,
|
|
cellIdxCalc,
|
|
smallContributionThreshold,
|
|
isProducer));
|
|
}
|
|
else
|
|
{
|
|
if (pipeBranchesCLCoords.size() > 0)
|
|
{
|
|
wfCalculator.reset(new RigAccWellFlowCalculator(pipeBranchesCLCoords,
|
|
pipeBranchesCellIds,
|
|
smallContributionThreshold));
|
|
}
|
|
}
|
|
|
|
auto depthType = accumulatedWellFlowPlot()->depthType();
|
|
|
|
if ( depthType == RimWellLogPlot::MEASURED_DEPTH ) return;
|
|
|
|
// Create tracks and curves from the calculated data
|
|
|
|
size_t branchCount = pipeBranchesCLCoords.size();
|
|
for (size_t brIdx = 0; brIdx < branchCount; ++brIdx)
|
|
{
|
|
// Skip Tiny dummy branches
|
|
if (pipeBranchesCellIds[brIdx].size() <= 3) continue;
|
|
|
|
RimWellLogTrack* plotTrack = new RimWellLogTrack();
|
|
|
|
plotTrack->setDescription(QString("Branch %1").arg(brIdx + 1));
|
|
|
|
accumulatedWellFlowPlot()->addTrack(plotTrack);
|
|
|
|
const std::vector<double>& depthValues = depthType == RimWellLogPlot::CONNECTION_NUMBER ? wfCalculator->connectionNumbersFromTop(brIdx) :
|
|
depthType == RimWellLogPlot::PSEUDO_LENGTH ? wfCalculator->pseudoLengthFromTop(brIdx) :
|
|
depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH ? wfCalculator->trueVerticalDepth(brIdx) :
|
|
std::vector<double>();
|
|
|
|
{
|
|
std::vector<QString> tracerNames = wfCalculator->tracerNames();
|
|
for (const QString& tracerName: tracerNames)
|
|
{
|
|
const std::vector<double>* accFlow = nullptr;
|
|
if (depthType == RimWellLogPlot::CONNECTION_NUMBER)
|
|
{
|
|
accFlow = &(m_flowType == ACCUMULATED ?
|
|
wfCalculator->accumulatedTracerFlowPrConnection(tracerName, brIdx):
|
|
wfCalculator->tracerFlowPrConnection(tracerName, brIdx));
|
|
}
|
|
else if ( depthType == RimWellLogPlot::PSEUDO_LENGTH || depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH)
|
|
{
|
|
accFlow = &(m_flowType == ACCUMULATED ?
|
|
wfCalculator->accumulatedTracerFlowPrPseudoLength(tracerName, brIdx):
|
|
wfCalculator->tracerFlowPrPseudoLength(tracerName, brIdx));
|
|
}
|
|
|
|
addStackedCurve(tracerName, depthValues, *accFlow, plotTrack);
|
|
//TODO: THIs is the data to be plotted...
|
|
}
|
|
}
|
|
|
|
|
|
updateWellFlowPlotXAxisTitle(plotTrack);
|
|
|
|
}
|
|
|
|
QString wellStatusText = QString("(%1)").arg(RimWellAllocationPlot::wellStatusTextForTimeStep(m_wellName, m_case, m_timeStep));
|
|
|
|
QString flowTypeText = m_flowDiagSolution() ? "Well Allocation": "Well Flow";
|
|
setDescription(flowTypeText + ": " + m_wellName + " " + wellStatusText + ", " + m_case->timeStepStrings()[m_timeStep] + " (" + m_case->caseUserDescription() + ")");
|
|
|
|
/// Pie chart
|
|
|
|
m_totalWellAllocationPlot->clearSlices();
|
|
if (m_wellAllocationPlotWidget) m_wellAllocationPlotWidget->clearLegend();
|
|
|
|
if (wfCalculator)
|
|
{
|
|
std::vector<std::pair<QString, double> > totalTracerFractions = wfCalculator->totalTracerFractions() ;
|
|
|
|
for ( const auto& tracerVal : totalTracerFractions )
|
|
{
|
|
cvf::Color3f color;
|
|
if (m_flowDiagSolution)
|
|
color = m_flowDiagSolution->tracerColor(tracerVal.first);
|
|
else
|
|
color = getTracerColor(tracerVal.first);
|
|
|
|
double tracerPercent = 100*tracerVal.second;
|
|
|
|
m_totalWellAllocationPlot->addSlice(tracerVal.first, color, tracerPercent);
|
|
if ( m_wellAllocationPlotWidget ) m_wellAllocationPlotWidget->addLegendItem(tracerVal.first, color, tracerPercent);
|
|
}
|
|
}
|
|
|
|
if (m_wellAllocationPlotWidget) m_wellAllocationPlotWidget->showLegend(m_wellAllocationPlotLegend->isShowingLegend());
|
|
m_totalWellAllocationPlot->updateConnectedEditors();
|
|
|
|
accumulatedWellFlowPlot()->updateConnectedEditors();
|
|
|
|
m_tofAccumulatedPhaseFractionsPlot->reloadFromWell();
|
|
m_tofAccumulatedPhaseFractionsPlot->updateConnectedEditors();
|
|
|
|
if (m_wellAllocationPlotWidget) m_wellAllocationPlotWidget->updateGeometry();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::map<QString, const std::vector<double> *> RimWellAllocationPlot::findRelevantTracerCellFractions(const RigSingleWellResultsData* wellResults)
|
|
{
|
|
std::map<QString, const std::vector<double> *> tracerCellFractionValues;
|
|
|
|
if ( m_flowDiagSolution && wellResults->hasWellResult(m_timeStep) )
|
|
{
|
|
RimFlowDiagSolution::TracerStatusType requestedTracerType = RimFlowDiagSolution::UNDEFINED;
|
|
|
|
const RigWellResultFrame::WellProductionType prodType = wellResults->wellProductionType(m_timeStep);
|
|
if ( prodType == RigWellResultFrame::PRODUCER
|
|
|| prodType == RigWellResultFrame::UNDEFINED_PRODUCTION_TYPE )
|
|
{
|
|
requestedTracerType = RimFlowDiagSolution::INJECTOR;
|
|
}
|
|
else
|
|
{
|
|
requestedTracerType = RimFlowDiagSolution::PRODUCER;
|
|
}
|
|
|
|
std::vector<QString> tracerNames = m_flowDiagSolution->tracerNames();
|
|
for ( const QString& tracerName : tracerNames )
|
|
{
|
|
if ( m_flowDiagSolution->tracerStatusInTimeStep(tracerName, m_timeStep) == requestedTracerType )
|
|
{
|
|
RigFlowDiagResultAddress resAddr(RIG_FLD_CELL_FRACTION_RESNAME, RigFlowDiagResultAddress::PHASE_ALL, tracerName.toStdString());
|
|
const std::vector<double>* tracerCellFractions = m_flowDiagSolution->flowDiagResults()->resultValues(resAddr, m_timeStep);
|
|
if (tracerCellFractions) tracerCellFractionValues[tracerName] = tracerCellFractions;
|
|
}
|
|
}
|
|
}
|
|
|
|
return tracerCellFractionValues;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellAllocationPlot::updateWellFlowPlotXAxisTitle(RimWellLogTrack* plotTrack)
|
|
{
|
|
RiaEclipseUnitTools::UnitSystem unitSet = m_case->eclipseCaseData()->unitsType();
|
|
|
|
|
|
if (m_flowDiagSolution)
|
|
{
|
|
QString unitText;
|
|
switch ( unitSet )
|
|
{
|
|
case RiaEclipseUnitTools::UNITS_METRIC:
|
|
unitText = "[m<sup>3</sup>/day]";
|
|
break;
|
|
case RiaEclipseUnitTools::UNITS_FIELD:
|
|
unitText = "[Brl/day]";
|
|
break;
|
|
case RiaEclipseUnitTools::UNITS_LAB:
|
|
unitText = "[cm<sup>3</sup>/hr]";
|
|
break;
|
|
default:
|
|
break;
|
|
|
|
}
|
|
plotTrack->setXAxisTitle("Reservoir Flow Rate " + unitText);
|
|
}
|
|
else
|
|
{
|
|
QString unitText;
|
|
switch ( unitSet )
|
|
{
|
|
case RiaEclipseUnitTools::UNITS_METRIC:
|
|
unitText = "[Liquid Sm<sup>3</sup>/day], [Gas kSm<sup>3</sup>/day]";
|
|
break;
|
|
case RiaEclipseUnitTools::UNITS_FIELD:
|
|
unitText = "[Liquid BBL/day], [Gas BOE/day]";
|
|
break;
|
|
case RiaEclipseUnitTools::UNITS_LAB:
|
|
unitText = "[cm<sup>3</sup>/hr]";
|
|
break;
|
|
default:
|
|
break;
|
|
|
|
}
|
|
plotTrack->setXAxisTitle("Surface Flow Rate " + unitText);
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellAllocationPlot::addStackedCurve(const QString& tracerName,
|
|
const std::vector<double>& depthValues,
|
|
const std::vector<double>& accFlow,
|
|
RimWellLogTrack* plotTrack)
|
|
{
|
|
RimWellFlowRateCurve* curve = new RimWellFlowRateCurve;
|
|
curve->setFlowValuesPrDepthValue(tracerName, depthValues, accFlow);
|
|
|
|
if ( m_flowDiagSolution )
|
|
{
|
|
curve->setColor(m_flowDiagSolution->tracerColor(tracerName));
|
|
}
|
|
else
|
|
{
|
|
curve->setColor(getTracerColor(tracerName));
|
|
}
|
|
|
|
plotTrack->addCurve(curve);
|
|
|
|
curve->loadDataAndUpdate(true);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellAllocationPlot::updateWidgetTitleWindowTitle()
|
|
{
|
|
updateMdiWindowTitle();
|
|
|
|
if (m_wellAllocationPlotWidget)
|
|
{
|
|
if (m_showPlotTitle)
|
|
{
|
|
m_wellAllocationPlotWidget->showTitle(m_userName);
|
|
}
|
|
else
|
|
{
|
|
m_wellAllocationPlotWidget->hideTitle();
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimWellAllocationPlot::wellStatusTextForTimeStep(const QString& wellName, const RimEclipseResultCase* eclipseResultCase, size_t timeStep)
|
|
{
|
|
QString statusText = "Undefined";
|
|
|
|
if (eclipseResultCase)
|
|
{
|
|
const RigSingleWellResultsData* wellResults = eclipseResultCase->eclipseCaseData()->findWellResult(wellName);
|
|
|
|
if (wellResults)
|
|
{
|
|
if (wellResults->hasWellResult(timeStep))
|
|
{
|
|
const RigWellResultFrame& wellResultFrame = wellResults->wellResultFrame(timeStep);
|
|
|
|
RigWellResultFrame::WellProductionType prodType = wellResultFrame.m_productionType;
|
|
|
|
switch (prodType)
|
|
{
|
|
case RigWellResultFrame::PRODUCER:
|
|
statusText = "Producer";
|
|
break;
|
|
case RigWellResultFrame::OIL_INJECTOR:
|
|
statusText = "Oil Injector";
|
|
break;
|
|
case RigWellResultFrame::GAS_INJECTOR:
|
|
statusText = "Gas Injector";
|
|
break;
|
|
case RigWellResultFrame::WATER_INJECTOR:
|
|
statusText = "Water Injector";
|
|
break;
|
|
case RigWellResultFrame::UNDEFINED_PRODUCTION_TYPE:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return statusText;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QWidget* RimWellAllocationPlot::viewWidget()
|
|
{
|
|
return m_wellAllocationPlotWidget;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellAllocationPlot::zoomAll()
|
|
{
|
|
m_accumulatedWellFlowPlot()->zoomAll();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimWellLogPlot* RimWellAllocationPlot::accumulatedWellFlowPlot()
|
|
{
|
|
return m_accumulatedWellFlowPlot();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimTotalWellAllocationPlot* RimWellAllocationPlot::totalWellFlowPlot()
|
|
{
|
|
return m_totalWellAllocationPlot();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimTofAccumulatedPhaseFractionsPlot * RimWellAllocationPlot::tofAccumulatedPhaseFractionsPlot()
|
|
{
|
|
return m_tofAccumulatedPhaseFractionsPlot();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
caf::PdmObject* RimWellAllocationPlot::plotLegend()
|
|
{
|
|
return m_wellAllocationPlotLegend;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimEclipseResultCase* RimWellAllocationPlot::rimCase()
|
|
{
|
|
return m_case();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
int RimWellAllocationPlot::timeStep()
|
|
{
|
|
return m_timeStep();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QList<caf::PdmOptionItemInfo> RimWellAllocationPlot::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly)
|
|
{
|
|
QList<caf::PdmOptionItemInfo> options;
|
|
|
|
if (fieldNeedingOptions == &m_wellName)
|
|
{
|
|
std::set<QString> sortedWellNames = this->findSortedWellNames();
|
|
|
|
QIcon simWellIcon(":/Well.png");
|
|
for ( const QString& wname: sortedWellNames )
|
|
{
|
|
options.push_back(caf::PdmOptionItemInfo(wname, wname, false, simWellIcon));
|
|
}
|
|
|
|
if (options.size() == 0)
|
|
{
|
|
options.push_front(caf::PdmOptionItemInfo("None", nullptr));
|
|
}
|
|
}
|
|
else if (fieldNeedingOptions == &m_timeStep)
|
|
{
|
|
QStringList timeStepNames;
|
|
|
|
if (m_case && m_case->eclipseCaseData())
|
|
{
|
|
timeStepNames = m_case->timeStepStrings();
|
|
}
|
|
|
|
for (int i = 0; i < timeStepNames.size(); i++)
|
|
{
|
|
options.push_back(caf::PdmOptionItemInfo(timeStepNames[i], i));
|
|
}
|
|
}
|
|
else if (fieldNeedingOptions == &m_case)
|
|
{
|
|
RimProject* proj = nullptr;
|
|
this->firstAncestorOrThisOfType(proj);
|
|
if (proj)
|
|
{
|
|
std::vector<RimEclipseResultCase*> cases;
|
|
proj->descendantsIncludingThisOfType(cases);
|
|
|
|
for (RimEclipseResultCase* c : cases)
|
|
{
|
|
options.push_back(caf::PdmOptionItemInfo(c->caseUserDescription(), c, false, c->uiIcon()));
|
|
}
|
|
}
|
|
}
|
|
else if (fieldNeedingOptions == &m_flowDiagSolution)
|
|
{
|
|
if (m_case)
|
|
{
|
|
//std::vector<RimFlowDiagSolution*> flowSols = m_case->flowDiagSolutions();
|
|
// options.push_back(caf::PdmOptionItemInfo("None", nullptr));
|
|
//for (RimFlowDiagSolution* flowSol : flowSols)
|
|
//{
|
|
// options.push_back(caf::PdmOptionItemInfo(flowSol->userDescription(), flowSol, false, flowSol->uiIcon()));
|
|
//}
|
|
|
|
RimFlowDiagSolution* defaultFlowSolution = m_case->defaultFlowDiagSolution();
|
|
options.push_back(caf::PdmOptionItemInfo("Well Flow", nullptr));
|
|
if (defaultFlowSolution)
|
|
{
|
|
options.push_back(caf::PdmOptionItemInfo("Allocation", defaultFlowSolution ));
|
|
}
|
|
}
|
|
}
|
|
|
|
return options;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimWellAllocationPlot::wellName() const
|
|
{
|
|
return m_wellName();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellAllocationPlot::removeFromMdiAreaAndDeleteViewWidget()
|
|
{
|
|
removeMdiWindowFromMdiArea();
|
|
deleteViewWidget();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellAllocationPlot::showPlotLegend(bool doShow)
|
|
{
|
|
if (m_wellAllocationPlotWidget) m_wellAllocationPlotWidget->showLegend(doShow);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellAllocationPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
|
{
|
|
RimViewWindow::fieldChangedByUi(changedField, oldValue, newValue);
|
|
|
|
if (changedField == &m_userName ||
|
|
changedField == &m_showPlotTitle)
|
|
{
|
|
updateWidgetTitleWindowTitle();
|
|
}
|
|
else if ( changedField == &m_case)
|
|
{
|
|
if ( m_flowDiagSolution && m_case )
|
|
{
|
|
m_flowDiagSolution = m_case->defaultFlowDiagSolution();
|
|
}
|
|
else
|
|
{
|
|
m_flowDiagSolution = nullptr;
|
|
}
|
|
|
|
if (!m_case) m_timeStep = 0;
|
|
else if (m_timeStep >= static_cast<int>(m_case->timeStepDates().size()))
|
|
{
|
|
m_timeStep = std::max(0, ((int)m_case->timeStepDates().size()) - 1);
|
|
}
|
|
|
|
std::set<QString> sortedWellNames = findSortedWellNames();
|
|
if (!sortedWellNames.size()) m_wellName = "";
|
|
else if ( sortedWellNames.count(m_wellName()) == 0 ){ m_wellName = *sortedWellNames.begin();}
|
|
|
|
loadDataAndUpdate();
|
|
}
|
|
else if ( changedField == &m_wellName
|
|
|| changedField == &m_timeStep
|
|
|| changedField == &m_flowDiagSolution
|
|
|| changedField == &m_groupSmallContributions
|
|
|| changedField == &m_smallContributionsThreshold
|
|
|| changedField == &m_flowType )
|
|
{
|
|
loadDataAndUpdate();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::set<QString> RimWellAllocationPlot::findSortedWellNames()
|
|
{
|
|
std::set<QString> sortedWellNames;
|
|
if ( m_case && m_case->eclipseCaseData() )
|
|
{
|
|
const cvf::Collection<RigSingleWellResultsData>& wellRes = m_case->eclipseCaseData()->wellResults();
|
|
|
|
for ( size_t wIdx = 0; wIdx < wellRes.size(); ++wIdx )
|
|
{
|
|
sortedWellNames.insert(wellRes[wIdx]->m_wellName);
|
|
}
|
|
}
|
|
|
|
return sortedWellNames;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QImage RimWellAllocationPlot::snapshotWindowContent()
|
|
{
|
|
QImage image;
|
|
|
|
if (m_wellAllocationPlotWidget)
|
|
{
|
|
QPixmap pix = QPixmap::grabWidget(m_wellAllocationPlotWidget);
|
|
image = pix.toImage();
|
|
}
|
|
|
|
return image;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellAllocationPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
|
{
|
|
uiOrdering.add(&m_userName);
|
|
uiOrdering.add(&m_showPlotTitle);
|
|
|
|
caf::PdmUiGroup& dataGroup = *uiOrdering.addNewGroup("Plot Data");
|
|
dataGroup.add(&m_case);
|
|
dataGroup.add(&m_timeStep);
|
|
dataGroup.add(&m_wellName);
|
|
|
|
caf::PdmUiGroup& optionGroup = *uiOrdering.addNewGroup("Options");
|
|
optionGroup.add(&m_flowDiagSolution);
|
|
optionGroup.add(&m_flowType);
|
|
optionGroup.add(&m_groupSmallContributions);
|
|
optionGroup.add(&m_smallContributionsThreshold);
|
|
m_smallContributionsThreshold.uiCapability()->setUiReadOnly(!m_groupSmallContributions());
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellAllocationPlot::setDescription(const QString& description)
|
|
{
|
|
m_userName = description;
|
|
|
|
updateWidgetTitleWindowTitle();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimWellAllocationPlot::description() const
|
|
{
|
|
return m_userName();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellAllocationPlot::loadDataAndUpdate()
|
|
{
|
|
updateMdiWindowVisibility();
|
|
updateFromWell();
|
|
m_accumulatedWellFlowPlot->loadDataAndUpdate();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QWidget* RimWellAllocationPlot::createViewWidget(QWidget* mainWindowParent)
|
|
{
|
|
m_wellAllocationPlotWidget = new RiuWellAllocationPlot(this, mainWindowParent);
|
|
return m_wellAllocationPlotWidget;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
cvf::Color3f RimWellAllocationPlot::getTracerColor(const QString& tracerName)
|
|
{
|
|
|
|
if (tracerName == RIG_FLOW_OIL_NAME) return cvf::Color3f::DARK_GREEN;
|
|
if (tracerName == RIG_FLOW_GAS_NAME) return cvf::Color3f::DARK_RED;
|
|
if (tracerName == RIG_FLOW_WATER_NAME) return cvf::Color3f::BLUE;
|
|
return cvf::Color3f::DARK_GRAY;
|
|
}
|
|
|