mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#1211 Disabled tracer allocation for wells with inconsistent flow.
This commit is contained in:
parent
ad5e18afa6
commit
4fc0839a33
@ -181,50 +181,26 @@ void RimWellAllocationPlot::updateFromWell()
|
|||||||
true,
|
true,
|
||||||
pipeBranchesCLCoords,
|
pipeBranchesCLCoords,
|
||||||
pipeBranchesCellIds);
|
pipeBranchesCellIds);
|
||||||
|
|
||||||
|
std::map<QString, const std::vector<double>* > tracerCellFractionValues = findRelevantTracerCellFractions(wellResults);
|
||||||
|
|
||||||
std::unique_ptr< RigAccWellFlowCalculator > wfCalculator;
|
std::unique_ptr< RigAccWellFlowCalculator > wfCalculator;
|
||||||
std::map<QString, const std::vector<double>* > tracerCellFractionValues;
|
|
||||||
double smallContributionThreshold = 0.0;
|
double smallContributionThreshold = 0.0;
|
||||||
if (m_groupSmallContributions()) smallContributionThreshold = m_smallContributionsThreshold;
|
if (m_groupSmallContributions()) smallContributionThreshold = m_smallContributionsThreshold;
|
||||||
|
|
||||||
|
if ( tracerCellFractionValues.size() )
|
||||||
if ( m_flowDiagSolution && wellResults->hasWellResult(m_timeStep))
|
|
||||||
{
|
{
|
||||||
RimFlowDiagSolution::TracerStatusType requestedTracerType = RimFlowDiagSolution::UNDEFINED;
|
bool isProducer = wellResults->wellProductionType(m_timeStep) == RigWellResultFrame::PRODUCER ;
|
||||||
|
RigEclCellIndexCalculator cellIdxCalc(m_case->reservoirData()->mainGrid(), m_case->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS));
|
||||||
const RigWellResultFrame& wellResultFrame = wellResults->wellResultFrame(m_timeStep);
|
wfCalculator.reset(new RigAccWellFlowCalculator(pipeBranchesCLCoords,
|
||||||
if (wellResultFrame.m_productionType == RigWellResultFrame::PRODUCER)
|
pipeBranchesCellIds,
|
||||||
{
|
tracerCellFractionValues,
|
||||||
requestedTracerType = RimFlowDiagSolution::INJECTOR;
|
cellIdxCalc,
|
||||||
}
|
smallContributionThreshold,
|
||||||
else
|
isProducer));
|
||||||
{
|
|
||||||
requestedTracerType = RimFlowDiagSolution::PRODUCER;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<QString> tracerNames = m_flowDiagSolution->tracerNames();
|
|
||||||
for ( const QString& tracerName : tracerNames )
|
|
||||||
{
|
|
||||||
if (m_flowDiagSolution->tracerStatusInTimeStep(tracerName, m_timeStep) == requestedTracerType)
|
|
||||||
{
|
|
||||||
RigFlowDiagResultAddress resAddr(RIG_FLD_CELL_FRACTION_RESNAME, tracerName.toStdString());
|
|
||||||
const std::vector<double>* tracerCellFractions = m_flowDiagSolution->flowDiagResults()->resultValues(resAddr, m_timeStep);
|
|
||||||
tracerCellFractionValues[tracerName] = tracerCellFractions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( tracerCellFractionValues.size() )
|
|
||||||
{
|
|
||||||
RigEclCellIndexCalculator cellIdxCalc(m_case->reservoirData()->mainGrid(), m_case->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS));
|
|
||||||
wfCalculator.reset(new RigAccWellFlowCalculator(pipeBranchesCLCoords,
|
|
||||||
pipeBranchesCellIds,
|
|
||||||
tracerCellFractionValues,
|
|
||||||
cellIdxCalc,
|
|
||||||
smallContributionThreshold));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (!wfCalculator)
|
|
||||||
{
|
{
|
||||||
if (pipeBranchesCLCoords.size() > 0)
|
if (pipeBranchesCLCoords.size() > 0)
|
||||||
{
|
{
|
||||||
@ -314,6 +290,45 @@ void RimWellAllocationPlot::updateFromWell()
|
|||||||
if (m_wellAllocationPlotWidget) m_wellAllocationPlotWidget->updateGeometry();
|
if (m_wellAllocationPlotWidget) m_wellAllocationPlotWidget->updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::map<QString, const std::vector<double> *> RimWellAllocationPlot::findRelevantTracerCellFractions(const RigSingleWellResultsData* wellResults)
|
||||||
|
{
|
||||||
|
std::map<QString, const std::vector<double> *> tracerCellFractionValues;
|
||||||
|
|
||||||
|
if ( m_flowDiagSolution && wellResults->isOpen(m_timeStep) )
|
||||||
|
{
|
||||||
|
RimFlowDiagSolution::TracerStatusType requestedTracerType = RimFlowDiagSolution::UNDEFINED;
|
||||||
|
|
||||||
|
const RigWellResultFrame::WellProductionType prodType = wellResults->wellProductionType(m_timeStep);
|
||||||
|
if ( prodType == RigWellResultFrame::PRODUCER )
|
||||||
|
{
|
||||||
|
requestedTracerType = RimFlowDiagSolution::INJECTOR;
|
||||||
|
}
|
||||||
|
else if (prodType != RigWellResultFrame::UNDEFINED_PRODUCTION_TYPE)
|
||||||
|
{
|
||||||
|
requestedTracerType = RimFlowDiagSolution::PRODUCER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( prodType != RigWellResultFrame::UNDEFINED_PRODUCTION_TYPE )
|
||||||
|
{
|
||||||
|
std::vector<QString> tracerNames = m_flowDiagSolution->tracerNames();
|
||||||
|
for ( const QString& tracerName : tracerNames )
|
||||||
|
{
|
||||||
|
if ( m_flowDiagSolution->tracerStatusInTimeStep(tracerName, m_timeStep) == requestedTracerType )
|
||||||
|
{
|
||||||
|
RigFlowDiagResultAddress resAddr(RIG_FLD_CELL_FRACTION_RESNAME, tracerName.toStdString());
|
||||||
|
const std::vector<double>* tracerCellFractions = m_flowDiagSolution->flowDiagResults()->resultValues(resAddr, m_timeStep);
|
||||||
|
tracerCellFractionValues[tracerName] = tracerCellFractions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tracerCellFractionValues;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -35,6 +35,7 @@ class RimWellAllocationPlotLegend;
|
|||||||
class RimWellLogPlot;
|
class RimWellLogPlot;
|
||||||
class RiuWellAllocationPlot;
|
class RiuWellAllocationPlot;
|
||||||
class RimWellLogTrack;
|
class RimWellLogTrack;
|
||||||
|
class RigSingleWellResultsData;
|
||||||
|
|
||||||
namespace caf {
|
namespace caf {
|
||||||
class PdmOptionItemInfo;
|
class PdmOptionItemInfo;
|
||||||
@ -86,6 +87,9 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void updateFromWell();
|
void updateFromWell();
|
||||||
|
|
||||||
|
std::map<QString, const std::vector<double> *> findRelevantTracerCellFractions(const RigSingleWellResultsData* wellResults);
|
||||||
|
|
||||||
void updateWellFlowPlotXAxisTitle(RimWellLogTrack* plotTrack);
|
void updateWellFlowPlotXAxisTitle(RimWellLogTrack* plotTrack);
|
||||||
|
|
||||||
void addStackedCurve(const QString& tracerName,
|
void addStackedCurve(const QString& tracerName,
|
||||||
|
@ -31,7 +31,8 @@ RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vecto
|
|||||||
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds,
|
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds,
|
||||||
const std::map<QString, const std::vector<double>* >& tracerCellFractionValues,
|
const std::map<QString, const std::vector<double>* >& tracerCellFractionValues,
|
||||||
const RigEclCellIndexCalculator cellIndexCalculator,
|
const RigEclCellIndexCalculator cellIndexCalculator,
|
||||||
double smallContribThreshold):
|
double smallContribThreshold,
|
||||||
|
bool isProducer):
|
||||||
m_pipeBranchesCLCoords(pipeBranchesCLCoords),
|
m_pipeBranchesCLCoords(pipeBranchesCLCoords),
|
||||||
m_pipeBranchesCellIds(pipeBranchesCellIds),
|
m_pipeBranchesCellIds(pipeBranchesCellIds),
|
||||||
m_tracerCellFractionValues(&tracerCellFractionValues),
|
m_tracerCellFractionValues(&tracerCellFractionValues),
|
||||||
@ -39,13 +40,26 @@ RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vecto
|
|||||||
m_smallContributionsThreshold(smallContribThreshold)
|
m_smallContributionsThreshold(smallContribThreshold)
|
||||||
{
|
{
|
||||||
m_accConnectionFlowPrBranch.resize(m_pipeBranchesCellIds.size());
|
m_accConnectionFlowPrBranch.resize(m_pipeBranchesCellIds.size());
|
||||||
for ( const auto& it: (*m_tracerCellFractionValues) ) m_tracerNames.push_back(it.first);
|
|
||||||
|
|
||||||
m_tracerNames.push_back(RIG_RESERVOIR_TRACER_NAME);
|
if (isWellFlowConsistent(isProducer))
|
||||||
|
{
|
||||||
|
|
||||||
calculateAccumulatedFlowPrConnection(0, 1);
|
for ( const auto& it: (*m_tracerCellFractionValues) ) m_tracerNames.push_back(it.first);
|
||||||
sortTracers();
|
|
||||||
groupSmallContributions();
|
m_tracerNames.push_back(RIG_RESERVOIR_TRACER_NAME);
|
||||||
|
|
||||||
|
calculateAccumulatedFlowPrConnection(0, 1);
|
||||||
|
sortTracers();
|
||||||
|
groupSmallContributions();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_tracerCellFractionValues = nullptr;
|
||||||
|
m_cellIndexCalculator = RigEclCellIndexCalculator(nullptr, nullptr);
|
||||||
|
m_tracerNames.push_back(RIG_FLOW_TOTAL_NAME);
|
||||||
|
|
||||||
|
calculateAccumulatedFlowPrConnection(0, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -61,7 +75,9 @@ RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vecto
|
|||||||
m_smallContributionsThreshold(smallContribThreshold)
|
m_smallContributionsThreshold(smallContribThreshold)
|
||||||
{
|
{
|
||||||
m_accConnectionFlowPrBranch.resize(m_pipeBranchesCellIds.size());
|
m_accConnectionFlowPrBranch.resize(m_pipeBranchesCellIds.size());
|
||||||
|
|
||||||
m_tracerNames.push_back(RIG_FLOW_TOTAL_NAME);
|
m_tracerNames.push_back(RIG_FLOW_TOTAL_NAME);
|
||||||
|
|
||||||
calculateAccumulatedFlowPrConnection(0, 1);
|
calculateAccumulatedFlowPrConnection(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,6 +150,24 @@ std::vector<std::pair<QString, double> > RigAccWellFlowCalculator::totalTracerFr
|
|||||||
return totalFlows;
|
return totalFlows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RigAccWellFlowCalculator::isWellFlowConsistent( bool isProducer)
|
||||||
|
{
|
||||||
|
bool isConsistent = true;
|
||||||
|
for (const std::vector <RigWellResultPoint> & branch : m_pipeBranchesCellIds)
|
||||||
|
{
|
||||||
|
for (const RigWellResultPoint& wrp : branch)
|
||||||
|
{
|
||||||
|
if (isProducer)
|
||||||
|
isConsistent = (wrp.flowRate() >= 0.0) ;
|
||||||
|
else
|
||||||
|
isConsistent = (wrp.flowRate() <= 0.0) ;
|
||||||
|
|
||||||
|
if (!isConsistent) break;
|
||||||
|
}
|
||||||
|
if (!isConsistent) break;
|
||||||
|
}
|
||||||
|
return isConsistent;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
@ -341,7 +375,7 @@ void RigAccWellFlowCalculator::groupSmallContributions()
|
|||||||
|
|
||||||
for ( const auto& tracerPair : totalTracerFractions )
|
for ( const auto& tracerPair : totalTracerFractions )
|
||||||
{
|
{
|
||||||
if ( tracerPair.second <= m_smallContributionsThreshold ) tracersToGroup.push_back(tracerPair.first);
|
if ( abs(tracerPair.second) <= m_smallContributionsThreshold ) tracersToGroup.push_back(tracerPair.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( tracersToGroup.size() < 2 ) return; // Must at least group two ...
|
if ( tracersToGroup.size() < 2 ) return; // Must at least group two ...
|
||||||
|
@ -61,7 +61,8 @@ public:
|
|||||||
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds,
|
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds,
|
||||||
const std::map<QString, const std::vector<double>* >& tracerCellFractionValues,
|
const std::map<QString, const std::vector<double>* >& tracerCellFractionValues,
|
||||||
const RigEclCellIndexCalculator cellIndexCalculator,
|
const RigEclCellIndexCalculator cellIndexCalculator,
|
||||||
double smallContribThreshold);
|
double smallContribThreshold,
|
||||||
|
bool isProducer);
|
||||||
|
|
||||||
RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords,
|
RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords,
|
||||||
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds,
|
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds,
|
||||||
@ -75,6 +76,7 @@ public:
|
|||||||
std::vector<std::pair<QString, double> > totalTracerFractions();
|
std::vector<std::pair<QString, double> > totalTracerFractions();
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
bool isWellFlowConsistent(bool isProducer);
|
||||||
void calculateAccumulatedFlowPrConnection( size_t branchIdx, size_t startConnectionNumberFromTop);
|
void calculateAccumulatedFlowPrConnection( size_t branchIdx, size_t startConnectionNumberFromTop);
|
||||||
std::vector<size_t> wrpToConnectionIndexFromBottom( const std::vector<RigWellResultPoint> &branchCells);
|
std::vector<size_t> wrpToConnectionIndexFromBottom( const std::vector<RigWellResultPoint> &branchCells);
|
||||||
static size_t connectionIndexFromTop( const std::vector<size_t>& resPointToConnectionIndexFromBottom, size_t clSegIdx);
|
static size_t connectionIndexFromTop( const std::vector<size_t>& resPointToConnectionIndexFromBottom, size_t clSegIdx);
|
||||||
|
@ -262,6 +262,38 @@ bool RigSingleWellResultsData::isMultiSegmentWell() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RigWellResultFrame::WellProductionType RigSingleWellResultsData::wellProductionType(size_t resultTimeStepIndex) const
|
||||||
|
{
|
||||||
|
if (hasWellResult(resultTimeStepIndex))
|
||||||
|
{
|
||||||
|
const RigWellResultFrame& wResFrame = wellResultFrame(resultTimeStepIndex);
|
||||||
|
return wResFrame.m_productionType;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return RigWellResultFrame::UNDEFINED_PRODUCTION_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RigSingleWellResultsData::isOpen(size_t resultTimeStepIndex) const
|
||||||
|
{
|
||||||
|
if (hasWellResult(resultTimeStepIndex))
|
||||||
|
{
|
||||||
|
const RigWellResultFrame& wResFrame = wellResultFrame(resultTimeStepIndex);
|
||||||
|
return wResFrame.m_isOpen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -131,23 +131,25 @@ class RigSingleWellResultsData : public cvf::Object
|
|||||||
public:
|
public:
|
||||||
RigSingleWellResultsData() { m_isMultiSegmentWell = false; }
|
RigSingleWellResultsData() { m_isMultiSegmentWell = false; }
|
||||||
|
|
||||||
void setMultiSegmentWell(bool isMultiSegmentWell);
|
void setMultiSegmentWell(bool isMultiSegmentWell);
|
||||||
bool isMultiSegmentWell() const;
|
bool isMultiSegmentWell() const;
|
||||||
|
|
||||||
bool hasWellResult(size_t resultTimeStepIndex) const;
|
bool hasWellResult(size_t resultTimeStepIndex) const;
|
||||||
|
const RigWellResultFrame& wellResultFrame(size_t resultTimeStepIndex) const;
|
||||||
|
bool isOpen(size_t resultTimeStepIndex) const;
|
||||||
|
RigWellResultFrame::WellProductionType wellProductionType(size_t resultTimeStepIndex) const;
|
||||||
|
|
||||||
const RigWellResultFrame& wellResultFrame(size_t resultTimeStepIndex) const;
|
void computeStaticWellCellPath() const ;
|
||||||
|
void computeMappingFromResultTimeIndicesToWellTimeIndices(const std::vector<QDateTime>& resultTimes);
|
||||||
|
|
||||||
void computeStaticWellCellPath() const ;
|
public: // Todo: Clean up this regarding public members and constness etc.
|
||||||
|
QString m_wellName;
|
||||||
|
|
||||||
void computeMappingFromResultTimeIndicesToWellTimeIndices(const std::vector<QDateTime>& resultTimes);
|
std::vector<size_t> m_resultTimeStepIndexToWellTimeStepIndex; // Well result timesteps may differ from result timesteps
|
||||||
|
std::vector< RigWellResultFrame > m_wellCellsTimeSteps;
|
||||||
|
mutable RigWellResultFrame m_staticWellCells;
|
||||||
|
|
||||||
public:
|
private:
|
||||||
QString m_wellName;
|
bool m_isMultiSegmentWell;
|
||||||
bool m_isMultiSegmentWell;
|
|
||||||
|
|
||||||
std::vector<size_t> m_resultTimeStepIndexToWellTimeStepIndex; // Well result timesteps may differ from result timesteps
|
|
||||||
std::vector< RigWellResultFrame > m_wellCellsTimeSteps;
|
|
||||||
mutable RigWellResultFrame m_staticWellCells;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user