#1696 Threshold option for aquifer cells

This commit is contained in:
Bjørnar Grip Fjær 2017-08-09 14:10:39 +02:00
parent 39c3338024
commit 7598d8c196
6 changed files with 88 additions and 56 deletions

View File

@ -58,6 +58,7 @@ 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_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", "", "", "");
@ -198,6 +199,7 @@ void RimFlowCharacteristicsPlot::defineUiOrdering(QString uiConfigName, caf::Pdm
if (m_timeStepSelectionType == SELECT_AVAILABLE) uiOrdering.add(&m_selectedTimeSteps); if (m_timeStepSelectionType == SELECT_AVAILABLE) uiOrdering.add(&m_selectedTimeSteps);
uiOrdering.add(&m_showLegend); uiOrdering.add(&m_showLegend);
uiOrdering.add(&m_maxPvFraction);
uiOrdering.skipRemainingFields(); uiOrdering.skipRemainingFields();
} }
@ -288,14 +290,14 @@ void RimFlowCharacteristicsPlot::loadDataAndUpdate()
for ( int timeStepIdx: calculatedTimesteps ) for ( int timeStepIdx: calculatedTimesteps )
{ {
lorenzVals[timeStepIdx] = flowResult->flowCharacteristicsResults(timeStepIdx).m_lorenzCoefficient; lorenzVals[timeStepIdx] = flowResult->flowCharacteristicsResults(timeStepIdx, 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); const auto flowCharResults = flowResult->flowCharacteristicsResults(timeStepIdx, 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

@ -87,6 +87,7 @@ private:
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_showLegend; caf::PdmField<bool> m_showLegend;
caf::PdmField<double> m_maxPvFraction;
std::vector<int> m_currentlyPlottedTimeSteps; std::vector<int> m_currentlyPlottedTimeSteps;

View File

@ -41,7 +41,6 @@ RigFlowDiagResults::RigFlowDiagResults(RimFlowDiagSolution* flowSolution, size_t
m_timeStepCount = timeStepCount; m_timeStepCount = timeStepCount;
m_hasAtemptedNativeResults.resize(timeStepCount, false); m_hasAtemptedNativeResults.resize(timeStepCount, false);
m_injProdPairFluxCommunicationTimesteps.resize(timeStepCount); m_injProdPairFluxCommunicationTimesteps.resize(timeStepCount);
m_flowCharResultFrames.resize(timeStepCount);
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -121,12 +120,6 @@ void RigFlowDiagResults::calculateNativeResultsIfNotPreviouslyAttempted(size_t f
m_injProdPairFluxCommunicationTimesteps[frameIndex].swap(nativeTimestepResults.injProdWellPairFluxes()); m_injProdPairFluxCommunicationTimesteps[frameIndex].swap(nativeTimestepResults.injProdWellPairFluxes());
m_flowCharResultFrames[frameIndex].m_lorenzCoefficient = nativeTimestepResults.lorenzCoefficient();
m_flowCharResultFrames[frameIndex].m_flowCapStorageCapCurve.first.swap(nativeTimestepResults.flowCapStorageCapCurve().first);
m_flowCharResultFrames[frameIndex].m_flowCapStorageCapCurve.second.swap(nativeTimestepResults.flowCapStorageCapCurve().second);
m_flowCharResultFrames[frameIndex].m_sweepEfficiencyCurve.first.swap(nativeTimestepResults.sweepEfficiencyCurve().first);
m_flowCharResultFrames[frameIndex].m_sweepEfficiencyCurve.second.swap(nativeTimestepResults.sweepEfficiencyCurve().second);
m_hasAtemptedNativeResults[frameIndex] = true; m_hasAtemptedNativeResults[frameIndex] = true;
} }
} }
@ -679,8 +672,31 @@ std::vector<int> RigFlowDiagResults::calculatedTimeSteps()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RigFlowDiagResults::FlowCharacteristicsResultFrame::FlowCharacteristicsResultFrame() RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagResults::flowCharacteristicsResults(int frameIndex, double max_pv_fraction)
: m_lorenzCoefficient(HUGE_VAL)
{ {
std::vector<QString> tracerNames = m_flowDiagSolution->tracerNames();
std::set<std::string> injectorNames;
std::set<std::string> producerNames;
for (const QString& tracerName : tracerNames)
{
RimFlowDiagSolution::TracerStatusType status = m_flowDiagSolution->tracerStatusInTimeStep(tracerName, frameIndex);
if (status == RimFlowDiagSolution::INJECTOR)
{
injectorNames.insert(tracerName.toStdString());
}
else if (status == RimFlowDiagSolution::PRODUCER)
{
producerNames.insert(tracerName.toStdString());
}
}
RigFlowDiagResultAddress injectorAddress(RIG_FLD_TOF_RESNAME, injectorNames);
RigFlowDiagResultAddress producerAddress(RIG_FLD_TOF_RESNAME, producerNames);
const std::vector<double>* injectorResults = resultValues(injectorAddress, frameIndex);
const std::vector<double>* producerResults = resultValues(producerAddress, frameIndex);
return solverInterface()->calculateFlowCharacteristics(*injectorResults, *producerResults, max_pv_fraction);
} }

View File

@ -19,6 +19,8 @@
#include "RigFlowDiagResultAddress.h" #include "RigFlowDiagResultAddress.h"
#include "RigFlowDiagSolverInterface.h"
#include "RimFlowDiagSolution.h" #include "RimFlowDiagSolution.h"
#include "cafPdmPointer.h" #include "cafPdmPointer.h"
@ -32,7 +34,6 @@
class RigFlowDiagResultFrames; class RigFlowDiagResultFrames;
class RigStatisticsDataCache; class RigStatisticsDataCache;
class RigFlowDiagSolverInterface;
class RigActiveCellInfo; class RigActiveCellInfo;
class RigFlowDiagResults: public cvf::Object class RigFlowDiagResults: public cvf::Object
@ -65,18 +66,8 @@ public:
std::vector<int> calculatedTimeSteps(); std::vector<int> calculatedTimeSteps();
struct FlowCharacteristicsResultFrame
{
FlowCharacteristicsResultFrame();
using Curve = std::pair< std::vector<double>, std::vector<double> >; RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame flowCharacteristicsResults(int frameIndex, double max_pv_fraction);
Curve m_flowCapStorageCapCurve;
Curve m_sweepEfficiencyCurve;
double m_lorenzCoefficient;
};
const FlowCharacteristicsResultFrame& flowCharacteristicsResults(int frameIndex) { return m_flowCharResultFrames[frameIndex];}
private: private:
const std::vector<double>* findOrCalculateResult (const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex); const std::vector<double>* findOrCalculateResult (const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex);
@ -133,11 +124,6 @@ private:
using InjectorProducerCommunicationMap = std::map< std::pair<std::string, std::string>, std::pair<double, double> >; using InjectorProducerCommunicationMap = std::map< std::pair<std::string, std::string>, std::pair<double, double> >;
std::vector<InjectorProducerCommunicationMap> m_injProdPairFluxCommunicationTimesteps; std::vector<InjectorProducerCommunicationMap> m_injProdPairFluxCommunicationTimesteps;
std::vector<FlowCharacteristicsResultFrame> m_flowCharResultFrames;
}; };

