mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Added support for building of metadata from existing time steps
Improved statistics calculation for opening single time step files Close all dynamic access files when a time step statistics is complete p4#: 20756
This commit is contained in:
parent
452b08db3a
commit
e94264a39f
@ -55,6 +55,7 @@
|
|||||||
#include "RimUiTreeModelPdm.h"
|
#include "RimUiTreeModelPdm.h"
|
||||||
#include "RiaImageCompareReporter.h"
|
#include "RiaImageCompareReporter.h"
|
||||||
#include "RiaImageFileCompare.h"
|
#include "RiaImageFileCompare.h"
|
||||||
|
#include "cafProgressInfo.h"
|
||||||
|
|
||||||
namespace caf
|
namespace caf
|
||||||
{
|
{
|
||||||
@ -1305,7 +1306,7 @@ bool RIApplication::addEclipseCases(const QStringList& fileNames)
|
|||||||
// First file is read completely including grid.
|
// First file is read completely including grid.
|
||||||
// The main grid from the first case is reused directly in for the other cases.
|
// The main grid from the first case is reused directly in for the other cases.
|
||||||
// When reading active cell info, only the total cell count is tested for consistency
|
// When reading active cell info, only the total cell count is tested for consistency
|
||||||
RigMainGrid* mainGrid = NULL;
|
RigEclipseCase* mainEclipseCase = NULL;
|
||||||
|
|
||||||
{
|
{
|
||||||
QString firstFileName = fileNames[0];
|
QString firstFileName = fileNames[0];
|
||||||
@ -1328,9 +1329,11 @@ bool RIApplication::addEclipseCases(const QStringList& fileNames)
|
|||||||
|
|
||||||
m_project->moveEclipseCaseIntoCaseGroup(rimResultReservoir);
|
m_project->moveEclipseCaseIntoCaseGroup(rimResultReservoir);
|
||||||
|
|
||||||
mainGrid = rimResultReservoir->reservoirData()->mainGrid();
|
mainEclipseCase = rimResultReservoir->reservoirData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
caf::ProgressInfo info(fileNames.size(), "Reading Active Cell data");
|
||||||
|
|
||||||
for (int i = 1; i < fileNames.size(); i++)
|
for (int i = 1; i < fileNames.size(); i++)
|
||||||
{
|
{
|
||||||
QString fileName = fileNames[i];
|
QString fileName = fileNames[i];
|
||||||
@ -1346,12 +1349,14 @@ bool RIApplication::addEclipseCases(const QStringList& fileNames)
|
|||||||
|
|
||||||
m_project->reservoirs.push_back(rimResultReservoir);
|
m_project->reservoirs.push_back(rimResultReservoir);
|
||||||
|
|
||||||
if (!rimResultReservoir->openAndReadActiveCellData(mainGrid))
|
if (!rimResultReservoir->openAndReadActiveCellData(mainEclipseCase))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_project->moveEclipseCaseIntoCaseGroup(rimResultReservoir);
|
m_project->moveEclipseCaseIntoCaseGroup(rimResultReservoir);
|
||||||
|
|
||||||
|
info.setProgress(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
onProjectOpenedOrClosed();
|
onProjectOpenedOrClosed();
|
||||||
|
@ -43,8 +43,10 @@ public:
|
|||||||
virtual ~RifEclipseRestartDataAccess();
|
virtual ~RifEclipseRestartDataAccess();
|
||||||
|
|
||||||
virtual bool open(const QStringList& fileSet) = 0;
|
virtual bool open(const QStringList& fileSet) = 0;
|
||||||
|
virtual void setFileSet(const QStringList& fileSet) {};
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
|
|
||||||
|
virtual void setTimeSteps(const QList<QDateTime>& timeSteps) {};
|
||||||
virtual size_t timeStepCount() = 0;
|
virtual size_t timeStepCount() = 0;
|
||||||
virtual QList<QDateTime> timeSteps() = 0;
|
virtual QList<QDateTime> timeSteps() = 0;
|
||||||
|
|
||||||
|
@ -42,20 +42,19 @@ RifEclipseRestartFilesetAccess::~RifEclipseRestartFilesetAccess()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RifEclipseRestartFilesetAccess::open(const QStringList& fileSet)
|
bool RifEclipseRestartFilesetAccess::open(const QStringList& fileSet)
|
||||||
{
|
{
|
||||||
setFileSet(fileSet);
|
if (m_fileNames.size() > 0)
|
||||||
|
|
||||||
int numFiles = fileSet.size();
|
|
||||||
|
|
||||||
caf::ProgressInfo progInfo(numFiles,"");
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < numFiles; i++)
|
|
||||||
{
|
{
|
||||||
progInfo.setProgressDescription(fileSet[i]);
|
caf::ProgressInfo progInfo(m_fileNames.size(), "");
|
||||||
|
|
||||||
openTimeStep(i);
|
int i;
|
||||||
|
for (i = 0; i < m_fileNames.size(); i++)
|
||||||
|
{
|
||||||
|
progInfo.setProgressDescription(m_fileNames[i]);
|
||||||
|
|
||||||
progInfo.incrementProgress();
|
openTimeStep(i);
|
||||||
|
|
||||||
|
progInfo.incrementProgress();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -95,12 +94,21 @@ void RifEclipseRestartFilesetAccess::close()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RifEclipseRestartFilesetAccess::setTimeSteps(const QList<QDateTime>& timeSteps)
|
||||||
|
{
|
||||||
|
CVF_ASSERT(m_fileNames.size() == timeSteps.size());
|
||||||
|
m_timeSteps = timeSteps;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
/// Get the number of time steps
|
/// Get the number of time steps
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
size_t RifEclipseRestartFilesetAccess::timeStepCount()
|
size_t RifEclipseRestartFilesetAccess::timeStepCount()
|
||||||
{
|
{
|
||||||
return m_ecl_files.size();
|
return m_timeSteps.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -108,29 +116,31 @@ size_t RifEclipseRestartFilesetAccess::timeStepCount()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
QList<QDateTime> RifEclipseRestartFilesetAccess::timeSteps()
|
QList<QDateTime> RifEclipseRestartFilesetAccess::timeSteps()
|
||||||
{
|
{
|
||||||
QList<QDateTime> timeSteps;
|
if (m_timeSteps.size() == 0)
|
||||||
|
|
||||||
size_t numSteps = timeStepCount();
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < numSteps; i++)
|
|
||||||
{
|
{
|
||||||
QList<QDateTime> stepTime;
|
size_t numSteps = m_fileNames.size();
|
||||||
|
size_t i;
|
||||||
openTimeStep(i);
|
for (i = 0; i < numSteps; i++)
|
||||||
|
|
||||||
RifEclipseOutputFileTools::timeSteps(m_ecl_files[i], &stepTime);
|
|
||||||
|
|
||||||
if (stepTime.size() == 1)
|
|
||||||
{
|
{
|
||||||
timeSteps.push_back(stepTime[0]);
|
QList<QDateTime> stepTime;
|
||||||
}
|
|
||||||
else
|
openTimeStep(i);
|
||||||
{
|
|
||||||
timeSteps.push_back(QDateTime());
|
RifEclipseOutputFileTools::timeSteps(m_ecl_files[i], &stepTime);
|
||||||
|
|
||||||
|
if (stepTime.size() == 1)
|
||||||
|
{
|
||||||
|
m_timeSteps.push_back(stepTime[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_timeSteps.push_back(QDateTime());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return timeSteps;
|
return m_timeSteps;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -39,6 +39,7 @@ public:
|
|||||||
void setFileSet(const QStringList& fileSet);
|
void setFileSet(const QStringList& fileSet);
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
void setTimeSteps(const QList<QDateTime>& timeSteps);
|
||||||
size_t timeStepCount();
|
size_t timeStepCount();
|
||||||
QList<QDateTime> timeSteps();
|
QList<QDateTime> timeSteps();
|
||||||
|
|
||||||
@ -52,5 +53,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList m_fileNames;
|
QStringList m_fileNames;
|
||||||
|
QList<QDateTime> m_timeSteps;
|
||||||
|
|
||||||
std::vector< ecl_file_type* > m_ecl_files;
|
std::vector< ecl_file_type* > m_ecl_files;
|
||||||
};
|
};
|
||||||
|
@ -392,7 +392,7 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigEclipseCase* eclip
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RifReaderEclipseOutput::openAndReadActiveCellData(const QString& fileName, RigEclipseCase* eclipseCase)
|
bool RifReaderEclipseOutput::openAndReadActiveCellData(const QString& fileName, RigEclipseCase* mainEclipseCase, RigEclipseCase* eclipseCase)
|
||||||
{
|
{
|
||||||
CVF_ASSERT(eclipseCase);
|
CVF_ASSERT(eclipseCase);
|
||||||
|
|
||||||
@ -402,8 +402,6 @@ bool RifReaderEclipseOutput::openAndReadActiveCellData(const QString& fileName,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
caf::ProgressInfo progInfo(100, "");
|
|
||||||
|
|
||||||
close();
|
close();
|
||||||
|
|
||||||
// Get set of files
|
// Get set of files
|
||||||
@ -417,23 +415,21 @@ bool RifReaderEclipseOutput::openAndReadActiveCellData(const QString& fileName,
|
|||||||
eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(this);
|
eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(this);
|
||||||
eclipseCase->results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(this);
|
eclipseCase->results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(this);
|
||||||
|
|
||||||
progInfo.setNextProgressIncrement(50);
|
|
||||||
progInfo.setProgressDescription("Reading active cell information");
|
|
||||||
|
|
||||||
if (!readActiveCellInfo())
|
if (!readActiveCellInfo())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
progInfo.incrementProgress();
|
|
||||||
|
|
||||||
progInfo.setNextProgressIncrement(50);
|
|
||||||
progInfo.setProgressDescription("Reading meta data");
|
|
||||||
|
|
||||||
// Reading of metadata and well cells is not performed here
|
// Reading of metadata and well cells is not performed here
|
||||||
//if (!buildMetaData()) return false;
|
//if (!buildMetaData()) return false;
|
||||||
// readWellCells();
|
// readWellCells();
|
||||||
|
|
||||||
|
m_dynamicResultsAccess = createDynamicResultsAccess(m_fileSet);
|
||||||
|
|
||||||
|
QList<QDateTime> mainCaseTimeSteps = mainEclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->readerInterface()->timeSteps();
|
||||||
|
m_dynamicResultsAccess->setTimeSteps(mainCaseTimeSteps);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,12 +524,14 @@ bool RifReaderEclipseOutput::buildMetaData()
|
|||||||
progInfo.setNextProgressIncrement(m_fileSet.size());
|
progInfo.setNextProgressIncrement(m_fileSet.size());
|
||||||
|
|
||||||
// Create access object for dynamic results
|
// Create access object for dynamic results
|
||||||
m_dynamicResultsAccess = dynamicResultsAccess(m_fileSet);
|
m_dynamicResultsAccess = createDynamicResultsAccess(m_fileSet);
|
||||||
if (m_dynamicResultsAccess.isNull())
|
if (m_dynamicResultsAccess.isNull())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_dynamicResultsAccess->open(m_fileSet);
|
||||||
|
|
||||||
|
|
||||||
progInfo.incrementProgress();
|
progInfo.incrementProgress();
|
||||||
|
|
||||||
@ -573,46 +571,46 @@ bool RifReaderEclipseOutput::buildMetaData()
|
|||||||
|
|
||||||
progInfo.incrementProgress();
|
progInfo.incrementProgress();
|
||||||
|
|
||||||
if (!openInitFile())
|
openInitFile();
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
progInfo.incrementProgress();
|
progInfo.incrementProgress();
|
||||||
|
|
||||||
QStringList resultNames;
|
if (m_ecl_init_file)
|
||||||
std::vector<size_t> resultNamesDataItemCounts;
|
|
||||||
RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(m_ecl_init_file, &resultNames, &resultNamesDataItemCounts);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
QStringList matrixResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, m_eclipseCase->activeCellInfo(), RifReaderInterface::MATRIX_RESULTS, 1);
|
QStringList resultNames;
|
||||||
|
std::vector<size_t> resultNamesDataItemCounts;
|
||||||
|
RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(m_ecl_init_file, &resultNames, &resultNamesDataItemCounts);
|
||||||
|
|
||||||
QList<QDateTime> staticDate;
|
|
||||||
if (m_timeSteps.size() > 0)
|
|
||||||
{
|
{
|
||||||
staticDate.push_back(m_timeSteps.front());
|
QStringList matrixResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, m_eclipseCase->activeCellInfo(), RifReaderInterface::MATRIX_RESULTS, 1);
|
||||||
|
|
||||||
|
QList<QDateTime> staticDate;
|
||||||
|
if (m_timeSteps.size() > 0)
|
||||||
|
{
|
||||||
|
staticDate.push_back(m_timeSteps.front());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < matrixResultNames.size(); ++i)
|
||||||
|
{
|
||||||
|
size_t resIndex = matrixModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, matrixResultNames[i]);
|
||||||
|
matrixModelResults->setTimeStepDates(resIndex, staticDate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < matrixResultNames.size(); ++i)
|
|
||||||
{
|
{
|
||||||
size_t resIndex = matrixModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, matrixResultNames[i]);
|
QStringList fractureResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, m_eclipseCase->activeCellInfo(), RifReaderInterface::FRACTURE_RESULTS, 1);
|
||||||
matrixModelResults->setTimeStepDates(resIndex, staticDate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
QList<QDateTime> staticDate;
|
||||||
QStringList fractureResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, m_eclipseCase->activeCellInfo(), RifReaderInterface::FRACTURE_RESULTS, 1);
|
if (m_timeSteps.size() > 0)
|
||||||
|
{
|
||||||
|
staticDate.push_back(m_timeSteps.front());
|
||||||
|
}
|
||||||
|
|
||||||
QList<QDateTime> staticDate;
|
for (int i = 0; i < fractureResultNames.size(); ++i)
|
||||||
if (m_timeSteps.size() > 0)
|
{
|
||||||
{
|
size_t resIndex = fractureModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, fractureResultNames[i]);
|
||||||
staticDate.push_back(m_timeSteps.front());
|
fractureModelResults->setTimeStepDates(resIndex, staticDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < fractureResultNames.size(); ++i)
|
|
||||||
{
|
|
||||||
size_t resIndex = fractureModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, fractureResultNames[i]);
|
|
||||||
fractureModelResults->setTimeStepDates(resIndex, staticDate);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,7 +620,7 @@ bool RifReaderEclipseOutput::buildMetaData()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
/// Create results access object (.UNRST or .X0001 ... .XNNNN)
|
/// Create results access object (.UNRST or .X0001 ... .XNNNN)
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
RifEclipseRestartDataAccess* RifReaderEclipseOutput::dynamicResultsAccess(const QStringList& fileSet)
|
RifEclipseRestartDataAccess* RifReaderEclipseOutput::createDynamicResultsAccess(const QStringList& fileSet)
|
||||||
{
|
{
|
||||||
RifEclipseRestartDataAccess* resultsAccess = NULL;
|
RifEclipseRestartDataAccess* resultsAccess = NULL;
|
||||||
|
|
||||||
@ -631,11 +629,7 @@ RifEclipseRestartDataAccess* RifReaderEclipseOutput::dynamicResultsAccess(const
|
|||||||
if (unrstFileName.size() > 0)
|
if (unrstFileName.size() > 0)
|
||||||
{
|
{
|
||||||
resultsAccess = new RifEclipseUnifiedRestartFileAccess();
|
resultsAccess = new RifEclipseUnifiedRestartFileAccess();
|
||||||
if (!resultsAccess->open(QStringList(unrstFileName)))
|
resultsAccess->setFileSet(QStringList(unrstFileName));
|
||||||
{
|
|
||||||
delete resultsAccess;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -644,17 +638,10 @@ RifEclipseRestartDataAccess* RifReaderEclipseOutput::dynamicResultsAccess(const
|
|||||||
if (restartFiles.size() > 0)
|
if (restartFiles.size() > 0)
|
||||||
{
|
{
|
||||||
resultsAccess = new RifEclipseRestartFilesetAccess();
|
resultsAccess = new RifEclipseRestartFilesetAccess();
|
||||||
if (!resultsAccess->open(restartFiles))
|
resultsAccess->setFileSet(restartFiles);
|
||||||
{
|
|
||||||
delete resultsAccess;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// !! could add support for formatted result files
|
|
||||||
// !! consider priorities in case multiple types exist (.UNRST, .XNNNN, ...)
|
|
||||||
|
|
||||||
return resultsAccess;
|
return resultsAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,7 +680,16 @@ bool RifReaderEclipseOutput::staticResult(const QString& result, PorosityModelRe
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RifReaderEclipseOutput::dynamicResult(const QString& result, PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector<double>* values)
|
bool RifReaderEclipseOutput::dynamicResult(const QString& result, PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector<double>* values)
|
||||||
{
|
{
|
||||||
CVF_ASSERT(m_dynamicResultsAccess.notNull());
|
if (m_dynamicResultsAccess.isNull())
|
||||||
|
{
|
||||||
|
m_dynamicResultsAccess = createDynamicResultsAccess(m_fileSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_dynamicResultsAccess.isNull())
|
||||||
|
{
|
||||||
|
CVF_ASSERT(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<double> fileValues;
|
std::vector<double> fileValues;
|
||||||
if (!m_dynamicResultsAccess->results(result, stepIndex, m_eclipseCase->mainGrid()->gridCount(), &fileValues))
|
if (!m_dynamicResultsAccess->results(result, stepIndex, m_eclipseCase->mainGrid()->gridCount(), &fileValues))
|
||||||
@ -1020,3 +1016,11 @@ bool RifReaderEclipseOutput::openInitFile()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
QList<QDateTime> RifReaderEclipseOutput::timeSteps()
|
||||||
|
{
|
||||||
|
return m_timeSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ public:
|
|||||||
virtual ~RifReaderEclipseOutput();
|
virtual ~RifReaderEclipseOutput();
|
||||||
|
|
||||||
bool open(const QString& fileName, RigEclipseCase* eclipseCase);
|
bool open(const QString& fileName, RigEclipseCase* eclipseCase);
|
||||||
virtual bool openAndReadActiveCellData(const QString& fileName, RigEclipseCase* eclipseCase);
|
virtual bool openAndReadActiveCellData(const QString& fileName, RigEclipseCase* mainEclipseCase, RigEclipseCase* eclipseCase);
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
bool staticResult(const QString& result, PorosityModelResultType matrixOrFracture, std::vector<double>* values);
|
bool staticResult(const QString& result, PorosityModelResultType matrixOrFracture, std::vector<double>* values);
|
||||||
@ -58,14 +58,15 @@ private:
|
|||||||
void readWellCells();
|
void readWellCells();
|
||||||
|
|
||||||
bool openInitFile();
|
bool openInitFile();
|
||||||
|
bool openDynamicAccess();
|
||||||
|
|
||||||
void extractResultValuesBasedOnPorosityModel(PorosityModelResultType matrixOrFracture, std::vector<double>* values, const std::vector<double>& fileValues);
|
void extractResultValuesBasedOnPorosityModel(PorosityModelResultType matrixOrFracture, std::vector<double>* values, const std::vector<double>& fileValues);
|
||||||
|
|
||||||
static RifEclipseRestartDataAccess* staticResultsAccess(const QStringList& fileSet);
|
static RifEclipseRestartDataAccess* createDynamicResultsAccess(const QStringList& fileSet);
|
||||||
static RifEclipseRestartDataAccess* dynamicResultsAccess(const QStringList& fileSet);
|
|
||||||
|
|
||||||
QStringList validKeywordsForPorosityModel(const QStringList& keywords, const std::vector<size_t>& keywordDataItemCounts, const RigActiveCellInfo* activeCellInfo, PorosityModelResultType matrixOrFracture, size_t timeStepCount) const;
|
QStringList validKeywordsForPorosityModel(const QStringList& keywords, const std::vector<size_t>& keywordDataItemCounts, const RigActiveCellInfo* activeCellInfo, PorosityModelResultType matrixOrFracture, size_t timeStepCount) const;
|
||||||
|
|
||||||
|
virtual QList<QDateTime> timeSteps();
|
||||||
private:
|
private:
|
||||||
QString m_fileName; // Name of file used to start accessing Eclipse output files
|
QString m_fileName; // Name of file used to start accessing Eclipse output files
|
||||||
QStringList m_fileSet; // Set of files in filename's path with same base name as filename
|
QStringList m_fileSet; // Set of files in filename's path with same base name as filename
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
|
|
||||||
class RigEclipseCase;
|
class RigEclipseCase;
|
||||||
@ -47,9 +48,11 @@ public:
|
|||||||
virtual ~RifReaderInterface() {}
|
virtual ~RifReaderInterface() {}
|
||||||
|
|
||||||
virtual bool open(const QString& fileName, RigEclipseCase* eclipseCase) = 0;
|
virtual bool open(const QString& fileName, RigEclipseCase* eclipseCase) = 0;
|
||||||
virtual bool openAndReadActiveCellData(const QString& fileName, RigEclipseCase* eclipseCase) { return true; };
|
virtual bool openAndReadActiveCellData(const QString& fileName, RigEclipseCase* mainEclipseCase, RigEclipseCase* eclipseCase) { return true; };
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
|
|
||||||
virtual bool staticResult(const QString& result, PorosityModelResultType matrixOrFracture, std::vector<double>* values) = 0;
|
virtual bool staticResult(const QString& result, PorosityModelResultType matrixOrFracture, std::vector<double>* values) = 0;
|
||||||
virtual bool dynamicResult(const QString& result, PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector<double>* values) = 0;
|
virtual bool dynamicResult(const QString& result, PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector<double>* values) = 0;
|
||||||
|
|
||||||
|
virtual QList<QDateTime> timeSteps() { QList<QDateTime> timeSteps; return timeSteps; }
|
||||||
};
|
};
|
||||||
|
@ -93,7 +93,7 @@ bool RimResultReservoir::openEclipseGridFile()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RimResultReservoir::openAndReadActiveCellData(RigMainGrid* mainGrid)
|
bool RimResultReservoir::openAndReadActiveCellData(RigEclipseCase* mainEclipseCase)
|
||||||
{
|
{
|
||||||
cvf::ref<RifReaderInterface> readerInterface;
|
cvf::ref<RifReaderInterface> readerInterface;
|
||||||
|
|
||||||
@ -113,10 +113,12 @@ bool RimResultReservoir::openAndReadActiveCellData(RigMainGrid* mainGrid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cvf::ref<RigEclipseCase> eclipseCase = new RigEclipseCase;
|
cvf::ref<RigEclipseCase> eclipseCase = new RigEclipseCase;
|
||||||
eclipseCase->setMainGrid(mainGrid);
|
|
||||||
|
CVF_ASSERT(mainEclipseCase && mainEclipseCase->mainGrid());
|
||||||
|
eclipseCase->setMainGrid(mainEclipseCase->mainGrid());
|
||||||
|
|
||||||
readerInterface = new RifReaderEclipseOutput;
|
readerInterface = new RifReaderEclipseOutput;
|
||||||
if (!readerInterface->openAndReadActiveCellData(fname, eclipseCase.p()))
|
if (!readerInterface->openAndReadActiveCellData(fname, mainEclipseCase, eclipseCase.p()))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
caf::PdmField<QString> caseDirectory;
|
caf::PdmField<QString> caseDirectory;
|
||||||
|
|
||||||
virtual bool openEclipseGridFile();
|
virtual bool openEclipseGridFile();
|
||||||
bool openAndReadActiveCellData(RigMainGrid* mainGrid);
|
bool openAndReadActiveCellData(RigEclipseCase* mainEclipseCase);
|
||||||
|
|
||||||
//virtual caf::PdmFieldHandle* userDescriptionField() { return &caseName;}
|
//virtual caf::PdmFieldHandle* userDescriptionField() { return &caseName;}
|
||||||
|
|
||||||
|
@ -152,8 +152,12 @@ void RimStatisticalCalculation::computeStatistics()
|
|||||||
RigStatisticsConfig statisticsConfig;
|
RigStatisticsConfig statisticsConfig;
|
||||||
|
|
||||||
std::vector<size_t> timeStepIndices;
|
std::vector<size_t> timeStepIndices;
|
||||||
timeStepIndices.push_back(0);
|
|
||||||
timeStepIndices.push_back(1);
|
size_t timeStepCount = sourceCases.at(0)->results(RifReaderInterface::MATRIX_RESULTS)->maxTimeStepCount();
|
||||||
|
for (size_t i = 0; i < timeStepCount; i++)
|
||||||
|
{
|
||||||
|
timeStepIndices.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
RigEclipseCase* resultCase = reservoirData();
|
RigEclipseCase* resultCase = reservoirData();
|
||||||
|
|
||||||
|
@ -408,3 +408,16 @@ cvf::ref<cvf::StructGridScalarDataAccess> RigEclipseCase::dataAccessObject(const
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RigEclipseCase::closeReaderInterface()
|
||||||
|
{
|
||||||
|
RifReaderInterface* readerInterface = m_matrixModelResults->readerInterface();
|
||||||
|
|
||||||
|
if (readerInterface)
|
||||||
|
{
|
||||||
|
readerInterface->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -49,6 +49,8 @@ public:
|
|||||||
RigReservoirCellResults* results(RifReaderInterface::PorosityModelResultType porosityModel);
|
RigReservoirCellResults* results(RifReaderInterface::PorosityModelResultType porosityModel);
|
||||||
const RigReservoirCellResults* results(RifReaderInterface::PorosityModelResultType porosityModel) const;
|
const RigReservoirCellResults* results(RifReaderInterface::PorosityModelResultType porosityModel) const;
|
||||||
|
|
||||||
|
void closeReaderInterface();
|
||||||
|
|
||||||
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObject(const RigGridBase* grid,
|
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObject(const RigGridBase* grid,
|
||||||
RifReaderInterface::PorosityModelResultType porosityModel,
|
RifReaderInterface::PorosityModelResultType porosityModel,
|
||||||
size_t timeStepIndex,
|
size_t timeStepIndex,
|
||||||
@ -74,7 +76,6 @@ private:
|
|||||||
void computeWellCellsPrGrid();
|
void computeWellCellsPrGrid();
|
||||||
void computeActiveCellsGeometryBoundingBox();
|
void computeActiveCellsGeometryBoundingBox();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RigActiveCellInfo m_activeCellInfo;
|
RigActiveCellInfo m_activeCellInfo;
|
||||||
|
|
||||||
|
@ -268,6 +268,61 @@ double RigReservoirCellResults::cellScalarResult( size_t scalarResultIndex, size
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
size_t RigReservoirCellResults::findOrLoadScalarResultForTimeStep(RimDefines::ResultCatType type, const QString& resultName, size_t timeStepIndex)
|
||||||
|
{
|
||||||
|
size_t resultGridIndex = cvf::UNDEFINED_SIZE_T;
|
||||||
|
|
||||||
|
resultGridIndex = findScalarResultIndex(type, resultName);
|
||||||
|
|
||||||
|
if (resultGridIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T;
|
||||||
|
|
||||||
|
if (type == RimDefines::GENERATED)
|
||||||
|
{
|
||||||
|
return cvf::UNDEFINED_SIZE_T;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_readerInterface.notNull())
|
||||||
|
{
|
||||||
|
// Add one more result to result container
|
||||||
|
size_t timeStepCount = m_resultInfos[resultGridIndex].m_timeStepDates.size();
|
||||||
|
|
||||||
|
bool resultLoadingSucess = true;
|
||||||
|
|
||||||
|
if (type == RimDefines::DYNAMIC_NATIVE && timeStepCount > 0)
|
||||||
|
{
|
||||||
|
std::vector<double>& values = m_cellScalarResults[resultGridIndex][timeStepIndex];
|
||||||
|
if (values.size() == 0)
|
||||||
|
{
|
||||||
|
if (!m_readerInterface->dynamicResult(resultName, RifReaderInterface::MATRIX_RESULTS, timeStepIndex, &values))
|
||||||
|
{
|
||||||
|
resultLoadingSucess = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == RimDefines::STATIC_NATIVE)
|
||||||
|
{
|
||||||
|
std::vector<double>& values = m_cellScalarResults[resultGridIndex][0];
|
||||||
|
if (!m_readerInterface->staticResult(resultName, RifReaderInterface::MATRIX_RESULTS, &values))
|
||||||
|
{
|
||||||
|
resultLoadingSucess = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!resultLoadingSucess)
|
||||||
|
{
|
||||||
|
// Error logging
|
||||||
|
CVF_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultGridIndex;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -336,6 +391,15 @@ void RigReservoirCellResults::setReaderInterface(RifReaderInterface* readerInter
|
|||||||
m_readerInterface = readerInterface;
|
m_readerInterface = readerInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RifReaderInterface* RigReservoirCellResults::readerInterface()
|
||||||
|
{
|
||||||
|
return m_readerInterface.p();
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -697,12 +761,15 @@ void RigReservoirCellResults::setTimeStepDates(size_t scalarResultIndex, const Q
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
size_t RigReservoirCellResults::maxTimeStepCount() const
|
size_t RigReservoirCellResults::maxTimeStepCount() const
|
||||||
{
|
{
|
||||||
size_t maxTsCount = 0;
|
int maxTsCount = 0;
|
||||||
for (size_t i = 0; i < m_cellScalarResults.size(); ++i)
|
|
||||||
|
std::vector<ResultInfo>::const_iterator it;
|
||||||
|
for (it = m_resultInfos.begin(); it != m_resultInfos.end(); it++)
|
||||||
{
|
{
|
||||||
maxTsCount = m_cellScalarResults[i].size() > maxTsCount ? m_cellScalarResults[i].size() : maxTsCount;
|
maxTsCount = it->m_timeStepDates.size() > maxTsCount ? it->m_timeStepDates.size() : maxTsCount;
|
||||||
}
|
}
|
||||||
return maxTsCount;
|
|
||||||
|
return static_cast<size_t>(maxTsCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -36,6 +36,7 @@ public:
|
|||||||
RigReservoirCellResults(RigMainGrid* ownerGrid);
|
RigReservoirCellResults(RigMainGrid* ownerGrid);
|
||||||
|
|
||||||
void setReaderInterface(RifReaderInterface* readerInterface);
|
void setReaderInterface(RifReaderInterface* readerInterface);
|
||||||
|
RifReaderInterface* readerInterface();
|
||||||
|
|
||||||
// Max and min values of the results
|
// Max and min values of the results
|
||||||
void recalculateMinMax(size_t scalarResultIndex);
|
void recalculateMinMax(size_t scalarResultIndex);
|
||||||
@ -57,6 +58,7 @@ public:
|
|||||||
void setTimeStepDates(size_t scalarResultIndex, const QList<QDateTime>& dates);
|
void setTimeStepDates(size_t scalarResultIndex, const QList<QDateTime>& dates);
|
||||||
|
|
||||||
// Find or create a slot for the results
|
// Find or create a slot for the results
|
||||||
|
size_t findOrLoadScalarResultForTimeStep(RimDefines::ResultCatType type, const QString& resultName, size_t timeStepIndex);
|
||||||
size_t findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName);
|
size_t findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName);
|
||||||
size_t findOrLoadScalarResult(const QString& resultName); ///< Simplified search. Assumes unique names across types.
|
size_t findOrLoadScalarResult(const QString& resultName); ///< Simplified search. Assumes unique names across types.
|
||||||
size_t findScalarResultIndex(RimDefines::ResultCatType type, const QString& resultName) const;
|
size_t findScalarResultIndex(RimDefines::ResultCatType type, const QString& resultName) const;
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "RigReservoirCellResults.h"
|
#include "RigReservoirCellResults.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include "cafProgressInfo.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
@ -36,7 +37,7 @@ void RigStatistics::addNamedResult(RigReservoirCellResults* cellResults, RimDefi
|
|||||||
std::vector< std::vector<double> >& dataValues = cellResults->cellScalarResults(resultIndexMin);
|
std::vector< std::vector<double> >& dataValues = cellResults->cellScalarResults(resultIndexMin);
|
||||||
dataValues.resize(timeStepDates.size());
|
dataValues.resize(timeStepDates.size());
|
||||||
|
|
||||||
for (size_t i = 0; i < timeStepDates.size(); i++)
|
for (int i = 0; i < timeStepDates.size(); i++)
|
||||||
{
|
{
|
||||||
dataValues[i].resize(activeCellCount, HUGE_VAL);
|
dataValues[i].resize(activeCellCount, HUGE_VAL);
|
||||||
}
|
}
|
||||||
@ -109,6 +110,8 @@ void RigStatistics::evaluateStatistics(RimDefines::ResultCatType resultType, con
|
|||||||
|
|
||||||
computeActiveCellUnion();
|
computeActiveCellUnion();
|
||||||
|
|
||||||
|
buildSourceMetaData(resultType, resultName);
|
||||||
|
|
||||||
QString minResultName = resultName + "_MIN";
|
QString minResultName = resultName + "_MIN";
|
||||||
QString maxResultName = resultName + "_MAX";
|
QString maxResultName = resultName + "_MAX";
|
||||||
QString meanResultName = resultName + "_MEAN";
|
QString meanResultName = resultName + "_MEAN";
|
||||||
@ -127,6 +130,8 @@ void RigStatistics::evaluateStatistics(RimDefines::ResultCatType resultType, con
|
|||||||
|
|
||||||
if (activeMatrixCellCount > 0)
|
if (activeMatrixCellCount > 0)
|
||||||
{
|
{
|
||||||
|
caf::ProgressInfo info(m_timeStepIndices.size(), "Computing Statistics");
|
||||||
|
|
||||||
for (size_t timeIndicesIdx = 0; timeIndicesIdx < m_timeStepIndices.size(); timeIndicesIdx++)
|
for (size_t timeIndicesIdx = 0; timeIndicesIdx < m_timeStepIndices.size(); timeIndicesIdx++)
|
||||||
{
|
{
|
||||||
size_t timeStepIdx = m_timeStepIndices[timeIndicesIdx];
|
size_t timeStepIdx = m_timeStepIndices[timeIndicesIdx];
|
||||||
@ -142,7 +147,7 @@ void RigStatistics::evaluateStatistics(RimDefines::ResultCatType resultType, con
|
|||||||
{
|
{
|
||||||
RigEclipseCase* eclipseCase = m_sourceCases.at(caseIdx);
|
RigEclipseCase* eclipseCase = m_sourceCases.at(caseIdx);
|
||||||
|
|
||||||
size_t scalarResultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResult(resultName);
|
size_t scalarResultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResultForTimeStep(resultType, resultName, timeStepIdx);
|
||||||
|
|
||||||
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObject = eclipseCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, timeStepIdx, scalarResultIndex);
|
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObject = eclipseCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, timeStepIdx, scalarResultIndex);
|
||||||
if (dataAccessObject.notNull())
|
if (dataAccessObject.notNull())
|
||||||
@ -227,6 +232,19 @@ void RigStatistics::evaluateStatistics(RimDefines::ResultCatType resultType, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++)
|
||||||
|
{
|
||||||
|
RigEclipseCase* eclipseCase = m_sourceCases.at(caseIdx);
|
||||||
|
|
||||||
|
// When one time step is completed, close all result files.
|
||||||
|
// Microsoft note: On Windows, the maximum number of files open at the same time is 512
|
||||||
|
// http://msdn.microsoft.com/en-us/library/kdfaxaay%28vs.71%29.aspx
|
||||||
|
//
|
||||||
|
eclipseCase->closeReaderInterface();
|
||||||
|
}
|
||||||
|
|
||||||
|
info.setProgress(timeIndicesIdx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,3 +282,27 @@ RigStatistics::RigStatistics(cvf::Collection<RigEclipseCase>& sourceCases, const
|
|||||||
m_globalCellCount = sourceCases[0]->mainGrid()->cells().size();
|
m_globalCellCount = sourceCases[0]->mainGrid()->cells().size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RigStatistics::buildSourceMetaData(RimDefines::ResultCatType resultType, const QString& resultName)
|
||||||
|
{
|
||||||
|
for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++)
|
||||||
|
{
|
||||||
|
RigEclipseCase* eclipseCase = m_sourceCases.at(caseIdx);
|
||||||
|
|
||||||
|
RigReservoirCellResults* matrixResults = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS);
|
||||||
|
size_t scalarResultIndex = matrixResults->findOrLoadScalarResult(resultType, resultName);
|
||||||
|
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
|
||||||
|
{
|
||||||
|
QList<QDateTime> timeStepDates = m_sourceCases[0]->results(RifReaderInterface::MATRIX_RESULTS)->timeStepDates(0);
|
||||||
|
|
||||||
|
size_t scalarResultIndex = matrixResults->addEmptyScalarResult(resultType, resultName);
|
||||||
|
matrixResults->setTimeStepDates(scalarResultIndex, timeStepDates);
|
||||||
|
|
||||||
|
std::vector< std::vector<double> >& dataValues = matrixResults->cellScalarResults(scalarResultIndex);
|
||||||
|
dataValues.resize(timeStepDates.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -135,7 +135,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void computeActiveCellUnion();
|
void computeActiveCellUnion();
|
||||||
void addNamedResult(RigReservoirCellResults* cellResults, RimDefines::ResultCatType resultType, const QString& resultName, size_t activeCellCount);
|
void addNamedResult(RigReservoirCellResults* cellResults, RimDefines::ResultCatType resultType, const QString& resultName, size_t activeCellCount);
|
||||||
|
void buildSourceMetaData( RimDefines::ResultCatType resultType, const QString& resultName );
|
||||||
private:
|
private:
|
||||||
cvf::Collection<RigEclipseCase> m_sourceCases;
|
cvf::Collection<RigEclipseCase> m_sourceCases;
|
||||||
std::vector<size_t> m_timeStepIndices;
|
std::vector<size_t> m_timeStepIndices;
|
||||||
|
Loading…
Reference in New Issue
Block a user