mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#1035 Connected the Flow Diag solver, and added the statistics needed for legend. Now many things work .
This commit is contained in:
parent
3c55a86650
commit
003271ff54
@ -35,6 +35,7 @@
|
||||
#include "RimReservoirCellResultsStorage.h"
|
||||
#include "RimTools.h"
|
||||
#include "RimFlowDiagSolution.h"
|
||||
#include "RigFlowDiagSolverInterface.h"
|
||||
|
||||
#include "cafPdmSettings.h"
|
||||
#include "cafPdmUiPropertyViewDialog.h"
|
||||
@ -71,6 +72,8 @@ RimEclipseResultCase::RimEclipseResultCase()
|
||||
flipYAxis.xmlCapability()->setIOWritable(true);
|
||||
//flipYAxis.uiCapability()->setUiHidden(true);
|
||||
|
||||
m_flowDagSolverInterface = new RigFlowDiagSolverInterface(this);
|
||||
|
||||
m_activeCellInfoIsReadFromFile = false;
|
||||
m_gridAndWellDataIsReadFromFile = false;
|
||||
}
|
||||
@ -357,6 +360,14 @@ std::vector<RimFlowDiagSolution*> RimEclipseResultCase::flowDiagSolutions()
|
||||
return flowSols;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigFlowDiagSolverInterface* RimEclipseResultCase::flowDiagSolverInterface()
|
||||
{
|
||||
return m_flowDagSolverInterface.p();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -25,6 +25,7 @@
|
||||
class RifReaderInterface;
|
||||
class RigMainGrid;
|
||||
class RimFlowDiagSolution;
|
||||
class RigFlowDiagSolverInterface;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
@ -52,6 +53,8 @@ public:
|
||||
virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath);
|
||||
|
||||
std::vector<RimFlowDiagSolution*> flowDiagSolutions();
|
||||
RigFlowDiagSolverInterface* flowDiagSolverInterface();
|
||||
|
||||
private:
|
||||
cvf::ref<RifReaderInterface> createMockModel(QString modelName);
|
||||
|
||||
@ -59,6 +62,8 @@ private:
|
||||
|
||||
virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering );
|
||||
|
||||
cvf::ref<RigFlowDiagSolverInterface> m_flowDagSolverInterface;
|
||||
|
||||
// Fields:
|
||||
caf::PdmField<QString> caseFileName;
|
||||
caf::PdmChildArrayField<RimFlowDiagSolution*> m_flowDiagSolutions;
|
||||
|
@ -76,6 +76,9 @@
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <limits.h>
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimFlowDiagSolution.h"
|
||||
#include "RigFlowDiagResults.h"
|
||||
|
||||
|
||||
|
||||
@ -947,6 +950,7 @@ void RimEclipseView::updateLegends()
|
||||
CVF_ASSERT(results);
|
||||
|
||||
updateMinMaxValuesAndAddLegendToView(QString("Cell Results: \n"), this->cellResult(), results);
|
||||
|
||||
if (this->faultResultSettings()->showCustomFaultResult() && this->faultResultSettings()->hasValidCustomResult())
|
||||
{
|
||||
updateMinMaxValuesAndAddLegendToView(QString("Fault Results: \n"), this->currentFaultResultColors(), results);
|
||||
@ -994,7 +998,43 @@ void RimEclipseView::updateMinMaxValuesAndAddLegendToView(QString legendLabel, R
|
||||
{
|
||||
if (resultColors->resultType() == RimDefines::FLOW_DIAGNOSTICS)
|
||||
{
|
||||
// Todo
|
||||
double globalMin, globalMax;
|
||||
double globalPosClosestToZero, globalNegClosestToZero;
|
||||
RigFlowDiagResults* cellResultsData = resultColors->flowDiagSolution()->flowDiagResults();
|
||||
RigFlowDiagResultAddress resAddr = resultColors->flowDiagResAddress();
|
||||
|
||||
cellResultsData->minMaxScalarValues(resAddr, m_currentTimeStep, &globalMin, &globalMax);
|
||||
cellResultsData->posNegClosestToZero(resAddr, m_currentTimeStep, &globalPosClosestToZero, &globalNegClosestToZero);
|
||||
|
||||
double localMin, localMax;
|
||||
double localPosClosestToZero, localNegClosestToZero;
|
||||
if ( resultColors->hasDynamicResult() )
|
||||
{
|
||||
cellResultsData->minMaxScalarValues(resAddr, m_currentTimeStep, &localMin, &localMax);
|
||||
cellResultsData->posNegClosestToZero(resAddr, m_currentTimeStep, &localPosClosestToZero, &localNegClosestToZero);
|
||||
}
|
||||
else
|
||||
{
|
||||
localMin = globalMin;
|
||||
localMax = globalMax;
|
||||
|
||||
localPosClosestToZero = globalPosClosestToZero;
|
||||
localNegClosestToZero = globalNegClosestToZero;
|
||||
}
|
||||
|
||||
CVF_ASSERT(resultColors->legendConfig());
|
||||
|
||||
resultColors->legendConfig()->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero);
|
||||
resultColors->legendConfig()->setAutomaticRanges(globalMin, globalMax, localMin, localMax);
|
||||
|
||||
if ( resultColors->hasCategoryResult() )
|
||||
{
|
||||
resultColors->legendConfig()->setIntegerCategories(cellResultsData->uniqueCellScalarValues(resAddr, m_currentTimeStep));
|
||||
}
|
||||
|
||||
m_viewer->addColorLegendToBottomLeftCorner(resultColors->legendConfig()->legend());
|
||||
resultColors->legendConfig()->setTitle(cvfqt::Utils::toString(legendLabel + resultColors->resultVariable()));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "RigCaseData.h"
|
||||
|
||||
#include "RigFlowDiagResults.h"
|
||||
#include "RigCaseCellResultsData.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimFlowDiagSolution, "FlowDiagSolution");
|
||||
|
||||
@ -94,6 +95,82 @@ std::set<QString> RimFlowDiagSolution::tracerNames()
|
||||
return tracerNameSet;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::map<std::string, std::vector<int> > RimFlowDiagSolution::allInjectorTracerActiveCellIndices(size_t timeStepIndex)
|
||||
{
|
||||
return allTracerActiveCellIndices(timeStepIndex, true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::map<std::string, std::vector<int> > RimFlowDiagSolution::allProducerTracerActiveCellIndices(size_t timeStepIndex)
|
||||
{
|
||||
return allTracerActiveCellIndices(timeStepIndex, false);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::map<std::string, std::vector<int> > RimFlowDiagSolution::allTracerActiveCellIndices(size_t timeStepIndex, bool useInjectors)
|
||||
{
|
||||
RimEclipseResultCase* eclCase;
|
||||
this->firstAncestorOrThisOfType(eclCase);
|
||||
TracerStatusType tracerStatus = UNDEFINED;
|
||||
|
||||
std::map<std::string, std::vector<int> > tracersWithCells;
|
||||
|
||||
if ( eclCase )
|
||||
{
|
||||
const cvf::Collection<RigSingleWellResultsData>& wellResults = eclCase->reservoirData()->wellResults();
|
||||
RigMainGrid* mainGrid = eclCase->reservoirData()->mainGrid();
|
||||
RigActiveCellInfo* activeCellInfo = eclCase->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); //Todo: Must come from the results definition
|
||||
|
||||
for ( size_t wIdx = 0; wIdx < wellResults.size(); ++wIdx )
|
||||
{
|
||||
if (!wellResults[wIdx]->hasWellResult(timeStepIndex) ) continue;
|
||||
|
||||
size_t wellTimeStep = wellResults[wIdx]->m_resultTimeStepIndexToWellTimeStepIndex[timeStepIndex];
|
||||
const RigWellResultFrame& wellResFrame = wellResults[wIdx]->m_wellCellsTimeSteps[wellTimeStep];
|
||||
|
||||
if ( !wellResFrame.m_isOpen ) continue;
|
||||
|
||||
bool useWell = ( useInjectors && ( wellResFrame.m_productionType == RigWellResultFrame::GAS_INJECTOR
|
||||
|| wellResFrame.m_productionType == RigWellResultFrame::OIL_INJECTOR
|
||||
|| wellResFrame.m_productionType == RigWellResultFrame::WATER_INJECTOR) )
|
||||
|| (!useInjectors && wellResFrame.m_productionType == RigWellResultFrame::PRODUCER);
|
||||
|
||||
|
||||
if (useWell)
|
||||
{
|
||||
std::string wellname = wellResults[wIdx]->m_wellName.toStdString();
|
||||
std::vector<int>& tracerCells = tracersWithCells[wellname];
|
||||
|
||||
for (const RigWellResultBranch& wBr: wellResFrame.m_wellResultBranches)
|
||||
{
|
||||
for (const RigWellResultPoint& wrp: wBr.m_branchResultPoints)
|
||||
{
|
||||
if (wrp.isValid() && wrp.m_isOpen)
|
||||
{
|
||||
RigGridBase * grid = mainGrid->gridByIndex(wrp.m_gridIndex);
|
||||
size_t reservoirCellIndex = grid->reservoirCellIndex(wrp.m_gridCellIndex);
|
||||
|
||||
int cellActiveIndex = static_cast<int>(activeCellInfo->cellResultIndex(reservoirCellIndex));
|
||||
tracerCells.push_back(cellActiveIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tracersWithCells;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -40,6 +40,9 @@ public:
|
||||
RigFlowDiagResults* flowDiagResults();
|
||||
std::set<QString> tracerNames();
|
||||
|
||||
std::map<std::string, std::vector<int> > allInjectorTracerActiveCellIndices(size_t timeStepIndex);
|
||||
std::map<std::string, std::vector<int> > allProducerTracerActiveCellIndices(size_t timeStepIndex);
|
||||
|
||||
enum TracerStatusType
|
||||
{
|
||||
PRODUCER,
|
||||
@ -50,10 +53,13 @@ public:
|
||||
|
||||
TracerStatusType tracerStatus(QString tracerName);
|
||||
|
||||
|
||||
protected:
|
||||
//virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override;
|
||||
|
||||
private:
|
||||
std::map<std::string, std::vector<int> > allTracerActiveCellIndices(size_t timeStepIndex, bool useInjectors);
|
||||
|
||||
virtual caf::PdmFieldHandle* userDescriptionField() override;
|
||||
caf::PdmField<QString> m_userDescription;
|
||||
|
||||
|
@ -24,6 +24,9 @@ ${CEE_CURRENT_LIST_DIR}RigFlowDiagResultAddress.h
|
||||
${CEE_CURRENT_LIST_DIR}RigFlowDiagResults.h
|
||||
${CEE_CURRENT_LIST_DIR}RigFlowDiagResultFrames.h
|
||||
${CEE_CURRENT_LIST_DIR}RigFlowDiagSolverInterface.h
|
||||
${CEE_CURRENT_LIST_DIR}RigFlowDiagInterfaceTools.h
|
||||
${CEE_CURRENT_LIST_DIR}RigFlowDiagStatCalc.h
|
||||
${CEE_CURRENT_LIST_DIR}RigFlowDiagVisibleCellsStatCalc.h
|
||||
${CEE_CURRENT_LIST_DIR}RigWellLogExtractor.h
|
||||
${CEE_CURRENT_LIST_DIR}RigEclipseWellLogExtractor.h
|
||||
${CEE_CURRENT_LIST_DIR}RigLocalGrid.h
|
||||
@ -66,6 +69,8 @@ ${CEE_CURRENT_LIST_DIR}RigFormationNames.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigFlowDiagResults.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigFlowDiagResultFrames.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigFlowDiagSolverInterface.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigFlowDiagStatCalc.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigFlowDiagVisibleCellsStatCalc.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigWellLogExtractor.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigEclipseWellLogExtractor.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigLocalGrid.cpp
|
||||
|
131
ApplicationCode/ReservoirDataModel/RigFlowDiagInterfaceTools.h
Normal file
131
ApplicationCode/ReservoirDataModel/RigFlowDiagInterfaceTools.h
Normal file
@ -0,0 +1,131 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <opm/flowdiagnostics/ConnectivityGraph.hpp>
|
||||
#include <opm/flowdiagnostics/ConnectionValues.hpp>
|
||||
#include <opm/flowdiagnostics/Toolbox.hpp>
|
||||
|
||||
#include <opm/utility/ECLGraph.hpp>
|
||||
#include <opm/utility/ECLWellSolution.hpp>
|
||||
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace RigFlowDiagInterfaceTools {
|
||||
|
||||
|
||||
inline Opm::FlowDiagnostics::ConnectionValues
|
||||
extractFluxField(const Opm::ECLGraph& G)
|
||||
{
|
||||
using ConnVals = Opm::FlowDiagnostics::ConnectionValues;
|
||||
|
||||
using NConn = ConnVals::NumConnections;
|
||||
using NPhas = ConnVals::NumPhases;
|
||||
|
||||
const auto nconn = NConn{G.numConnections()};
|
||||
const auto nphas = NPhas{3};
|
||||
|
||||
auto flux = ConnVals(nconn, nphas);
|
||||
|
||||
auto phas = ConnVals::PhaseID{0};
|
||||
|
||||
for (const auto& p : { Opm::ECLGraph::PhaseIndex::Aqua ,
|
||||
Opm::ECLGraph::PhaseIndex::Liquid ,
|
||||
Opm::ECLGraph::PhaseIndex::Vapour })
|
||||
{
|
||||
const std::vector<double> pflux = G.flux(p);
|
||||
|
||||
if (! pflux.empty()) {
|
||||
assert (pflux.size() == nconn.total);
|
||||
|
||||
auto conn = ConnVals::ConnID{0};
|
||||
|
||||
for (const auto& v : pflux) {
|
||||
flux(conn, phas) = v;
|
||||
|
||||
conn.id += 1;
|
||||
}
|
||||
}
|
||||
|
||||
phas.id += 1;
|
||||
}
|
||||
|
||||
return flux;
|
||||
}
|
||||
|
||||
template <class WellFluxes>
|
||||
Opm::FlowDiagnostics::CellSetValues
|
||||
extractWellFlows(const Opm::ECLGraph& G,
|
||||
const WellFluxes& well_fluxes)
|
||||
{
|
||||
Opm::FlowDiagnostics::CellSetValues inflow;
|
||||
for (const auto& well : well_fluxes) {
|
||||
for (const auto& completion : well.completions) {
|
||||
const int grid_index = completion.grid_index;
|
||||
const auto& ijk = completion.ijk;
|
||||
const int cell_index = G.activeCell(ijk, grid_index);
|
||||
if (cell_index >= 0) {
|
||||
inflow.emplace(cell_index, completion.reservoir_inflow_rate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return inflow;
|
||||
}
|
||||
|
||||
namespace Hack {
|
||||
inline Opm::FlowDiagnostics::ConnectionValues
|
||||
convert_flux_to_SI(Opm::FlowDiagnostics::ConnectionValues&& fl)
|
||||
{
|
||||
using Co = Opm::FlowDiagnostics::ConnectionValues::ConnID;
|
||||
using Ph = Opm::FlowDiagnostics::ConnectionValues::PhaseID;
|
||||
|
||||
const auto nconn = fl.numConnections();
|
||||
const auto nphas = fl.numPhases();
|
||||
|
||||
for (auto phas = Ph{0}; phas.id < nphas; ++phas.id) {
|
||||
for (auto conn = Co{0}; conn.id < nconn; ++conn.id) {
|
||||
fl(conn, phas) /= 86400;
|
||||
}
|
||||
}
|
||||
|
||||
return fl;
|
||||
}
|
||||
}
|
||||
|
||||
inline Opm::FlowDiagnostics::Toolbox
|
||||
initialiseFlowDiagnostics(const Opm::ECLGraph& G)
|
||||
{
|
||||
const Opm::FlowDiagnostics::ConnectivityGraph connGraph =
|
||||
Opm::FlowDiagnostics::ConnectivityGraph{ static_cast<int>(G.numCells()),
|
||||
G.neighbours() };
|
||||
|
||||
// Create the Toolbox.
|
||||
|
||||
Opm::FlowDiagnostics::Toolbox tool = Opm::FlowDiagnostics::Toolbox{ connGraph };
|
||||
|
||||
tool.assignPoreVolume(G.poreVolume());
|
||||
|
||||
Opm::FlowDiagnostics::ConnectionValues connectionsVals = Hack::convert_flux_to_SI(extractFluxField(G));
|
||||
tool.assignConnectionFlux(connectionsVals);
|
||||
|
||||
Opm::ECLWellSolution wsol = Opm::ECLWellSolution{};
|
||||
|
||||
const std::vector<Opm::ECLWellSolution::WellData> well_fluxes =
|
||||
wsol.solution(G.rawResultData(), G.numGrids());
|
||||
|
||||
tool.assignInflowFlux(extractWellFlows(G, well_fluxes));
|
||||
|
||||
return tool;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,16 +19,18 @@
|
||||
#include "RigFlowDiagResults.h"
|
||||
#include "RigFlowDiagSolverInterface.h"
|
||||
#include "RimFlowDiagSolution.h"
|
||||
#include "RimEclipseResultCase.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RigCaseData.h"
|
||||
#include "RigFlowDiagStatCalc.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigFlowDiagResults::RigFlowDiagResults(RimFlowDiagSolution* flowSolution, size_t timeStepCount)
|
||||
: m_flowDiagSolution()
|
||||
: m_flowDiagSolution(flowSolution)
|
||||
{
|
||||
|
||||
m_flowDagSolverInterface = new RigFlowDiagSolverInterface(flowSolution);
|
||||
|
||||
m_timeStepCount = timeStepCount;
|
||||
m_hasAtemptedNativeResults.resize(timeStepCount, false);
|
||||
}
|
||||
@ -52,6 +54,17 @@ const std::vector<double>* RigFlowDiagResults::resultValues(const RigFlowDiagRes
|
||||
return findOrCalculateResult(resVarAddr, frameIndex);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RigActiveCellInfo * RigFlowDiagResults::activeCellInfo(const RigFlowDiagResultAddress& resVarAddr)
|
||||
{
|
||||
RimEclipseResultCase* eclCase;
|
||||
m_flowDiagSolution->firstAncestorOrThisOfType(eclCase);
|
||||
|
||||
return eclCase->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); // Todo: base on resVarAddr member
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -70,7 +83,10 @@ const std::vector<double>* RigFlowDiagResults::findOrCalculateResult(const RigFl
|
||||
|
||||
if (!m_hasAtemptedNativeResults[frameIndex])
|
||||
{
|
||||
RigFlowDiagTimeStepResult nativeTimestepResults = m_flowDagSolverInterface->calculate(frameIndex);
|
||||
|
||||
RigFlowDiagTimeStepResult nativeTimestepResults = solverInterface()->calculate(frameIndex,
|
||||
m_flowDiagSolution->allInjectorTracerActiveCellIndices(frameIndex),
|
||||
m_flowDiagSolution->allProducerTracerActiveCellIndices(frameIndex));
|
||||
|
||||
std::map<RigFlowDiagResultAddress, std::vector<double> >& nativeResults = nativeTimestepResults.nativeResults();
|
||||
|
||||
@ -103,6 +119,17 @@ std::vector<double>* RigFlowDiagResults::findScalarResultFrame(const RigFlowDiag
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigFlowDiagSolverInterface* RigFlowDiagResults::solverInterface()
|
||||
{
|
||||
RimEclipseResultCase* eclCase;
|
||||
m_flowDiagSolution->firstAncestorOrThisOfType(eclCase);
|
||||
|
||||
return eclCase->flowDiagSolverInterface();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -134,3 +161,138 @@ std::vector<double>* RigFlowDiagResults::calculateDerivedResult(const RigFlowDia
|
||||
return nullptr; // Todo
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigStatisticsDataCache* RigFlowDiagResults::statistics(const RigFlowDiagResultAddress& resVarAddr)
|
||||
{
|
||||
RigStatisticsDataCache* statCache = m_resultStatistics[resVarAddr].p();
|
||||
if ( !statCache )
|
||||
{
|
||||
RigFlowDiagStatCalc* calculator = new RigFlowDiagStatCalc(this, resVarAddr);
|
||||
statCache = new RigStatisticsDataCache(calculator);
|
||||
m_resultStatistics[resVarAddr] = statCache;
|
||||
}
|
||||
|
||||
return statCache;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagResults::minMaxScalarValues(const RigFlowDiagResultAddress& resVarAddr, int frameIndex,
|
||||
double* localMin, double* localMax)
|
||||
{
|
||||
this->statistics(resVarAddr)->minMaxCellScalarValues(frameIndex, *localMin, *localMax);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagResults::minMaxScalarValues(const RigFlowDiagResultAddress& resVarAddr,
|
||||
double* globalMin, double* globalMax)
|
||||
{
|
||||
this->statistics(resVarAddr)->minMaxCellScalarValues(*globalMin, *globalMax);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagResults::posNegClosestToZero(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* localPosClosestToZero, double* localNegClosestToZero)
|
||||
{
|
||||
this->statistics(resVarAddr)->posNegClosestToZero(frameIndex, *localPosClosestToZero, *localNegClosestToZero);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagResults::posNegClosestToZero(const RigFlowDiagResultAddress& resVarAddr, double* globalPosClosestToZero, double* globalNegClosestToZero)
|
||||
{
|
||||
this->statistics(resVarAddr)->posNegClosestToZero(*globalPosClosestToZero, *globalNegClosestToZero);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagResults::meanScalarValue(const RigFlowDiagResultAddress& resVarAddr, double* meanValue)
|
||||
{
|
||||
CVF_ASSERT(meanValue);
|
||||
|
||||
this->statistics(resVarAddr)->meanCellScalarValues(*meanValue);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagResults::meanScalarValue(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* meanValue)
|
||||
{
|
||||
this->statistics(resVarAddr)->meanCellScalarValues(frameIndex, *meanValue);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagResults::p10p90ScalarValues(const RigFlowDiagResultAddress& resVarAddr, double* p10, double* p90)
|
||||
{
|
||||
this->statistics(resVarAddr)->p10p90CellScalarValues(*p10, *p90);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagResults::p10p90ScalarValues(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* p10, double* p90)
|
||||
{
|
||||
this->statistics(resVarAddr)->p10p90CellScalarValues(frameIndex, *p10, *p90);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagResults::sumScalarValue(const RigFlowDiagResultAddress& resVarAddr, double* sum)
|
||||
{
|
||||
CVF_ASSERT(sum);
|
||||
|
||||
this->statistics(resVarAddr)->sumCellScalarValues(*sum);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagResults::sumScalarValue(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* sum)
|
||||
{
|
||||
CVF_ASSERT(sum);
|
||||
|
||||
this->statistics(resVarAddr)->sumCellScalarValues(frameIndex, *sum);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<size_t>& RigFlowDiagResults::scalarValuesHistogram(const RigFlowDiagResultAddress& resVarAddr)
|
||||
{
|
||||
return this->statistics(resVarAddr)->cellScalarValuesHistogram();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<size_t>& RigFlowDiagResults::scalarValuesHistogram(const RigFlowDiagResultAddress& resVarAddr, int frameIndex)
|
||||
{
|
||||
return this->statistics(resVarAddr)->cellScalarValuesHistogram(frameIndex);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<int>& RigFlowDiagResults::uniqueCellScalarValues(const RigFlowDiagResultAddress& resVarAddr)
|
||||
{
|
||||
return this->statistics(resVarAddr)->uniqueCellScalarValues();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<int>& RigFlowDiagResults::uniqueCellScalarValues(const RigFlowDiagResultAddress& resVarAddr, int frameIndex)
|
||||
{
|
||||
return this->statistics(resVarAddr)->uniqueCellScalarValues(frameIndex);
|
||||
}
|
||||
|
@ -40,11 +40,31 @@ public:
|
||||
virtual ~RigFlowDiagResults();
|
||||
|
||||
const std::vector<double>* resultValues(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex);
|
||||
size_t timeStepCount() { return m_timeStepCount; }
|
||||
const RigActiveCellInfo * activeCellInfo(const RigFlowDiagResultAddress& resVarAddr);
|
||||
|
||||
|
||||
void minMaxScalarValues (const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* localMin, double* localMax);
|
||||
void minMaxScalarValues (const RigFlowDiagResultAddress& resVarAddr, double* globalMin, double* globalMax);
|
||||
void posNegClosestToZero(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* localPosClosestToZero, double* localNegClosestToZero);
|
||||
void posNegClosestToZero(const RigFlowDiagResultAddress& resVarAddr, double* globalPosClosestToZero, double* globalNegClosestToZero);
|
||||
void meanScalarValue(const RigFlowDiagResultAddress& resVarAddr, double* meanValue);
|
||||
void meanScalarValue(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* meanValue);
|
||||
void p10p90ScalarValues(const RigFlowDiagResultAddress& resVarAddr, double* p10, double* p90);
|
||||
void p10p90ScalarValues(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* p10, double* p90);
|
||||
void sumScalarValue(const RigFlowDiagResultAddress& resVarAddr, double* sum);
|
||||
void sumScalarValue(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* sum);
|
||||
const std::vector<size_t>& scalarValuesHistogram(const RigFlowDiagResultAddress& resVarAddr);
|
||||
const std::vector<size_t>& scalarValuesHistogram(const RigFlowDiagResultAddress& resVarAddr, int frameIndex);
|
||||
const std::vector<int>& uniqueCellScalarValues(const RigFlowDiagResultAddress& resVarAddr);
|
||||
const std::vector<int>& uniqueCellScalarValues(const RigFlowDiagResultAddress& resVarAddr, int frameIndex);
|
||||
|
||||
private:
|
||||
const std::vector<double>* findOrCalculateResult (const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex);
|
||||
std::vector<double>* calculateDerivedResult(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex);
|
||||
void calculateFractionWeightedTOF ( size_t timeStepIdx, std::set<std::string> selectedTracerNames);
|
||||
RigStatisticsDataCache* statistics(const RigFlowDiagResultAddress& resVarAddr);
|
||||
|
||||
void calculateFractionWeightedTOF (size_t timeStepIdx, std::set<std::string> selectedTracerNames);
|
||||
void calculateSumOfFractions ( size_t timeStepIdx, std::set<std::string> selectedTracerNames);
|
||||
void calculateTracerWithMaxFraction( size_t timeStepIdx, std::set<std::string> selectedTracerNames); // Needs a tracer index
|
||||
void calculateCommunication ( size_t timeStepIdx, std::set<std::string> selectedTracerNames);
|
||||
@ -60,7 +80,7 @@ private:
|
||||
std::map< RigFlowDiagResultAddress, cvf::ref<RigFlowDiagResultFrames> > m_resultSets;
|
||||
std::map< RigFlowDiagResultAddress, cvf::ref<RigStatisticsDataCache> > m_resultStatistics;
|
||||
|
||||
cvf::ref<RigFlowDiagSolverInterface> m_flowDagSolverInterface;
|
||||
RigFlowDiagSolverInterface* solverInterface();
|
||||
|
||||
caf::PdmPointer<RimFlowDiagSolution> m_flowDiagSolution;
|
||||
|
||||
|
@ -18,11 +18,21 @@
|
||||
|
||||
#include "RigFlowDiagSolverInterface.h"
|
||||
#include "RimFlowDiagSolution.h"
|
||||
#include "RimEclipseResultCase.h"
|
||||
#include "RigCaseCellResultsData.h"
|
||||
|
||||
#include "RigFlowDiagInterfaceTools.h"
|
||||
#include "RifEclipseOutputFileTools.h"
|
||||
#include "RigCaseData.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RifReaderInterface.h"
|
||||
#include <QMessageBox>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigFlowDiagTimeStepResult::RigFlowDiagTimeStepResult(size_t activeCellCount)
|
||||
: m_activeCellCount(activeCellCount)
|
||||
{
|
||||
|
||||
}
|
||||
@ -31,10 +41,70 @@ RigFlowDiagTimeStepResult::RigFlowDiagTimeStepResult(size_t activeCellCount)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigFlowDiagSolverInterface::RigFlowDiagSolverInterface(RimFlowDiagSolution* flowSol)
|
||||
: m_flowDiagSolution(flowSol)
|
||||
void RigFlowDiagTimeStepResult::setInjectorTracerTOF(const std::string& tracerName, const std::map<int, double>& cellValues)
|
||||
{
|
||||
std::set<std::string> tracers;
|
||||
tracers.insert(tracerName);
|
||||
|
||||
this->addResult(RigFlowDiagResultAddress(RIG_FLD_TOF_RESNAME, tracers), cellValues);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagTimeStepResult::setInjectorTracerFraction(const std::string& tracerName, const std::map<int, double>& cellValues)
|
||||
{
|
||||
std::set<std::string> tracers;
|
||||
tracers.insert(tracerName);
|
||||
|
||||
this->addResult(RigFlowDiagResultAddress(RIG_FLD_CELL_FRACTION_RESNAME, tracers), cellValues);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagTimeStepResult::setProducerTracerTOF(const std::string& tracerName, const std::map<int, double>& cellValues)
|
||||
{
|
||||
std::set<std::string> tracers;
|
||||
tracers.insert(tracerName);
|
||||
|
||||
this->addResult(RigFlowDiagResultAddress(RIG_FLD_TOF_RESNAME, tracers), cellValues);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagTimeStepResult::setProducerTracerFraction(const std::string& tracerName, const std::map<int, double>& cellValues)
|
||||
{
|
||||
std::set<std::string> tracers;
|
||||
tracers.insert(tracerName);
|
||||
|
||||
this->addResult(RigFlowDiagResultAddress(RIG_FLD_CELL_FRACTION_RESNAME, tracers), cellValues);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagTimeStepResult::addResult(const RigFlowDiagResultAddress& resAddr, const std::map<int, double>& cellValues)
|
||||
{
|
||||
std::vector<double>& activeCellValues = m_nativeResults[resAddr];
|
||||
activeCellValues.resize(m_activeCellCount, HUGE_VAL);
|
||||
|
||||
for (const auto& pairIt : cellValues)
|
||||
{
|
||||
activeCellValues[pairIt.first] = pairIt.second;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigFlowDiagSolverInterface::RigFlowDiagSolverInterface(RimEclipseResultCase * eclipseCase)
|
||||
: m_eclipseCase(eclipseCase)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -48,10 +118,92 @@ RigFlowDiagSolverInterface::~RigFlowDiagSolverInterface()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timestep)
|
||||
RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepIndex,
|
||||
std::map<std::string, std::vector<int> > injectorTracers,
|
||||
std::map<std::string, std::vector<int> > producerTracers)
|
||||
{
|
||||
std::vector<RigTracerCells > allTracerData;
|
||||
using namespace Opm::FlowDiagnostics;
|
||||
|
||||
return RigFlowDiagTimeStepResult(0); // Relying on implicit move constructor
|
||||
RigFlowDiagTimeStepResult result(m_eclipseCase->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->reservoirActiveCellCount());
|
||||
|
||||
// Get set of files
|
||||
QString gridFileName = m_eclipseCase->gridFileName();
|
||||
|
||||
QStringList m_filesWithSameBaseName;
|
||||
|
||||
if ( !RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(gridFileName, &m_filesWithSameBaseName) ) return result;
|
||||
|
||||
QString initFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_INIT_FILE);
|
||||
|
||||
Opm::ECLGraph graph = Opm::ECLGraph::load(gridFileName.toStdString(),
|
||||
initFileName.toStdString());
|
||||
|
||||
// Look for unified restart file
|
||||
QString restartFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_UNIFIED_RESTART_FILE);
|
||||
|
||||
if ( restartFileName.isEmpty() )
|
||||
{
|
||||
// Look for set of restart files (one file per time step)
|
||||
|
||||
QStringList restartFileNames;
|
||||
restartFileNames = RifEclipseOutputFileTools::filterFileNamesOfType(m_filesWithSameBaseName, ECL_RESTART_FILE);
|
||||
if (restartFileNames.size() <= timeStepIndex && restartFileNames.size() != m_eclipseCase->reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)->maxTimeStepCount() )
|
||||
{
|
||||
QMessageBox::critical(nullptr, "ResInsight", "Flow Diagnostics: Could not find all the restart files. Results will not be loaded.");
|
||||
return result;
|
||||
}
|
||||
|
||||
restartFileNames.sort(); // To make sure they are sorted in increasing *.X000N order. Hack. Should probably be actual time stored on file.
|
||||
restartFileName = restartFileNames[static_cast<int>(timeStepIndex)];
|
||||
}
|
||||
|
||||
std::string casePath;
|
||||
graph.assignFluxDataSource(restartFileName.toStdString());
|
||||
|
||||
if ( ! graph.selectReportStep(static_cast<int>(timeStepIndex)) )
|
||||
{
|
||||
QMessageBox::critical(nullptr, "ResInsight", "Flow Diagnostics: Could not find the requested timestep in the result file. Results will not be loaded.");
|
||||
return result;
|
||||
}
|
||||
|
||||
{
|
||||
Toolbox fdTool = RigFlowDiagInterfaceTools::initialiseFlowDiagnostics(graph);
|
||||
{
|
||||
std::vector<CellSet> injectorCellSet;
|
||||
for ( const auto& tIt: injectorTracers )
|
||||
{
|
||||
injectorCellSet.push_back(CellSet(CellSetID(tIt.first), tIt.second));
|
||||
}
|
||||
|
||||
Solution injSol = fdTool.computeInjectionDiagnostics(injectorCellSet).fd;
|
||||
|
||||
for ( const CellSetID& tracerId: injSol.startPoints() )
|
||||
{
|
||||
CellSetValues tofVals = injSol.timeOfFlight(tracerId);
|
||||
result.setInjectorTracerTOF(tracerId.to_string(), tofVals);
|
||||
CellSetValues fracVals = injSol.concentration(tracerId);
|
||||
result.setInjectorTracerFraction(tracerId.to_string(), fracVals);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<CellSet> prodjCellSet;
|
||||
for ( const auto& tIt: producerTracers )
|
||||
{
|
||||
prodjCellSet.push_back(CellSet(CellSetID(tIt.first), tIt.second));
|
||||
}
|
||||
Solution prodSol = fdTool.computeProductionDiagnostics(prodjCellSet).fd;
|
||||
for ( const CellSetID& tracerId: prodSol.startPoints() )
|
||||
{
|
||||
CellSetValues tofVals = prodSol.timeOfFlight(tracerId);
|
||||
result.setProducerTracerTOF(tracerId.to_string(), tofVals);
|
||||
CellSetValues fracVals = prodSol.concentration(tracerId);
|
||||
result.setInjectorTracerFraction(tracerId.to_string(), fracVals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result; // Relying on implicit move constructor
|
||||
}
|
||||
|
||||
|
@ -29,13 +29,6 @@
|
||||
class RimEclipseResultCase;
|
||||
class RimFlowDiagSolution;
|
||||
|
||||
struct RigTracerCells
|
||||
{
|
||||
std::string tracerName;
|
||||
std::vector<int> tracerCellActiveIndices;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class RigFlowDiagTimeStepResult
|
||||
{
|
||||
@ -54,21 +47,25 @@ private:
|
||||
void addResult(const RigFlowDiagResultAddress& resAddr, const std::map<int, double>& cellValues);
|
||||
|
||||
std::map<RigFlowDiagResultAddress, std::vector<double> > m_nativeResults;
|
||||
size_t m_activeCellCount;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class RigCaseData;
|
||||
|
||||
class RigFlowDiagSolverInterface : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RigFlowDiagSolverInterface(RimFlowDiagSolution* flowSol);
|
||||
RigFlowDiagSolverInterface(RimEclipseResultCase * eclipseCase);
|
||||
virtual ~RigFlowDiagSolverInterface();
|
||||
|
||||
RigFlowDiagTimeStepResult calculate(size_t timestep);
|
||||
RigFlowDiagTimeStepResult calculate(size_t timestep,
|
||||
std::map<std::string, std::vector<int> > injectorTracers,
|
||||
std::map<std::string, std::vector<int> > producerTracers);
|
||||
|
||||
private:
|
||||
caf::PdmPointer<RimFlowDiagSolution> m_flowDiagSolution;
|
||||
RimEclipseResultCase * m_eclipseCase;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
107
ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.cpp
Normal file
107
ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RigFlowDiagStatCalc.h"
|
||||
#include "RigFlowDiagResults.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "RigStatisticsMath.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigFlowDiagStatCalc::RigFlowDiagStatCalc(RigFlowDiagResults* flowDiagResults, const RigFlowDiagResultAddress& resVarAddr)
|
||||
: m_resVarAddr(resVarAddr)
|
||||
{
|
||||
m_resultsData = flowDiagResults;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagStatCalc::minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max)
|
||||
{
|
||||
MinMaxAccumulator minMaxCalc(min, max);
|
||||
const std::vector<double>* vals = m_resultsData->resultValues(m_resVarAddr, timeStepIndex);
|
||||
|
||||
if (vals) minMaxCalc.addData(*vals);
|
||||
|
||||
min = minMaxCalc.min;
|
||||
max = minMaxCalc.max;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagStatCalc::posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg)
|
||||
{
|
||||
PosNegAccumulator posNegCalc(pos, neg);
|
||||
const std::vector<double>* vals = m_resultsData->resultValues(m_resVarAddr, timeStepIndex);
|
||||
|
||||
if ( vals ) posNegCalc.addData(*vals);
|
||||
|
||||
pos = posNegCalc.pos;
|
||||
neg = posNegCalc.neg;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagStatCalc::valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount)
|
||||
{
|
||||
SumCountAccumulator sumCountCalc(valueSum, sampleCount);
|
||||
const std::vector<double>* vals = m_resultsData->resultValues(m_resVarAddr, timeStepIndex);
|
||||
|
||||
if ( vals ) sumCountCalc.addData(*vals);
|
||||
|
||||
valueSum = sumCountCalc.valueSum;
|
||||
sampleCount = sumCountCalc.sampleCount;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagStatCalc::addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator)
|
||||
{
|
||||
const std::vector<double>* vals = m_resultsData->resultValues(m_resVarAddr, timeStepIndex);
|
||||
|
||||
if ( vals ) histogramCalculator.addData(*vals);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagStatCalc::uniqueValues(size_t timeStepIndex, std::set<int>& uniqueValues)
|
||||
{
|
||||
const std::vector<double>* vals = m_resultsData->resultValues(m_resVarAddr, timeStepIndex);
|
||||
|
||||
if ( vals ) for ( double val : (*vals) ) uniqueValues.insert(static_cast<int>(val));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigFlowDiagStatCalc::timeStepCount()
|
||||
{
|
||||
return m_resultsData->timeStepCount();
|
||||
}
|
||||
|
||||
|
50
ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.h
Normal file
50
ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.h
Normal file
@ -0,0 +1,50 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RigStatisticsCalculator.h"
|
||||
#include "RigFlowDiagResultAddress.h"
|
||||
|
||||
class RigHistogramCalculator;
|
||||
class RigFlowDiagResults;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
class RigFlowDiagStatCalc : public RigStatisticsCalculator
|
||||
{
|
||||
public:
|
||||
RigFlowDiagStatCalc(RigFlowDiagResults* femResultCollection, const RigFlowDiagResultAddress& resVarAddr);
|
||||
|
||||
virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max);
|
||||
virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg);
|
||||
virtual void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount);
|
||||
virtual void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator);
|
||||
virtual void uniqueValues(size_t timeStepIndex, std::set<int>& values);
|
||||
virtual size_t timeStepCount();
|
||||
|
||||
private:
|
||||
RigFlowDiagResults* m_resultsData;
|
||||
RigFlowDiagResultAddress m_resVarAddr;
|
||||
};
|
||||
|
||||
|
||||
|
@ -0,0 +1,98 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2015- Statoil ASA
|
||||
// Copyright (C) 2015- Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "RigFlowDiagVisibleCellsStatCalc.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "RigStatisticsMath.h"
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigFlowDiagVisibleCellsStatCalc::RigFlowDiagVisibleCellsStatCalc(RigFlowDiagResults* resultsData,
|
||||
const RigFlowDiagResultAddress& resVarAddr,
|
||||
const cvf::UByteArray* cellVisibilities)
|
||||
: m_resultsData(resultsData), m_resVarAddr(resVarAddr), m_cellVisibilities(cellVisibilities)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagVisibleCellsStatCalc::minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max)
|
||||
{
|
||||
MinMaxAccumulator acc(min, max);
|
||||
traverseElementNodes(acc, timeStepIndex);
|
||||
min = acc.min;
|
||||
max = acc.max;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagVisibleCellsStatCalc::posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg)
|
||||
{
|
||||
PosNegAccumulator acc(pos, neg);
|
||||
traverseElementNodes(acc, timeStepIndex);
|
||||
pos = acc.pos;
|
||||
neg = acc.neg;
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagVisibleCellsStatCalc::valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount)
|
||||
{
|
||||
SumCountAccumulator acc(valueSum, sampleCount);
|
||||
traverseElementNodes(acc, timeStepIndex);
|
||||
valueSum = acc.valueSum;
|
||||
sampleCount = acc.sampleCount;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagVisibleCellsStatCalc::addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator)
|
||||
{
|
||||
traverseElementNodes(histogramCalculator, timeStepIndex);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFlowDiagVisibleCellsStatCalc::uniqueValues(size_t timeStepIndex, std::set<int>& values)
|
||||
{
|
||||
UniqueValueAccumulator acc;
|
||||
traverseElementNodes(acc, timeStepIndex);
|
||||
values = acc.uniqueValues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigFlowDiagVisibleCellsStatCalc::timeStepCount()
|
||||
{
|
||||
return m_resultsData->timeStepCount();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,78 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2015- Statoil ASA
|
||||
// Copyright (C) 2015- Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
#include "RigStatisticsCalculator.h"
|
||||
#include "RigFlowDiagResultAddress.h"
|
||||
#include "RigFlowDiagResults.h"
|
||||
|
||||
#include "cvfArray.h"
|
||||
|
||||
class RigFlowDiagResults;
|
||||
|
||||
|
||||
class RigFlowDiagVisibleCellsStatCalc : public RigStatisticsCalculator
|
||||
{
|
||||
public:
|
||||
RigFlowDiagVisibleCellsStatCalc(RigFlowDiagResults* resultsData,
|
||||
const RigFlowDiagResultAddress& resVarAddr,
|
||||
const cvf::UByteArray* cellVisibilities);
|
||||
|
||||
virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max);
|
||||
virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg);
|
||||
virtual void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount);
|
||||
virtual void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator);
|
||||
virtual void uniqueValues(size_t timeStepIndex, std::set<int>& values);
|
||||
virtual size_t timeStepCount();
|
||||
|
||||
private:
|
||||
RigFlowDiagResults* m_resultsData;
|
||||
RigFlowDiagResultAddress m_resVarAddr;
|
||||
cvf::cref<cvf::UByteArray> m_cellVisibilities;
|
||||
|
||||
template <typename StatisticsAccumulator>
|
||||
void traverseElementNodes(StatisticsAccumulator& accumulator, size_t timeStepIndex)
|
||||
{
|
||||
const std::vector<double>* values = m_resultsData->resultValues(m_resVarAddr, timeStepIndex);
|
||||
if (!values) return;
|
||||
|
||||
const RigActiveCellInfo* actCellInfo = m_resultsData->activeCellInfo(m_resVarAddr);
|
||||
|
||||
size_t cellCount = actCellInfo->reservoirCellCount();
|
||||
|
||||
CVF_TIGHT_ASSERT(cellCount == m_cellVisibilities->size());
|
||||
|
||||
for ( size_t cIdx = 0; cIdx < cellCount; ++cIdx )
|
||||
{
|
||||
if ( !(*m_cellVisibilities)[cIdx] ) continue;
|
||||
|
||||
size_t cellResultIndex = actCellInfo->cellResultIndex(cIdx);
|
||||
|
||||
if ( cellResultIndex != cvf::UNDEFINED_SIZE_T ) accumulator.addValue((*values)[cellResultIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user