View File

@ -39,7 +39,7 @@
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RigFlowDiagTimeStepResult::RigFlowDiagTimeStepResult(size_t activeCellCount) RigFlowDiagTimeStepResult::RigFlowDiagTimeStepResult(size_t activeCellCount)
: m_activeCellCount(activeCellCount), m_lorenzCoefficient(HUGE_VAL) : m_activeCellCount(activeCellCount)
{ {
} }
@ -394,24 +394,46 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
} }
} }
} }
try
{
Graph flowCapStorCapCurve = flowCapacityStorageCapacityCurve(*(injectorSolution.get()),
*(producerSolution.get()),
m_opmFlowDiagStaticData->m_poreVolume,
0.1);
result.setFlowCapStorageCapCurve(flowCapStorCapCurve);
result.setSweepEfficiencyCurve(sweepEfficiency(flowCapStorCapCurve));
result.setLorenzCoefficient(lorenzCoefficient(flowCapStorCapCurve));
}
catch ( const std::exception& e )
{
QMessageBox::critical(nullptr, "ResInsight", "Flow Diagnostics: " + QString(e.what()));
}
} }
return result; // Relying on implicit move constructor return result; // Relying on implicit move constructor
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagSolverInterface::calculateFlowCharacteristics(const std::vector<double>& injector_tof,
const std::vector<double>& producer_tof,
double max_pv_fraction)
{
using namespace Opm::FlowDiagnostics;
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame result;
try
{
Graph flowCapStorCapCurve = flowCapacityStorageCapacityCurve(injector_tof,
producer_tof,
m_opmFlowDiagStaticData->m_poreVolume,
max_pv_fraction);
result.m_flowCapStorageCapCurve = flowCapStorCapCurve;
result.m_lorenzCoefficient = lorenzCoefficient(flowCapStorCapCurve);
result.m_sweepEfficiencyCurve = sweepEfficiency(flowCapStorCapCurve);
}
catch (const std::exception& e)
{
QMessageBox::critical(nullptr, "ResInsight", "Flow Diagnostics: " + QString(e.what()));
}
return result;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame::FlowCharacteristicsResultFrame()
: m_lorenzCoefficient(HUGE_VAL)
{
}

View File

@ -42,18 +42,11 @@ public:
const std::pair<double, double>& injProdFluxes) ; const std::pair<double, double>& injProdFluxes) ;
using Curve = std::pair< std::vector<double>, std::vector<double> >; using Curve = std::pair< std::vector<double>, std::vector<double> >;
void setFlowCapStorageCapCurve(const Curve& flCapStCapCurve) { m_flowCapStorageCapCurve = flCapStCapCurve;}
void setSweepEfficiencyCurve(const Curve& sweepEffCurve) { m_sweepEfficiencyCurve = sweepEffCurve; }
void setLorenzCoefficient(double coeff) { m_lorenzCoefficient = coeff;}
// Used to "steal" the data from this one using swap // Used to "steal" the data from this one using swap
std::map<RigFlowDiagResultAddress, std::vector<double> >& nativeResults() { return m_nativeResults; } std::map<RigFlowDiagResultAddress, std::vector<double> >& nativeResults() { return m_nativeResults; }
std::map<std::pair<std::string, std::string>, std::pair<double, double> > & injProdWellPairFluxes() { return m_injProdWellPairFluxes; } std::map<std::pair<std::string, std::string>, std::pair<double, double> > & injProdWellPairFluxes() { return m_injProdWellPairFluxes; }
Curve& flowCapStorageCapCurve() { return m_flowCapStorageCapCurve; }
Curve& sweepEfficiencyCurve() { return m_sweepEfficiencyCurve; }
double lorenzCoefficient() { return m_lorenzCoefficient;}
private: private:
void addResult(const RigFlowDiagResultAddress& resAddr, const std::map<int, double>& cellValues); void addResult(const RigFlowDiagResultAddress& resAddr, const std::map<int, double>& cellValues);
@ -61,10 +54,6 @@ private:
std::map<RigFlowDiagResultAddress, std::vector<double> > m_nativeResults; std::map<RigFlowDiagResultAddress, std::vector<double> > m_nativeResults;
std::map<std::pair<std::string, std::string>, std::pair<double, double> > m_injProdWellPairFluxes; std::map<std::pair<std::string, std::string>, std::pair<double, double> > m_injProdWellPairFluxes;
Curve m_flowCapStorageCapCurve;
Curve m_sweepEfficiencyCurve;
double m_lorenzCoefficient;
size_t m_activeCellCount; size_t m_activeCellCount;
}; };
@ -74,6 +63,18 @@ class RigOpmFlowDiagStaticData;
class RigFlowDiagSolverInterface : public cvf::Object class RigFlowDiagSolverInterface : public cvf::Object
{ {
public:
struct FlowCharacteristicsResultFrame
{
FlowCharacteristicsResultFrame();
using Curve = std::pair< std::vector<double>, std::vector<double> >;
Curve m_flowCapStorageCapCurve;
Curve m_sweepEfficiencyCurve;
double m_lorenzCoefficient;
};
public: public:
explicit RigFlowDiagSolverInterface(RimEclipseResultCase * eclipseCase); explicit RigFlowDiagSolverInterface(RimEclipseResultCase * eclipseCase);
virtual ~RigFlowDiagSolverInterface(); virtual ~RigFlowDiagSolverInterface();
@ -82,6 +83,10 @@ public:
std::map<std::string, std::vector<int> > injectorTracers, std::map<std::string, std::vector<int> > injectorTracers,
std::map<std::string, std::vector<int> > producerTracers); std::map<std::string, std::vector<int> > producerTracers);
FlowCharacteristicsResultFrame calculateFlowCharacteristics(const std::vector<double>& injector_tof,
const std::vector<double>& producer_tof,
double max_pv_fraction);
private: private:
RimEclipseResultCase * m_eclipseCase; RimEclipseResultCase * m_eclipseCase;