#1049 Reuse Opm::ECLGraph and Opm::Flowdiagnostics::Toolbox for each timestep.

This commit is contained in:
Jacob Støren
2017-01-06 14:41:00 +01:00
parent e455529b36
commit c19fc232c8
4 changed files with 305 additions and 202 deletions

View File

@@ -160,9 +160,31 @@ std::vector<double>* RigFlowDiagResults::calculateDerivedResult(const RigFlowDia
{
if (resVarAddr.isNativeResult()) return nullptr;
size_t activeCellCount = this->activeCellInfo(resVarAddr)->reservoirActiveCellCount();
if (resVarAddr.variableName == RIG_FLD_TOF_RESNAME)
{
return calculateAverageTOFResult(resVarAddr, frameIndex);
}
else if (resVarAddr.variableName == RIG_FLD_CELL_FRACTION_RESNAME)
{
return calculateSumOfFractionsResult(resVarAddr, frameIndex);
}
else if ( resVarAddr.variableName == RIG_FLD_COMMUNICATION_RESNAME )
{
return calculateCommunicationResult(resVarAddr, frameIndex);
}
else if ( resVarAddr.variableName == RIG_FLD_MAX_FRACTION_TRACER_RESNAME )
{
return calculateTracerWithMaxFractionResult(resVarAddr, frameIndex);
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double>* RigFlowDiagResults::calculateAverageTOFResult(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex)
{
std::vector<const std::vector<double>* > injectorTOFs = findResultsForSelectedTracers(resVarAddr, frameIndex,
RIG_FLD_TOF_RESNAME, RimFlowDiagSolution::INJECTOR);
@@ -173,6 +195,7 @@ std::vector<double>* RigFlowDiagResults::calculateDerivedResult(const RigFlowDia
RIG_FLD_TOF_RESNAME, RimFlowDiagSolution::PRODUCER);
std::vector<const std::vector<double>* > producerFractions = findResultsForSelectedTracers(resVarAddr, frameIndex,
RIG_FLD_CELL_FRACTION_RESNAME, RimFlowDiagSolution::PRODUCER);
size_t activeCellCount = this->activeCellInfo(resVarAddr)->reservoirActiveCellCount();
std::vector<double> injectorTotalFractions;
std::vector<double> injectorFractMultTof;
@@ -206,7 +229,12 @@ std::vector<double>* RigFlowDiagResults::calculateDerivedResult(const RigFlowDia
return &averageTof;
}
else if (resVarAddr.variableName == RIG_FLD_CELL_FRACTION_RESNAME)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double>* RigFlowDiagResults::calculateSumOfFractionsResult(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex)
{
std::vector<const std::vector<double>* > fractions = findResultsForSelectedTracers(resVarAddr,
frameIndex,
@@ -216,42 +244,18 @@ std::vector<double>* RigFlowDiagResults::calculateDerivedResult(const RigFlowDia
RigFlowDiagResultFrames* sumOfFractionsFrames = this->createScalarResult(resVarAddr);
std::vector<double>& sumOfFractions = sumOfFractionsFrames->frameData(frameIndex);
size_t activeCellCount = this->activeCellInfo(resVarAddr)->reservoirActiveCellCount();
calculateSumOfFractions(fractions, activeCellCount, &sumOfFractions);
return &sumOfFractions;
}
else if ( resVarAddr.variableName == RIG_FLD_COMMUNICATION_RESNAME )
{
std::vector<const std::vector<double>* > injectorFractions = findResultsForSelectedTracers(resVarAddr,
frameIndex,
RIG_FLD_CELL_FRACTION_RESNAME,
RimFlowDiagSolution::INJECTOR);
std::vector<const std::vector<double>* > producerFractions = findResultsForSelectedTracers(resVarAddr,
frameIndex,
RIG_FLD_CELL_FRACTION_RESNAME,
RimFlowDiagSolution::PRODUCER);
std::vector<double> sumOfInjectorFractions;
calculateSumOfFractions(injectorFractions, activeCellCount, &sumOfInjectorFractions);
std::vector<double> sumOfProducerFractions;
calculateSumOfFractions(producerFractions, activeCellCount, &sumOfProducerFractions);
RigFlowDiagResultFrames* commFrames = this->createScalarResult(resVarAddr);
std::vector<double>& commPI = commFrames->frameData(frameIndex);
commPI.resize(activeCellCount, HUGE_VAL);
for ( size_t acIdx = 0 ; acIdx < activeCellCount; ++acIdx )
{
if ( (sumOfInjectorFractions)[acIdx] == HUGE_VAL ) continue;
if ( (sumOfProducerFractions)[acIdx] == HUGE_VAL ) continue;
(commPI)[acIdx] = (sumOfInjectorFractions)[acIdx] * (sumOfProducerFractions)[acIdx];
}
return &commPI;
}
else if ( resVarAddr.variableName == RIG_FLD_MAX_FRACTION_TRACER_RESNAME )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double>* RigFlowDiagResults::calculateTracerWithMaxFractionResult(const RigFlowDiagResultAddress &resVarAddr, size_t frameIndex)
{
std::vector<int> selectedTracerIdxToGlobalTracerIdx;
{
@@ -274,6 +278,7 @@ std::vector<double>* RigFlowDiagResults::calculateDerivedResult(const RigFlowDia
}
}
size_t activeCellCount = this->activeCellInfo(resVarAddr)->reservoirActiveCellCount();
RigFlowDiagResultFrames* maxFractionTracerIdxFrames = this->createScalarResult(resVarAddr);
std::vector<double>& maxFractionTracerIdx = maxFractionTracerIdxFrames->frameData(frameIndex);
@@ -316,10 +321,47 @@ std::vector<double>* RigFlowDiagResults::calculateDerivedResult(const RigFlowDia
return &maxFractionTracerIdx;
}
return nullptr;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double>* RigFlowDiagResults::calculateCommunicationResult(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex)
{
std::vector<const std::vector<double>* > injectorFractions = findResultsForSelectedTracers(resVarAddr,
frameIndex,
RIG_FLD_CELL_FRACTION_RESNAME,
RimFlowDiagSolution::INJECTOR);
std::vector<const std::vector<double>* > producerFractions = findResultsForSelectedTracers(resVarAddr,
frameIndex,
RIG_FLD_CELL_FRACTION_RESNAME,
RimFlowDiagSolution::PRODUCER);
size_t activeCellCount = this->activeCellInfo(resVarAddr)->reservoirActiveCellCount();
std::vector<double> sumOfInjectorFractions;
calculateSumOfFractions(injectorFractions, activeCellCount, &sumOfInjectorFractions);
std::vector<double> sumOfProducerFractions;
calculateSumOfFractions(producerFractions, activeCellCount, &sumOfProducerFractions);
RigFlowDiagResultFrames* commFrames = this->createScalarResult(resVarAddr);
std::vector<double>& commPI = commFrames->frameData(frameIndex);
commPI.resize(activeCellCount, HUGE_VAL);
for ( size_t acIdx = 0 ; acIdx < activeCellCount; ++acIdx )
{
if ( (sumOfInjectorFractions)[acIdx] == HUGE_VAL ) continue;
if ( (sumOfProducerFractions)[acIdx] == HUGE_VAL ) continue;
(commPI)[acIdx] = (sumOfInjectorFractions)[acIdx] * (sumOfProducerFractions)[acIdx];
}
return &commPI;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<const std::vector<double>* > RigFlowDiagResults::findResultsForSelectedTracers(const RigFlowDiagResultAddress& resVarAddr,
size_t frameIndex,
const std::string& nativeResultName,

View File

@@ -64,6 +64,14 @@ private:
std::vector<double>* calculateDerivedResult(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex);
std::vector<double>* calculateAverageTOFResult(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex);
std::vector<double>* calculateSumOfFractionsResult(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex);
std::vector<double>* calculateTracerWithMaxFractionResult(const RigFlowDiagResultAddress &resVarAddr, size_t frameIndex);
std::vector<double>* calculateCommunicationResult(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex);
std::vector<const std::vector<double>* > findResultsForSelectedTracers(const RigFlowDiagResultAddress& resVarAddr,
size_t frameIndex,
const std::string& nativeResultName,

View File

@@ -98,13 +98,26 @@ void RigFlowDiagTimeStepResult::addResult(const RigFlowDiagResultAddress& resAdd
}
}
class RigOpmFldStaticData : public cvf::Object
{
public:
RigOpmFldStaticData(const std::string& grid, const std::string& init) : eclGraph(Opm::ECLGraph::load(grid, init)), m_hasUnifiedRestartFile(false) {}
Opm::ECLGraph eclGraph;
std::unique_ptr<Opm::FlowDiagnostics::Toolbox> fldToolbox;
bool m_hasUnifiedRestartFile;
QStringList restartFileNames;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagSolverInterface::RigFlowDiagSolverInterface(RimEclipseResultCase * eclipseCase)
: m_eclipseCase(eclipseCase)
{
}
//--------------------------------------------------------------------------------------------------
@@ -115,6 +128,7 @@ RigFlowDiagSolverInterface::~RigFlowDiagSolverInterface()
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -126,6 +140,8 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
RigFlowDiagTimeStepResult result(m_eclipseCase->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->reservoirActiveCellCount());
if ( m_opmFldData.isNull() )
{
// Get set of files
QString gridFileName = m_eclipseCase->gridFileName();
@@ -135,20 +151,32 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
QString initFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_INIT_FILE);
Opm::ECLGraph graph = Opm::ECLGraph::load(gridFileName.toStdString(),
m_opmFldData = new RigOpmFldStaticData(gridFileName.toStdString(),
initFileName.toStdString());
const Opm::FlowDiagnostics::ConnectivityGraph connGraph =
Opm::FlowDiagnostics::ConnectivityGraph{ static_cast<int>(m_opmFldData->eclGraph.numCells()),
m_opmFldData->eclGraph.neighbours() };
// Create the Toolbox.
m_opmFldData->fldToolbox.reset(new Opm::FlowDiagnostics::Toolbox{ connGraph });
m_opmFldData->fldToolbox->assignPoreVolume( m_opmFldData->eclGraph.poreVolume());
// Look for unified restart file
QString restartFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_UNIFIED_RESTART_FILE);
if ( restartFileName.isEmpty() )
if ( !restartFileName.isEmpty() )
{
m_opmFldData->eclGraph.assignFluxDataSource(restartFileName.toStdString());
m_opmFldData->m_hasUnifiedRestartFile = true;
}
else
{
// Look for set of restart files (one file per time step)
QStringList restartFileNames;
restartFileNames = RifEclipseOutputFileTools::filterFileNamesOfType(m_filesWithSameBaseName, ECL_RESTART_FILE);
m_opmFldData->restartFileNames = RifEclipseOutputFileTools::filterFileNamesOfType(m_filesWithSameBaseName, ECL_RESTART_FILE);
size_t restartFileCount = static_cast<size_t>(restartFileNames.size());
size_t restartFileCount = static_cast<size_t>(m_opmFldData->restartFileNames.size());
size_t maxTimeStepCount = m_eclipseCase->reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)->maxTimeStepCount();
if (restartFileCount <= timeStepIndex && restartFileCount != maxTimeStepCount )
@@ -157,20 +185,41 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
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)];
m_opmFldData->restartFileNames.sort(); // To make sure they are sorted in increasing *.X000N order. Hack. Should probably be actual time stored on file.
m_opmFldData->m_hasUnifiedRestartFile = false;
}
}
graph.assignFluxDataSource(restartFileName.toStdString());
if ( ! graph.selectReportStep(static_cast<int>(timeStepIndex)) )
if ( ! m_opmFldData->m_hasUnifiedRestartFile )
{
QString restartFileName = m_opmFldData->restartFileNames[static_cast<int>(timeStepIndex)];
m_opmFldData->eclGraph.assignFluxDataSource(restartFileName.toStdString());
}
if ( ! m_opmFldData->eclGraph.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;
}
// Set up flow Toolbox with timestep data
{
Toolbox fdTool = RigFlowDiagInterfaceTools::initialiseFlowDiagnostics(graph);
Opm::FlowDiagnostics::ConnectionValues connectionsVals = RigFlowDiagInterfaceTools::Hack::convert_flux_to_SI( RigFlowDiagInterfaceTools::extractFluxField(m_opmFldData->eclGraph));
m_opmFldData->fldToolbox->assignConnectionFlux(connectionsVals);
Opm::ECLWellSolution wsol = Opm::ECLWellSolution{};
const std::vector<Opm::ECLWellSolution::WellData> well_fluxes =
wsol.solution(m_opmFldData->eclGraph.rawResultData(), m_opmFldData->eclGraph.numGrids());
m_opmFldData->fldToolbox->assignInflowFlux(RigFlowDiagInterfaceTools::extractWellFlows(m_opmFldData->eclGraph, well_fluxes));
}
// Injection Solution
{
std::vector<CellSet> injectorCellSet;
for ( const auto& tIt: injectorTracers )
@@ -178,7 +227,7 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
injectorCellSet.push_back(CellSet(CellSetID(tIt.first), tIt.second));
}
Solution injSol = fdTool.computeInjectionDiagnostics(injectorCellSet).fd;
Solution injSol = m_opmFldData->fldToolbox->computeInjectionDiagnostics(injectorCellSet).fd;
for ( const CellSetID& tracerId: injSol.startPoints() )
{
@@ -189,13 +238,16 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
}
}
// Producer Solution
{
std::vector<CellSet> prodjCellSet;
for ( const auto& tIt: producerTracers )
{
prodjCellSet.push_back(CellSet(CellSetID(tIt.first), tIt.second));
}
Solution prodSol = fdTool.computeProductionDiagnostics(prodjCellSet).fd;
Solution prodSol = m_opmFldData->fldToolbox->computeProductionDiagnostics(prodjCellSet).fd;
for ( const CellSetID& tracerId: prodSol.startPoints() )
{
CellSetValues tofVals = prodSol.timeOfFlight(tracerId);
@@ -204,8 +256,6 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
result.setInjectorTracerFraction(tracerId.to_string(), fracVals);
}
}
}
return result; // Relying on implicit move constructor
}

View File

@@ -52,6 +52,7 @@ private:
class RigCaseData;
class RigOpmFldStaticData;
class RigFlowDiagSolverInterface : public cvf::Object
{
@@ -66,6 +67,8 @@ public:
private:
RimEclipseResultCase * m_eclipseCase;
cvf::ref<RigOpmFldStaticData> m_opmFldData;
};