ResInsight/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.cpp
Magne Sjaastad 1841379e64 #2127 Sim Well Branches : Major refactor of sim well branch computation
Remove local branch geometry caches
Add checkbox to control if branch detection should be used
Add RiaSimWllBranchTools and move helper functions from RimProject
2017-12-08 10:24:14 +01:00

842 lines
34 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 "RigSimWellData.h"
#include "RimEclipseCase.h"
#include "RimEclipseCellColors.h"
#include "RimEclipseResultCase.h"
#include "RimEclipseView.h"
#include "RimSimWellInViewCollection.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"
#include "RimWellLogFile.h"
#include "RimWellPlotTools.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->simWellData()->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();
}
onLoadDataAndUpdate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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 RigSimWellData* simWellData = m_case->eclipseCaseData()->findSimWellData(m_wellName);
if (!simWellData) 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(),
simWellData,
m_timeStep,
true,
true,
pipeBranchesCLCoords,
pipeBranchesCellIds);
std::map<QString, const std::vector<double>* > tracerFractionCellValues = findRelevantTracerCellFractions(simWellData);
std::unique_ptr< RigAccWellFlowCalculator > wfCalculator;
double smallContributionThreshold = 0.0;
if (m_groupSmallContributions()) smallContributionThreshold = m_smallContributionsThreshold;
if ( tracerFractionCellValues.size() )
{
bool isProducer = ( simWellData->wellProductionType(m_timeStep) == RigWellResultFrame::PRODUCER
|| simWellData->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));
plotTrack->setFormationBranchIndex((int)brIdx);
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 RigSimWellData* simWellData)
{
std::map<QString, const std::vector<double> *> tracerCellFractionValues;
if ( m_flowDiagSolution && simWellData->hasWellResult(m_timeStep) )
{
RimFlowDiagSolution::TracerStatusType requestedTracerType = RimFlowDiagSolution::UNDEFINED;
const RigWellResultFrame::WellProductionType prodType = simWellData->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();
RimWellLogFile::WellFlowCondition condition = m_flowDiagSolution ? RimWellLogFile::WELL_FLOW_COND_RESERVOIR :
RimWellLogFile::WELL_FLOW_COND_STANDARD;
QString axisTitle = RimWellPlotTools::flowPlotAxisTitle(condition, unitSet);
plotTrack->setXAxisTitle(axisTitle);
#if 0
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);
}
#endif
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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 RigSimWellData* simWellData = eclipseResultCase->eclipseCaseData()->findSimWellData(wellName);
if (simWellData)
{
if (simWellData->hasWellResult(timeStep))
{
const RigWellResultFrame& wellResultFrame = simWellData->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();}
onLoadDataAndUpdate();
}
else if ( changedField == &m_wellName
|| changedField == &m_timeStep
|| changedField == &m_flowDiagSolution
|| changedField == &m_groupSmallContributions
|| changedField == &m_smallContributionsThreshold
|| changedField == &m_flowType )
{
onLoadDataAndUpdate();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<QString> RimWellAllocationPlot::findSortedWellNames()
{
std::set<QString> sortedWellNames;
if ( m_case && m_case->eclipseCaseData() )
{
const cvf::Collection<RigSimWellData>& simWellData = m_case->eclipseCaseData()->wellResults();
for ( size_t wIdx = 0; wIdx < simWellData.size(); ++wIdx )
{
sortedWellNames.insert(simWellData[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::onLoadDataAndUpdate()
{
updateMdiWindowVisibility();
updateFromWell();
m_accumulatedWellFlowPlot->loadDataAndUpdate();
updateFormationNamesData();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellAllocationPlot::updateFormationNamesData() const
{
for (size_t i = 0; i < m_accumulatedWellFlowPlot->trackCount(); ++i)
{
RimWellLogTrack* track = m_accumulatedWellFlowPlot->trackByIndex(i);
track->setAndUpdateSimWellFormationNamesData(m_case, m_wellName);
}
}