#1377 Flow Characteristics Plot: Calculate for a defined set of cells

This commit is contained in:
Bjørnar Grip Fjær
2017-08-17 11:24:51 +02:00
parent 6ddf8aae27
commit 65ce0d3788
10 changed files with 365 additions and 39 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
} }

View File

@@ -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();

View File

@@ -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);
} }

View File

@@ -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);

View File

@@ -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;
@@ -429,11 +430,17 @@ 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;

View File

@@ -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:

View File

@@ -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

View File

@@ -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);
}; };
} }