From 65ce0d3788182e5c020b5972f5f88ef807e00d0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rnar=20Grip=20Fj=C3=A6r?= Date: Thu, 17 Aug 2017 11:24:51 +0200 Subject: [PATCH] #1377 Flow Characteristics Plot: Calculate for a defined set of cells --- .../Flow/RimFlowCharacteristicsPlot.cpp | 228 ++++++++++++++++-- .../Flow/RimFlowCharacteristicsPlot.h | 9 + .../RimEclipseResultDefinition.cpp | 16 +- .../RimEclipseResultDefinition.h | 2 +- .../ReservoirDataModel/RigFlowDiagResults.cpp | 104 +++++++- .../ReservoirDataModel/RigFlowDiagResults.h | 17 +- .../RigFlowDiagSolverInterface.cpp | 9 +- .../RigFlowDiagSolverInterface.h | 1 + Fwk/AppFwk/CommonCode/cafUtils.cpp | 16 ++ Fwk/AppFwk/CommonCode/cafUtils.h | 2 + 10 files changed, 365 insertions(+), 39 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp index 1a25c08d6e..269d3098ae 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp @@ -23,10 +23,18 @@ #include "RimEclipseResultCase.h" #include "RimFlowDiagSolution.h" #include "RimProject.h" +#include "RimEclipseCellColors.h" +#include "RimEclipseView.h" + +#include "RicEclipsePropertyFilterFeatureImpl.h" #include "RiuFlowCharacteristicsPlot.h" +#include "RiuMainWindow.h" #include "cafPdmUiCheckBoxEditor.h" +#include "cafPdmUiListEditor.h" +#include "cafPdmUiPushButtonEditor.h" +#include "cafUtils.h" #include @@ -35,13 +43,13 @@ 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); -} + 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"); @@ -60,10 +68,28 @@ RimFlowCharacteristicsPlot::RimFlowCharacteristicsPlot() CAF_PDM_InitFieldNoDefault(&m_timeStepSelectionType, "TimeSelectionType", "Time Steps", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_selectedTimeSteps, "SelectedTimeSteps", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_applyTimeSteps, "ApplyTimeSteps", "", "", "", ""); + m_applyTimeSteps.xmlCapability()->setIOWritable(false); + m_applyTimeSteps.xmlCapability()->setIOReadable(false); + m_applyTimeSteps.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + m_applyTimeSteps.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); CAF_PDM_InitField(&m_maxPvFraction, "CellPVThreshold", 0.1, "Aquifer Cell Threshold", "", "Exclude Aquifer Effects by adding a Cell Pore Volume Threshold as Fraction of Total Pore Volume.", ""); + CAF_PDM_InitField(&m_showLegend, "ShowLegend", true, "Legend", "", "", ""); + // Region group + CAF_PDM_InitFieldNoDefault(&m_cellSelection, "CellSelection", "Cell Selection", "", "", ""); + CAF_PDM_InitField(&m_tracerFilter, "TracerFilter", QString(), "Filter", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_selectedTracerNames, "SelectedTracerNames", " ", "", "", ""); + m_selectedTracerNames.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); + CAF_PDM_InitFieldNoDefault(&m_showRegion, "ShowRegion", "", "", "", ""); + m_showRegion.xmlCapability()->setIOWritable(false); + m_showRegion.xmlCapability()->setIOReadable(false); + m_showRegion.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + m_showRegion.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + + this->m_showWindow = false; setAsPlotMdiWindow(); } @@ -173,14 +199,66 @@ QList RimFlowCharacteristicsPlot::calculateValueOptions( { if ( m_flowDiagSolution ) { - RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults(); - std::vector calculatedTimesteps = flowResult->calculatedTimeSteps(RigFlowDiagResultAddress::PHASE_ALL); - QStringList timeStepDates = m_case->timeStepStrings(); - - for ( int tsIdx : calculatedTimesteps ) + std::vector calculatedTimeSteps = m_flowDiagSolution()->flowDiagResults()->calculatedTimeSteps(RigFlowDiagResultAddress::PHASE_ALL); + for (int tsIdx = 0; tsIdx < timeStepDates.size(); ++tsIdx) { - options.push_back(caf::PdmOptionItemInfo(timeStepDates[tsIdx], tsIdx)); + auto it = std::find(calculatedTimeSteps.begin(), calculatedTimeSteps.end(), tsIdx); + QString itemText = timeStepDates[tsIdx]; + if (it == calculatedTimeSteps.end()) + { + itemText = itemText + " *"; + } + options.push_back(caf::PdmOptionItemInfo(itemText, tsIdx)); + } + } + } + else if (fieldNeedingOptions == &m_selectedTracerNames) + { + if (m_flowDiagSolution) + { + std::vector tracerNames = m_flowDiagSolution->tracerNames(); + for (QString tracerName : tracerNames) + { + if (!caf::Utils::isStringMatch(m_tracerFilter, tracerName)) continue; + + RimFlowDiagSolution::TracerStatusType tracerStatus = m_flowDiagSolution->tracerStatusOverall(tracerName); + if (tracerStatus == RimFlowDiagSolution::CLOSED) continue; + + if (m_cellSelection() == RigFlowDiagResults::CELLS_FLOODED) + { + if (tracerStatus == RimFlowDiagSolution::INJECTOR || tracerStatus == RimFlowDiagSolution::VARYING) + { + options.push_back(caf::PdmOptionItemInfo(tracerName, tracerName)); + } + } + else if (m_cellSelection() == RigFlowDiagResults::CELLS_DRAINED) + { + if (tracerStatus == RimFlowDiagSolution::PRODUCER || tracerStatus == RimFlowDiagSolution::VARYING) + { + options.push_back(caf::PdmOptionItemInfo(tracerName, tracerName)); + } + } + else if (m_cellSelection() == RigFlowDiagResults::CELLS_COMMUNICATION) + { + QString prefix; + switch (tracerStatus) + { + case RimFlowDiagSolution::INJECTOR: + prefix = "I : "; + break; + case RimFlowDiagSolution::PRODUCER: + prefix = "P : "; + break; + case RimFlowDiagSolution::VARYING: + prefix = "I/P: "; + break; + case RimFlowDiagSolution::UNDEFINED: + prefix = "U : "; + break; + } + options.push_back(caf::PdmOptionItemInfo(prefix + tracerName, tracerName)); + } } } } @@ -198,14 +276,52 @@ void RimFlowCharacteristicsPlot::defineUiOrdering(QString uiConfigName, caf::Pdm uiOrdering.add(&m_flowDiagSolution); uiOrdering.add(&m_timeStepSelectionType); - if (m_timeStepSelectionType == SELECT_AVAILABLE) uiOrdering.add(&m_selectedTimeSteps); + if (m_timeStepSelectionType == SELECT_AVAILABLE) + { + uiOrdering.add(&m_selectedTimeSteps); + uiOrdering.add(&m_applyTimeSteps); + } uiOrdering.add(&m_showLegend); uiOrdering.add(&m_maxPvFraction); + { + caf::PdmUiGroup* regionGroup = uiOrdering.addNewGroup("Region"); + regionGroup->add(&m_cellSelection); + if (m_cellSelection() != RigFlowDiagResults::CELLS_ACTIVE) + { + regionGroup->add(&m_tracerFilter); + regionGroup->add(&m_selectedTracerNames); + } + regionGroup->add(&m_showRegion); + } + uiOrdering.skipRemainingFields(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFlowCharacteristicsPlot::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +{ + if (field == &m_applyTimeSteps) + { + caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast(attribute); + if (attrib) + { + attrib->m_buttonText = "Apply"; + } + } + else if (field == &m_showRegion) + { + caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast(attribute); + if (attrib) + { + attrib->m_buttonText = "Show Region"; + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -234,6 +350,77 @@ void RimFlowCharacteristicsPlot::fieldChangedByUi(const caf::PdmFieldHandle* cha m_flowDiagSolution = m_case->defaultFlowDiagSolution(); m_currentlyPlottedTimeSteps.clear(); } + else if (&m_applyTimeSteps == changedField) + { + if (m_flowDiagSolution) + { + // Compute any missing time steps from selected + for (int tsIdx : m_selectedTimeSteps()) + { + m_flowDiagSolution()->flowDiagResults()->maxAbsPairFlux(tsIdx); + } + } + m_applyTimeSteps = false; + } + else if (&m_showRegion == changedField) + { + if (m_case) + { + if (m_cellSelection() != RigFlowDiagResults::CELLS_ACTIVE) + { + RimEclipseView* view = m_case->createAndAddReservoirView(); + + view->cellResult()->setResultType(RiaDefines::FLOW_DIAGNOSTICS); + view->cellResult()->setFlowDiagTracerSelectionType(RimEclipseResultDefinition::FLOW_TR_BY_SELECTION); + view->cellResult()->setSelectedTracers(m_selectedTracerNames); + + if (m_cellSelection() == RigFlowDiagResults::CELLS_COMMUNICATION) + { + view->cellResult()->setResultVariable(RIG_FLD_COMMUNICATION_RESNAME); + } + else + { + view->cellResult()->setResultVariable(RIG_FLD_TOF_RESNAME); + } + + int timeStep = 0; + if (m_timeStepSelectionType() == ALL_AVAILABLE) + { + if (m_flowDiagSolution) + { + std::vector timeSteps = m_flowDiagSolution()->flowDiagResults()->calculatedTimeSteps(RigFlowDiagResultAddress::PHASE_ALL); + if (!timeSteps.empty()) + { + timeStep = timeSteps[0]; + } + } + } + else + { + if (!m_selectedTimeSteps().empty()) + { + timeStep = m_selectedTimeSteps()[0]; + } + } + + // Ensure selected time step has computed results + m_flowDiagSolution()->flowDiagResults()->maxAbsPairFlux(timeStep); + + view->setCurrentTimeStep(timeStep); + RicEclipsePropertyFilterFeatureImpl::addPropertyFilter(view->eclipsePropertyFilterCollection()); + + view->loadDataAndUpdate(); + m_case->updateConnectedEditors(); + + RiuMainWindow::instance()->raise(); + RiuMainWindow::instance()->selectAsCurrentItem(view); + } + } + } + else if (changedField == &m_cellSelection) + { + m_selectedTracerNames = std::vector(); + } // All fields update plot @@ -290,16 +477,25 @@ void RimFlowCharacteristicsPlot::loadDataAndUpdate() m_flowCharPlotWidget->removeAllCurves(); + std::vector selectedTracerNames = m_selectedTracerNames(); + if (m_cellSelection() == RigFlowDiagResults::CELLS_ACTIVE) + { + if (m_flowDiagSolution) + { + selectedTracerNames = m_flowDiagSolution->tracerNames(); + } + } + for ( int timeStepIdx: calculatedTimesteps ) { - lorenzVals[timeStepIdx] = flowResult->flowCharacteristicsResults(timeStepIdx, m_maxPvFraction()).m_lorenzCoefficient; + lorenzVals[timeStepIdx] = flowResult->flowCharacteristicsResults(timeStepIdx, m_cellSelection(), selectedTracerNames, m_maxPvFraction()).m_lorenzCoefficient; } m_flowCharPlotWidget->setLorenzCurve(timeStepStrings, timeStepDates, lorenzVals); for ( int timeStepIdx: calculatedTimesteps ) { - const auto flowCharResults = flowResult->flowCharacteristicsResults(timeStepIdx, m_maxPvFraction()); + const auto flowCharResults = flowResult->flowCharacteristicsResults(timeStepIdx, m_cellSelection(), selectedTracerNames, m_maxPvFraction()); m_flowCharPlotWidget->addFlowCapStorageCapCurve(timeStepDates[timeStepIdx], flowCharResults.m_flowCapStorageCapCurve.first, flowCharResults.m_flowCapStorageCapCurve.second); diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h index 8e1747d129..36b6b3446c 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h @@ -21,6 +21,8 @@ #include "RimViewWindow.h" +#include "RigFlowDiagResults.h" + #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPtrField.h" @@ -78,6 +80,7 @@ protected: virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + virtual void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ); private: @@ -86,9 +89,15 @@ private: caf::PdmPtrField m_flowDiagSolution; caf::PdmField > m_timeStepSelectionType; caf::PdmField > m_selectedTimeSteps; + caf::PdmField m_applyTimeSteps; caf::PdmField m_showLegend; caf::PdmField m_maxPvFraction; + caf::PdmField m_cellSelection; + caf::PdmField m_tracerFilter; + caf::PdmField< std::vector > m_selectedTracerNames; + caf::PdmField m_showRegion; + std::vector m_currentlyPlottedTimeSteps; QPointer m_flowCharPlotWidget; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index ec8df94448..2609ea044e 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -41,6 +41,7 @@ #include "RimWellLogExtractionCurve.h" #include "cafPdmUiListEditor.h" +#include "cafUtils.h" namespace caf { @@ -404,19 +405,6 @@ void RimEclipseResultDefinition::loadDataAndUpdate() } } -bool isStringMatch(const QString& filterString, const QString& value) -{ - if (filterString.isEmpty()) return true; - if (filterString.trimmed() == "*") - { - if (!value.isEmpty()) return true; - else return false; - } - - QRegExp searcher(filterString, Qt::CaseInsensitive, QRegExp::WildcardUnix); - return searcher.exactMatch(value); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1123,7 +1111,7 @@ std::vector RimEclipseResultDefinition::tracerNamesMatchingFilter() con { for (const QString& tracerName : tracerNames) { - if (isStringMatch(m_selectedTracersUiFieldFilter, tracerName)) + if (caf::Utils::isStringMatch(m_selectedTracersUiFieldFilter, tracerName)) { matchingNames.push_back(tracerName); } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h index 843f9a4ed6..2811c69048 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h @@ -95,6 +95,7 @@ public: void updateAnyFieldHasChanged(); void setTofAndSelectTracer(const QString& tracerName); + void setSelectedTracers(const std::vector& selectedTracers); protected: @@ -135,7 +136,6 @@ protected: caf::PdmPointer m_eclipseCase; private: - void setSelectedTracers(const std::vector& selectedTracers); void assignFlowSolutionFromCase(); bool hasDualPorFractureResult(); diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp index c212dd2ee1..a8319dbab1 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp @@ -31,6 +31,19 @@ #include // Needed for HUGE_VAL on Linux +namespace caf +{ + template<> + void RigFlowDiagResults::CellSelectionEnum::setUp() + { + addItem(RigFlowDiagResults::CELLS_ACTIVE, "CELLS_ACTIVE", "Active cells"); + addItem(RigFlowDiagResults::CELLS_COMMUNICATION, "CELLS_COMMUNICATION", "Communication cells"); + addItem(RigFlowDiagResults::CELLS_FLOODED, "CELLS_FLOODED", "Flooded cells"); + addItem(RigFlowDiagResults::CELLS_DRAINED, "CELLS_DRAINED", "Drained cells"); + setDefault(RigFlowDiagResults::CELLS_ACTIVE); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -678,10 +691,11 @@ std::vector RigFlowDiagResults::calculatedTimeSteps(RigFlowDiagResultAddres //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagResults::flowCharacteristicsResults(int frameIndex, double max_pv_fraction) +RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagResults::flowCharacteristicsResults(int frameIndex, + CellSelection cellSelection, + const std::vector& tracerNames, + double max_pv_fraction) { - std::vector tracerNames = m_flowDiagSolution->tracerNames(); - std::set injectorNames; std::set producerNames; @@ -701,8 +715,86 @@ RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagResults::f RigFlowDiagResultAddress injectorAddress(RIG_FLD_TOF_RESNAME, RigFlowDiagResultAddress::PHASE_ALL, injectorNames); RigFlowDiagResultAddress producerAddress(RIG_FLD_TOF_RESNAME, RigFlowDiagResultAddress::PHASE_ALL, producerNames); - const std::vector* injectorResults = resultValues(injectorAddress, frameIndex); - const std::vector* producerResults = resultValues(producerAddress, frameIndex); + const std::vector* allInjectorResults = resultValues(injectorAddress, frameIndex); + const std::vector* allProducerResults = resultValues(producerAddress, frameIndex); - return solverInterface()->calculateFlowCharacteristics(injectorResults, producerResults, max_pv_fraction); + std::vector injectorResults; + std::vector producerResults; + std::vector selectedCellIndices; + + if (cellSelection == CELLS_COMMUNICATION) + { + std::set allTracers; + allTracers.insert(injectorNames.begin(), injectorNames.end()); + allTracers.insert(producerNames.begin(), producerNames.end()); + + RigFlowDiagResultAddress communicationAddress(RIG_FLD_COMMUNICATION_RESNAME, RigFlowDiagResultAddress::PHASE_ALL, allTracers); + const std::vector* communicationResult = resultValues(communicationAddress, frameIndex); + + for (size_t i = 0; i < communicationResult->size(); ++i) + { + if (communicationResult->at(i) != HUGE_VAL && communicationResult->at(i) > 0) + { + selectedCellIndices.push_back(i); + if (allInjectorResults != nullptr) injectorResults.push_back(allInjectorResults->at(i)); + if (allProducerResults != nullptr) producerResults.push_back(allProducerResults->at(i)); + } + } + } + else if (cellSelection == CELLS_FLOODED) + { + if (allInjectorResults != nullptr) + { + for (size_t i = 0; i < allInjectorResults->size(); ++i) + { + if (allInjectorResults->at(i) != HUGE_VAL) + { + selectedCellIndices.push_back(i); + injectorResults.push_back(allInjectorResults->at(i)); + if (allProducerResults != nullptr) + { + producerResults.push_back(allProducerResults->at(i)); + } + else + { + producerResults.push_back(0); + } + } + } + } + } + else if (cellSelection == CELLS_DRAINED) + { + if (allProducerResults != nullptr) + { + for (size_t i = 0; i < allProducerResults->size(); ++i) + { + if (allProducerResults->at(i) != HUGE_VAL) + { + selectedCellIndices.push_back(i); + producerResults.push_back(allProducerResults->at(i)); + if (allInjectorResults != nullptr) + { + injectorResults.push_back(allInjectorResults->at(i)); + } + else + { + injectorResults.push_back(0); + } + } + } + } + } + else + { + if (allInjectorResults != nullptr) injectorResults = *allInjectorResults; + if (allProducerResults != nullptr) producerResults = *allProducerResults; + + for (size_t i = 0; i < injectorResults.size(); ++i) + { + selectedCellIndices.push_back(i); + } + } + + return solverInterface()->calculateFlowCharacteristics(&injectorResults, &producerResults, selectedCellIndices, max_pv_fraction); } diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h index 2935e451fc..92c6425575 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h @@ -24,6 +24,7 @@ #include "RimFlowDiagSolution.h" #include "cafPdmPointer.h" +#include "cafAppEnum.h" #include "cvfBase.h" #include "cvfObject.h" @@ -38,6 +39,17 @@ class RigActiveCellInfo; class RigFlowDiagResults: public cvf::Object { + +public: + enum CellSelection + { + CELLS_ACTIVE, + CELLS_COMMUNICATION, + CELLS_FLOODED, + CELLS_DRAINED + }; + + typedef caf::AppEnum CellSelectionEnum; public: RigFlowDiagResults(RimFlowDiagSolution* flowSolution, size_t timeStepCount); virtual ~RigFlowDiagResults(); @@ -67,7 +79,10 @@ public: std::vector calculatedTimeSteps(RigFlowDiagResultAddress::PhaseSelection phaseSelection); - RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame flowCharacteristicsResults(int frameIndex, double max_pv_fraction); + RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame flowCharacteristicsResults(int frameIndex, + CellSelection cellSelection, + const std::vector& tracerNames, + double max_pv_fraction); private: const std::vector* findOrCalculateResult (const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex); diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp index edff3fc51c..fa4342bfa7 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp @@ -419,6 +419,7 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI //-------------------------------------------------------------------------------------------------- RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagSolverInterface::calculateFlowCharacteristics(const std::vector* injector_tof, const std::vector* producer_tof, + const std::vector& selected_cell_indices, double max_pv_fraction) { using namespace Opm::FlowDiagnostics; @@ -428,12 +429,18 @@ RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagSolverInte { return result; } + + std::vector poreVolume; + for (size_t cellIndex : selected_cell_indices) + { + poreVolume.push_back(m_opmFlowDiagStaticData->m_poreVolume[cellIndex]); + } try { Graph flowCapStorCapCurve = flowCapacityStorageCapacityCurve(*injector_tof, *producer_tof, - m_opmFlowDiagStaticData->m_poreVolume, + poreVolume, max_pv_fraction); result.m_flowCapStorageCapCurve = flowCapStorCapCurve; diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h index eee1f75860..a2bf0ccd12 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h @@ -86,6 +86,7 @@ public: FlowCharacteristicsResultFrame calculateFlowCharacteristics(const std::vector* injector_tof, const std::vector* producer_tof, + const std::vector& selected_cell_indices, double max_pv_fraction); private: diff --git a/Fwk/AppFwk/CommonCode/cafUtils.cpp b/Fwk/AppFwk/CommonCode/cafUtils.cpp index 31cb2f6cf0..81a1b8b5f9 100644 --- a/Fwk/AppFwk/CommonCode/cafUtils.cpp +++ b/Fwk/AppFwk/CommonCode/cafUtils.cpp @@ -251,4 +251,20 @@ QString Utils::fileExtension(const QString & fileName) return fi.suffix(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool Utils::isStringMatch(const QString& filterString, const QString& value) +{ + if (filterString.isEmpty()) return true; + if (filterString.trimmed() == "*") + { + if (!value.isEmpty()) return true; + else return false; + } + + QRegExp searcher(filterString, Qt::CaseInsensitive, QRegExp::WildcardUnix); + return searcher.exactMatch(value); +} + } // namespace caf diff --git a/Fwk/AppFwk/CommonCode/cafUtils.h b/Fwk/AppFwk/CommonCode/cafUtils.h index dde22b2837..4dbba4d108 100644 --- a/Fwk/AppFwk/CommonCode/cafUtils.h +++ b/Fwk/AppFwk/CommonCode/cafUtils.h @@ -66,6 +66,8 @@ public: static bool fileExists(const QString& fileName); static QString fileExtension(const QString& fileName); + + static bool isStringMatch(const QString& filterString, const QString& value); }; }