mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#1377 Flow Characteristics Plot: Calculate for a defined set of cells
This commit is contained in:
@@ -23,10 +23,18 @@
|
|||||||
#include "RimEclipseResultCase.h"
|
#include "RimEclipseResultCase.h"
|
||||||
#include "RimFlowDiagSolution.h"
|
#include "RimFlowDiagSolution.h"
|
||||||
#include "RimProject.h"
|
#include "RimProject.h"
|
||||||
|
#include "RimEclipseCellColors.h"
|
||||||
|
#include "RimEclipseView.h"
|
||||||
|
|
||||||
|
#include "RicEclipsePropertyFilterFeatureImpl.h"
|
||||||
|
|
||||||
#include "RiuFlowCharacteristicsPlot.h"
|
#include "RiuFlowCharacteristicsPlot.h"
|
||||||
|
#include "RiuMainWindow.h"
|
||||||
|
|
||||||
#include "cafPdmUiCheckBoxEditor.h"
|
#include "cafPdmUiCheckBoxEditor.h"
|
||||||
|
#include "cafPdmUiListEditor.h"
|
||||||
|
#include "cafPdmUiPushButtonEditor.h"
|
||||||
|
#include "cafUtils.h"
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
@@ -35,13 +43,13 @@
|
|||||||
|
|
||||||
namespace caf
|
namespace caf
|
||||||
{
|
{
|
||||||
template<>
|
template<>
|
||||||
void AppEnum< RimFlowCharacteristicsPlot::TimeSelectionType >::setUp()
|
void AppEnum< RimFlowCharacteristicsPlot::TimeSelectionType >::setUp()
|
||||||
{
|
{
|
||||||
addItem(RimFlowCharacteristicsPlot::ALL_AVAILABLE, "ALL_AVAILABLE", "All available");
|
addItem(RimFlowCharacteristicsPlot::ALL_AVAILABLE, "ALL_AVAILABLE", "All available");
|
||||||
addItem(RimFlowCharacteristicsPlot::SELECT_AVAILABLE, "SELECT_AVAILABLE", "Select");
|
addItem(RimFlowCharacteristicsPlot::SELECT_AVAILABLE, "SELECT_AVAILABLE", "Select");
|
||||||
setDefault(RimFlowCharacteristicsPlot::ALL_AVAILABLE);
|
setDefault(RimFlowCharacteristicsPlot::ALL_AVAILABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CAF_PDM_SOURCE_INIT(RimFlowCharacteristicsPlot, "FlowCharacteristicsPlot");
|
CAF_PDM_SOURCE_INIT(RimFlowCharacteristicsPlot, "FlowCharacteristicsPlot");
|
||||||
@@ -60,10 +68,28 @@ RimFlowCharacteristicsPlot::RimFlowCharacteristicsPlot()
|
|||||||
|
|
||||||
CAF_PDM_InitFieldNoDefault(&m_timeStepSelectionType, "TimeSelectionType", "Time Steps", "", "", "");
|
CAF_PDM_InitFieldNoDefault(&m_timeStepSelectionType, "TimeSelectionType", "Time Steps", "", "", "");
|
||||||
CAF_PDM_InitFieldNoDefault(&m_selectedTimeSteps, "SelectedTimeSteps", "", "", "", "");
|
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_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", "", "", "");
|
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;
|
this->m_showWindow = false;
|
||||||
setAsPlotMdiWindow();
|
setAsPlotMdiWindow();
|
||||||
}
|
}
|
||||||
@@ -173,14 +199,66 @@ QList<caf::PdmOptionItemInfo> RimFlowCharacteristicsPlot::calculateValueOptions(
|
|||||||
{
|
{
|
||||||
if ( m_flowDiagSolution )
|
if ( m_flowDiagSolution )
|
||||||
{
|
{
|
||||||
RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults();
|
|
||||||
std::vector<int> calculatedTimesteps = flowResult->calculatedTimeSteps(RigFlowDiagResultAddress::PHASE_ALL);
|
|
||||||
|
|
||||||
QStringList timeStepDates = m_case->timeStepStrings();
|
QStringList timeStepDates = m_case->timeStepStrings();
|
||||||
|
std::vector<int> calculatedTimeSteps = m_flowDiagSolution()->flowDiagResults()->calculatedTimeSteps(RigFlowDiagResultAddress::PHASE_ALL);
|
||||||
for ( int tsIdx : calculatedTimesteps )
|
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<QString> 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_flowDiagSolution);
|
||||||
uiOrdering.add(&m_timeStepSelectionType);
|
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_showLegend);
|
||||||
uiOrdering.add(&m_maxPvFraction);
|
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();
|
uiOrdering.skipRemainingFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RimFlowCharacteristicsPlot::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
|
||||||
|
{
|
||||||
|
if (field == &m_applyTimeSteps)
|
||||||
|
{
|
||||||
|
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>(attribute);
|
||||||
|
if (attrib)
|
||||||
|
{
|
||||||
|
attrib->m_buttonText = "Apply";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (field == &m_showRegion)
|
||||||
|
{
|
||||||
|
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>(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_flowDiagSolution = m_case->defaultFlowDiagSolution();
|
||||||
m_currentlyPlottedTimeSteps.clear();
|
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<int> 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<QString>();
|
||||||
|
}
|
||||||
|
|
||||||
// All fields update plot
|
// All fields update plot
|
||||||
|
|
||||||
@@ -290,16 +477,25 @@ void RimFlowCharacteristicsPlot::loadDataAndUpdate()
|
|||||||
|
|
||||||
m_flowCharPlotWidget->removeAllCurves();
|
m_flowCharPlotWidget->removeAllCurves();
|
||||||
|
|
||||||
|
std::vector<QString> selectedTracerNames = m_selectedTracerNames();
|
||||||
|
if (m_cellSelection() == RigFlowDiagResults::CELLS_ACTIVE)
|
||||||
|
{
|
||||||
|
if (m_flowDiagSolution)
|
||||||
|
{
|
||||||
|
selectedTracerNames = m_flowDiagSolution->tracerNames();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for ( int timeStepIdx: calculatedTimesteps )
|
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);
|
m_flowCharPlotWidget->setLorenzCurve(timeStepStrings, timeStepDates, lorenzVals);
|
||||||
|
|
||||||
for ( int timeStepIdx: calculatedTimesteps )
|
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],
|
m_flowCharPlotWidget->addFlowCapStorageCapCurve(timeStepDates[timeStepIdx],
|
||||||
flowCharResults.m_flowCapStorageCapCurve.first,
|
flowCharResults.m_flowCapStorageCapCurve.first,
|
||||||
flowCharResults.m_flowCapStorageCapCurve.second);
|
flowCharResults.m_flowCapStorageCapCurve.second);
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#include "RimViewWindow.h"
|
#include "RimViewWindow.h"
|
||||||
|
|
||||||
|
#include "RigFlowDiagResults.h"
|
||||||
|
|
||||||
#include "cafPdmField.h"
|
#include "cafPdmField.h"
|
||||||
#include "cafPdmObject.h"
|
#include "cafPdmObject.h"
|
||||||
#include "cafPdmPtrField.h"
|
#include "cafPdmPtrField.h"
|
||||||
@@ -78,6 +80,7 @@ protected:
|
|||||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||||
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;
|
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;
|
||||||
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||||
|
virtual void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -86,9 +89,15 @@ private:
|
|||||||
caf::PdmPtrField<RimFlowDiagSolution*> m_flowDiagSolution;
|
caf::PdmPtrField<RimFlowDiagSolution*> m_flowDiagSolution;
|
||||||
caf::PdmField<caf::AppEnum<TimeSelectionType> > m_timeStepSelectionType;
|
caf::PdmField<caf::AppEnum<TimeSelectionType> > m_timeStepSelectionType;
|
||||||
caf::PdmField<std::vector<int> > m_selectedTimeSteps;
|
caf::PdmField<std::vector<int> > m_selectedTimeSteps;
|
||||||
|
caf::PdmField<bool> m_applyTimeSteps;
|
||||||
caf::PdmField<bool> m_showLegend;
|
caf::PdmField<bool> m_showLegend;
|
||||||
caf::PdmField<double> m_maxPvFraction;
|
caf::PdmField<double> m_maxPvFraction;
|
||||||
|
|
||||||
|
caf::PdmField<RigFlowDiagResults::CellSelectionEnum> m_cellSelection;
|
||||||
|
caf::PdmField<QString> m_tracerFilter;
|
||||||
|
caf::PdmField< std::vector<QString> > m_selectedTracerNames;
|
||||||
|
caf::PdmField<bool> m_showRegion;
|
||||||
|
|
||||||
std::vector<int> m_currentlyPlottedTimeSteps;
|
std::vector<int> m_currentlyPlottedTimeSteps;
|
||||||
|
|
||||||
QPointer<RiuFlowCharacteristicsPlot> m_flowCharPlotWidget;
|
QPointer<RiuFlowCharacteristicsPlot> m_flowCharPlotWidget;
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include "RimWellLogExtractionCurve.h"
|
#include "RimWellLogExtractionCurve.h"
|
||||||
|
|
||||||
#include "cafPdmUiListEditor.h"
|
#include "cafPdmUiListEditor.h"
|
||||||
|
#include "cafUtils.h"
|
||||||
|
|
||||||
namespace caf
|
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<QString> RimEclipseResultDefinition::tracerNamesMatchingFilter() con
|
|||||||
{
|
{
|
||||||
for (const QString& tracerName : tracerNames)
|
for (const QString& tracerName : tracerNames)
|
||||||
{
|
{
|
||||||
if (isStringMatch(m_selectedTracersUiFieldFilter, tracerName))
|
if (caf::Utils::isStringMatch(m_selectedTracersUiFieldFilter, tracerName))
|
||||||
{
|
{
|
||||||
matchingNames.push_back(tracerName);
|
matchingNames.push_back(tracerName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ public:
|
|||||||
void updateAnyFieldHasChanged();
|
void updateAnyFieldHasChanged();
|
||||||
|
|
||||||
void setTofAndSelectTracer(const QString& tracerName);
|
void setTofAndSelectTracer(const QString& tracerName);
|
||||||
|
void setSelectedTracers(const std::vector<QString>& selectedTracers);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -135,7 +136,6 @@ protected:
|
|||||||
caf::PdmPointer<RimEclipseCase> m_eclipseCase;
|
caf::PdmPointer<RimEclipseCase> m_eclipseCase;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setSelectedTracers(const std::vector<QString>& selectedTracers);
|
|
||||||
void assignFlowSolutionFromCase();
|
void assignFlowSolutionFromCase();
|
||||||
|
|
||||||
bool hasDualPorFractureResult();
|
bool hasDualPorFractureResult();
|
||||||
|
|||||||
@@ -31,6 +31,19 @@
|
|||||||
|
|
||||||
#include <cmath> // Needed for HUGE_VAL on Linux
|
#include <cmath> // 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<int> RigFlowDiagResults::calculatedTimeSteps(RigFlowDiagResultAddres
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagResults::flowCharacteristicsResults(int frameIndex, double max_pv_fraction)
|
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagResults::flowCharacteristicsResults(int frameIndex,
|
||||||
|
CellSelection cellSelection,
|
||||||
|
const std::vector<QString>& tracerNames,
|
||||||
|
double max_pv_fraction)
|
||||||
{
|
{
|
||||||
std::vector<QString> tracerNames = m_flowDiagSolution->tracerNames();
|
|
||||||
|
|
||||||
std::set<std::string> injectorNames;
|
std::set<std::string> injectorNames;
|
||||||
std::set<std::string> producerNames;
|
std::set<std::string> producerNames;
|
||||||
|
|
||||||
@@ -701,8 +715,86 @@ RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagResults::f
|
|||||||
RigFlowDiagResultAddress injectorAddress(RIG_FLD_TOF_RESNAME, RigFlowDiagResultAddress::PHASE_ALL, injectorNames);
|
RigFlowDiagResultAddress injectorAddress(RIG_FLD_TOF_RESNAME, RigFlowDiagResultAddress::PHASE_ALL, injectorNames);
|
||||||
RigFlowDiagResultAddress producerAddress(RIG_FLD_TOF_RESNAME, RigFlowDiagResultAddress::PHASE_ALL, producerNames);
|
RigFlowDiagResultAddress producerAddress(RIG_FLD_TOF_RESNAME, RigFlowDiagResultAddress::PHASE_ALL, producerNames);
|
||||||
|
|
||||||
const std::vector<double>* injectorResults = resultValues(injectorAddress, frameIndex);
|
const std::vector<double>* allInjectorResults = resultValues(injectorAddress, frameIndex);
|
||||||
const std::vector<double>* producerResults = resultValues(producerAddress, frameIndex);
|
const std::vector<double>* allProducerResults = resultValues(producerAddress, frameIndex);
|
||||||
|
|
||||||
return solverInterface()->calculateFlowCharacteristics(injectorResults, producerResults, max_pv_fraction);
|
std::vector<double> injectorResults;
|
||||||
|
std::vector<double> producerResults;
|
||||||
|
std::vector<size_t> selectedCellIndices;
|
||||||
|
|
||||||
|
if (cellSelection == CELLS_COMMUNICATION)
|
||||||
|
{
|
||||||
|
std::set<std::string> 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<double>* 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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "RimFlowDiagSolution.h"
|
#include "RimFlowDiagSolution.h"
|
||||||
|
|
||||||
#include "cafPdmPointer.h"
|
#include "cafPdmPointer.h"
|
||||||
|
#include "cafAppEnum.h"
|
||||||
|
|
||||||
#include "cvfBase.h"
|
#include "cvfBase.h"
|
||||||
#include "cvfObject.h"
|
#include "cvfObject.h"
|
||||||
@@ -38,6 +39,17 @@ class RigActiveCellInfo;
|
|||||||
|
|
||||||
class RigFlowDiagResults: public cvf::Object
|
class RigFlowDiagResults: public cvf::Object
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum CellSelection
|
||||||
|
{
|
||||||
|
CELLS_ACTIVE,
|
||||||
|
CELLS_COMMUNICATION,
|
||||||
|
CELLS_FLOODED,
|
||||||
|
CELLS_DRAINED
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef caf::AppEnum<CellSelection> CellSelectionEnum;
|
||||||
public:
|
public:
|
||||||
RigFlowDiagResults(RimFlowDiagSolution* flowSolution, size_t timeStepCount);
|
RigFlowDiagResults(RimFlowDiagSolution* flowSolution, size_t timeStepCount);
|
||||||
virtual ~RigFlowDiagResults();
|
virtual ~RigFlowDiagResults();
|
||||||
@@ -67,7 +79,10 @@ public:
|
|||||||
std::vector<int> calculatedTimeSteps(RigFlowDiagResultAddress::PhaseSelection phaseSelection);
|
std::vector<int> calculatedTimeSteps(RigFlowDiagResultAddress::PhaseSelection phaseSelection);
|
||||||
|
|
||||||
|
|
||||||
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame flowCharacteristicsResults(int frameIndex, double max_pv_fraction);
|
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame flowCharacteristicsResults(int frameIndex,
|
||||||
|
CellSelection cellSelection,
|
||||||
|
const std::vector<QString>& tracerNames,
|
||||||
|
double max_pv_fraction);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::vector<double>* findOrCalculateResult (const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex);
|
const std::vector<double>* findOrCalculateResult (const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex);
|
||||||
|
|||||||
@@ -419,6 +419,7 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagSolverInterface::calculateFlowCharacteristics(const std::vector<double>* injector_tof,
|
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagSolverInterface::calculateFlowCharacteristics(const std::vector<double>* injector_tof,
|
||||||
const std::vector<double>* producer_tof,
|
const std::vector<double>* producer_tof,
|
||||||
|
const std::vector<size_t>& selected_cell_indices,
|
||||||
double max_pv_fraction)
|
double max_pv_fraction)
|
||||||
{
|
{
|
||||||
using namespace Opm::FlowDiagnostics;
|
using namespace Opm::FlowDiagnostics;
|
||||||
@@ -428,12 +429,18 @@ RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagSolverInte
|
|||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<double> poreVolume;
|
||||||
|
for (size_t cellIndex : selected_cell_indices)
|
||||||
|
{
|
||||||
|
poreVolume.push_back(m_opmFlowDiagStaticData->m_poreVolume[cellIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Graph flowCapStorCapCurve = flowCapacityStorageCapacityCurve(*injector_tof,
|
Graph flowCapStorCapCurve = flowCapacityStorageCapacityCurve(*injector_tof,
|
||||||
*producer_tof,
|
*producer_tof,
|
||||||
m_opmFlowDiagStaticData->m_poreVolume,
|
poreVolume,
|
||||||
max_pv_fraction);
|
max_pv_fraction);
|
||||||
|
|
||||||
result.m_flowCapStorageCapCurve = flowCapStorCapCurve;
|
result.m_flowCapStorageCapCurve = flowCapStorCapCurve;
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ public:
|
|||||||
|
|
||||||
FlowCharacteristicsResultFrame calculateFlowCharacteristics(const std::vector<double>* injector_tof,
|
FlowCharacteristicsResultFrame calculateFlowCharacteristics(const std::vector<double>* injector_tof,
|
||||||
const std::vector<double>* producer_tof,
|
const std::vector<double>* producer_tof,
|
||||||
|
const std::vector<size_t>& selected_cell_indices,
|
||||||
double max_pv_fraction);
|
double max_pv_fraction);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -251,4 +251,20 @@ QString Utils::fileExtension(const QString & fileName)
|
|||||||
return fi.suffix();
|
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
|
} // namespace caf
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ public:
|
|||||||
|
|
||||||
static bool fileExists(const QString& fileName);
|
static bool fileExists(const QString& fileName);
|
||||||
static QString fileExtension(const QString& fileName);
|
static QString fileExtension(const QString& fileName);
|
||||||
|
|
||||||
|
static bool isStringMatch(const QString& filterString, const QString& value);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user