///////////////////////////////////////////////////////////////////////////////// // // 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 "RimFlowCharacteristicsPlot.h" #include "RigFlowDiagResults.h" #include "RimEclipseResultCase.h" #include "RimFlowDiagSolution.h" #include "RimProject.h" #include "RiuFlowCharacteristicsPlot.h" #include "cafPdmUiCheckBoxEditor.h" #include <cmath> // Needed for HUGE_VAL on Linux namespace caf { template<> void AppEnum< RimFlowCharacteristicsPlot::TimeSelectionType >::setUp() { addItem(RimFlowCharacteristicsPlot::ALL_AVAILABLE, "ALL_AVAILABLE", "All available"); addItem(RimFlowCharacteristicsPlot::SELECT_AVAILABLE, "SELECT_AVAILABLE", "Select"); setDefault(RimFlowCharacteristicsPlot::ALL_AVAILABLE); } } CAF_PDM_SOURCE_INIT(RimFlowCharacteristicsPlot, "FlowCharacteristicsPlot"); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimFlowCharacteristicsPlot::RimFlowCharacteristicsPlot() { CAF_PDM_InitObject("Flow Characteristics", ":/WellAllocPie16x16.png", "", ""); CAF_PDM_InitFieldNoDefault(&m_case, "FlowCase", "Case", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_flowDiagSolution, "FlowDiagSolution", "Flow Diag Solution", "", "", ""); m_flowDiagSolution.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&m_timeStepSelectionType, "TimeSelectionType", "Time Steps", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_selectedTimeSteps, "SelectedTimeSteps", "", "", "", ""); CAF_PDM_InitField(&m_showLegend, "ShowLegend", true, "Legend", "", "", ""); this->m_showWindow = false; setAsPlotMdiWindow(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimFlowCharacteristicsPlot::~RimFlowCharacteristicsPlot() { removeMdiWindowFromMdiArea(); deleteViewWidget(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFlowCharacteristicsPlot::setFromFlowSolution(RimFlowDiagSolution* flowSolution) { if ( !flowSolution ) { m_case = nullptr; } else { RimEclipseResultCase* eclCase; flowSolution->firstAncestorOrThisOfType(eclCase); m_case = eclCase; } m_flowDiagSolution = flowSolution; m_showWindow = true; loadDataAndUpdate(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFlowCharacteristicsPlot::deleteViewWidget() { if (m_flowCharPlotWidget) { m_flowCharPlotWidget->deleteLater(); m_flowCharPlotWidget= nullptr; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFlowCharacteristicsPlot::updateCurrentTimeStep() { if (m_timeStepSelectionType() != ALL_AVAILABLE) return; if (!m_flowDiagSolution()) return; RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults(); std::vector<int> calculatedTimesteps = flowResult->calculatedTimeSteps(); if (m_currentlyPlottedTimeSteps == calculatedTimesteps) return; this->loadDataAndUpdate(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QList<caf::PdmOptionItemInfo> RimFlowCharacteristicsPlot::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) { QList<caf::PdmOptionItemInfo> options; if ( fieldNeedingOptions == &m_case ) { RimProject* proj = nullptr; this->firstAncestorOrThisOfType(proj); if ( proj ) { std::vector<RimEclipseResultCase*> cases; proj->descendantsIncludingThisOfType(cases); RimEclipseResultCase* defaultCase = nullptr; for ( RimEclipseResultCase* c : cases ) { if ( c->defaultFlowDiagSolution() ) { options.push_back(caf::PdmOptionItemInfo(c->caseUserDescription(), c, false, c->uiIcon())); if (!defaultCase) defaultCase = c; // Select first } } if (!m_case() && defaultCase) m_case = defaultCase; } } 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())); } } } else if ( fieldNeedingOptions == &m_selectedTimeSteps ) { if ( m_flowDiagSolution ) { RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults(); std::vector<int> calculatedTimesteps = flowResult->calculatedTimeSteps(); QStringList timeStepDates = m_case->timeStepStrings(); for ( int tsIdx : calculatedTimesteps ) { options.push_back(caf::PdmOptionItemInfo(timeStepDates[tsIdx], tsIdx)); } } } return options; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFlowCharacteristicsPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { uiOrdering.add(&m_case); uiOrdering.add(&m_flowDiagSolution); uiOrdering.add(&m_timeStepSelectionType); if (m_timeStepSelectionType == SELECT_AVAILABLE) uiOrdering.add(&m_selectedTimeSteps); uiOrdering.add(&m_showLegend); uiOrdering.skipRemainingFields(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QWidget* RimFlowCharacteristicsPlot::viewWidget() { return m_flowCharPlotWidget; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFlowCharacteristicsPlot::zoomAll() { if (m_flowCharPlotWidget) m_flowCharPlotWidget->zoomAll(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFlowCharacteristicsPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { RimViewWindow::fieldChangedByUi(changedField, oldValue, newValue); if ( &m_case == changedField ) { m_flowDiagSolution = m_case->defaultFlowDiagSolution(); m_currentlyPlottedTimeSteps.clear(); } // All fields update plot this->loadDataAndUpdate(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QImage RimFlowCharacteristicsPlot::snapshotWindowContent() { QImage image; if (m_flowCharPlotWidget) { QPixmap pix = QPixmap::grabWidget(m_flowCharPlotWidget); image = pix.toImage(); } return image; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimFlowCharacteristicsPlot::loadDataAndUpdate() { updateMdiWindowVisibility(); if (m_flowDiagSolution && m_flowCharPlotWidget) { RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults(); std::vector<int> calculatedTimesteps = flowResult->calculatedTimeSteps(); if (m_timeStepSelectionType == SELECT_AVAILABLE) { // Find set intersection of selected and available time steps std::set<int> calculatedTimeStepsSet; calculatedTimeStepsSet.insert(calculatedTimesteps.begin(), calculatedTimesteps.end()); calculatedTimesteps.clear(); auto selectedTimeSteps = m_selectedTimeSteps(); for (int tsIdx : selectedTimeSteps) { if (calculatedTimeStepsSet.count(tsIdx)) calculatedTimesteps.push_back(tsIdx); } } m_currentlyPlottedTimeSteps = calculatedTimesteps; std::vector<QDateTime> timeStepDates = m_case->timeStepDates(); QStringList timeStepStrings = m_case->timeStepStrings(); std::vector<double> lorenzVals(timeStepDates.size(), HUGE_VAL); m_flowCharPlotWidget->removeAllCurves(); for ( int timeStepIdx: calculatedTimesteps ) { lorenzVals[timeStepIdx] = flowResult->flowCharacteristicsResults(timeStepIdx).m_lorenzCoefficient; } m_flowCharPlotWidget->setLorenzCurve(timeStepStrings, timeStepDates, lorenzVals); for ( int timeStepIdx: calculatedTimesteps ) { const auto & flowCharResults = flowResult->flowCharacteristicsResults(timeStepIdx); m_flowCharPlotWidget->addFlowCapStorageCapCurve(timeStepDates[timeStepIdx], flowCharResults.m_flowCapStorageCapCurve.first, flowCharResults.m_flowCapStorageCapCurve.second); m_flowCharPlotWidget->addSweepEfficiencyCurve(timeStepDates[timeStepIdx], flowCharResults.m_sweepEfficiencyCurve.first, flowCharResults.m_sweepEfficiencyCurve.second); } m_flowCharPlotWidget->showLegend(m_showLegend()); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QWidget* RimFlowCharacteristicsPlot::createViewWidget(QWidget* mainWindowParent) { m_flowCharPlotWidget = new RiuFlowCharacteristicsPlot(this, mainWindowParent); return m_flowCharPlotWidget; }