mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#4580 Import Eclipse RFT data as part of ensemble import
This commit is contained in:
@@ -16,7 +16,9 @@ ${CMAKE_CURRENT_LIST_DIR}/RifColumnBasedUserDataParser.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifKeywordVectorParser.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderObservedData.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseSummary.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderRftInterface.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseRft.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderFmuRft.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifJsonEncodeDecode.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderInterface.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderMockModel.h
|
||||
@@ -42,6 +44,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RifSummaryCaseRestartSelector.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifCaseRealizationParametersReader.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifFileParseTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifEnsembleStatisticsReader.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEnsembleStatisticsRft.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifDerivedEnsembleReader.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifActiveCellsReader.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifCsvDataTableFormatter.h
|
||||
@@ -68,7 +71,9 @@ ${CMAKE_CURRENT_LIST_DIR}/RifColumnBasedUserDataParser.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifKeywordVectorParser.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderObservedData.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseSummary.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderRftInterface.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseRft.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderFmuRft.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifJsonEncodeDecode.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderInterface.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderMockModel.cpp
|
||||
@@ -95,6 +100,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RifEnsembleStatisticsReader.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifDerivedEnsembleReader.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifActiveCellsReader.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifCsvDataTableFormatter.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEnsembleStatisticsRft.cpp
|
||||
|
||||
# HDF5 file reader is directly included in ResInsight main CmakeList.txt
|
||||
#${CMAKE_CURRENT_LIST_DIR}/RifHdf5Reader.cpp
|
||||
|
||||
@@ -135,6 +135,14 @@ std::string RifColumnBasedUserData::unitName(const RifEclipseSummaryAddress& res
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifColumnBasedUserData::unitSystem() const
|
||||
{
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -48,7 +48,8 @@ public:
|
||||
bool values(const RifEclipseSummaryAddress& resultAddress,
|
||||
std::vector<double>* values) const override;
|
||||
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
|
||||
private:
|
||||
void buildTimeStepsAndMappings();
|
||||
|
||||
@@ -140,6 +140,14 @@ std::string RifCsvUserData::unitName(const RifEclipseSummaryAddress& resultAddre
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifCsvUserData::unitSystem() const
|
||||
{
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -52,6 +52,9 @@ public:
|
||||
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
|
||||
private:
|
||||
void buildTimeStepsAndMappings();
|
||||
|
||||
|
||||
@@ -1,41 +1,43 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil ASA
|
||||
//
|
||||
//
|
||||
// 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>
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RifDataSourceForRftPlt.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimSummaryCase.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
#include "RimWellLogFile.h"
|
||||
|
||||
#include "RimEclipseResultCase.h"
|
||||
#include "cafAppEnum.h"
|
||||
#include "cvfAssert.h"
|
||||
#include <QString>
|
||||
#include <QTextStream>
|
||||
#include "RimEclipseResultCase.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt::RifDataSourceForRftPlt() : m_sourceType(SourceType::NONE)
|
||||
RifDataSourceForRftPlt::RifDataSourceForRftPlt()
|
||||
: m_sourceType(SourceType::NONE)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt::RifDataSourceForRftPlt(SourceType sourceType, RimEclipseCase* eclCase)
|
||||
{
|
||||
@@ -43,22 +45,47 @@ RifDataSourceForRftPlt::RifDataSourceForRftPlt(SourceType sourceType, RimEclipse
|
||||
CVF_ASSERT(eclCase != nullptr);
|
||||
|
||||
m_sourceType = sourceType;
|
||||
m_eclCase = eclCase;
|
||||
m_eclCase = eclCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt::RifDataSourceForRftPlt(SourceType sourceType, RimWellLogFile* wellLogFile)
|
||||
{
|
||||
CVF_ASSERT(sourceType == SourceType::OBSERVED);
|
||||
|
||||
m_sourceType = sourceType;
|
||||
m_sourceType = sourceType;
|
||||
m_wellLogFile = wellLogFile;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt::RifDataSourceForRftPlt(SourceType sourceType, RimSummaryCaseCollection* ensemble)
|
||||
{
|
||||
CVF_ASSERT(sourceType == SourceType::ENSEMBLE_RFT);
|
||||
|
||||
m_sourceType = sourceType;
|
||||
m_ensemble = ensemble;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt::RifDataSourceForRftPlt(SourceType sourceType,
|
||||
RimSummaryCase* summaryCase,
|
||||
RimSummaryCaseCollection* ensemble)
|
||||
{
|
||||
CVF_ASSERT(sourceType == SourceType::SUMMARY_RFT);
|
||||
|
||||
m_sourceType = sourceType;
|
||||
m_summaryCase = summaryCase;
|
||||
m_ensemble = ensemble;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt::SourceType RifDataSourceForRftPlt::sourceType() const
|
||||
{
|
||||
@@ -66,7 +93,7 @@ RifDataSourceForRftPlt::SourceType RifDataSourceForRftPlt::sourceType() const
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEclipseCase* RifDataSourceForRftPlt::eclCase() const
|
||||
{
|
||||
@@ -74,22 +101,45 @@ RimEclipseCase* RifDataSourceForRftPlt::eclCase() const
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEclipseRft* RifDataSourceForRftPlt::rftReader() const
|
||||
RifReaderRftInterface* RifDataSourceForRftPlt::rftReader() const
|
||||
{
|
||||
if (m_sourceType == RFT)
|
||||
{
|
||||
auto eclResCase = dynamic_cast<RimEclipseResultCase*>(m_eclCase.p());
|
||||
|
||||
if (eclResCase ) return eclResCase->rftReader();
|
||||
if (eclResCase) return eclResCase->rftReader();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
else if (m_sourceType == SUMMARY_RFT)
|
||||
{
|
||||
if (m_summaryCase) return m_summaryCase->rftReader();
|
||||
}
|
||||
else if (m_sourceType == ENSEMBLE_RFT)
|
||||
{
|
||||
if (m_ensemble) return m_ensemble->rftStatisticsReader();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCaseCollection* RifDataSourceForRftPlt::ensemble() const
|
||||
{
|
||||
return m_ensemble;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCase* RifDataSourceForRftPlt::summaryCase() const
|
||||
{
|
||||
return m_summaryCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellLogFile* RifDataSourceForRftPlt::wellLogFile() const
|
||||
{
|
||||
@@ -97,33 +147,40 @@ RimWellLogFile* RifDataSourceForRftPlt::wellLogFile() const
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RifDataSourceForRftPlt::sourceTypeUiText(SourceType sourceType)
|
||||
{
|
||||
switch (sourceType)
|
||||
{
|
||||
case SourceType::RFT: return QString("RFT File Cases");
|
||||
case SourceType::GRID: return QString("Grid Cases");
|
||||
case SourceType::OBSERVED: return QString("Observed Data");
|
||||
case SourceType::RFT:
|
||||
return QString("RFT File Cases");
|
||||
case SourceType::GRID:
|
||||
return QString("Grid Cases");
|
||||
case SourceType::OBSERVED:
|
||||
return QString("Observed Data");
|
||||
case SourceType::ENSEMBLE_RFT:
|
||||
return QString("Ensembles with RFT Data");
|
||||
case SourceType::SUMMARY_RFT:
|
||||
return QString("Summary case with RFT Data");
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool operator==(const RifDataSourceForRftPlt& addr1, const RifDataSourceForRftPlt& addr2)
|
||||
{
|
||||
return addr1.sourceType() == addr2.sourceType()
|
||||
&& addr1.eclCase() == addr2.eclCase()
|
||||
&& addr1.wellLogFile() == addr2.wellLogFile();
|
||||
return addr1.sourceType() == addr2.sourceType() && addr1.eclCase() == addr2.eclCase() &&
|
||||
addr1.wellLogFile() == addr2.wellLogFile() && addr1.summaryCase() == addr2.summaryCase() &&
|
||||
addr1.ensemble() == addr2.ensemble();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QTextStream& operator << (QTextStream& str, const RifDataSourceForRftPlt& addr)
|
||||
QTextStream& operator<<(QTextStream& str, const RifDataSourceForRftPlt& addr)
|
||||
{
|
||||
// Not implemented
|
||||
CVF_ASSERT(false);
|
||||
@@ -131,9 +188,9 @@ QTextStream& operator << (QTextStream& str, const RifDataSourceForRftPlt& addr)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QTextStream& operator >> (QTextStream& str, RifDataSourceForRftPlt& source)
|
||||
QTextStream& operator>>(QTextStream& str, RifDataSourceForRftPlt& source)
|
||||
{
|
||||
// Not implemented
|
||||
CVF_ASSERT(false);
|
||||
@@ -146,16 +203,16 @@ QTextStream& operator >> (QTextStream& str, RifDataSourceForRftPlt& source)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool operator<(const RifDataSourceForRftPlt& addr1, const RifDataSourceForRftPlt& addr2)
|
||||
{
|
||||
if ( addr1.m_sourceType != addr2.m_sourceType )
|
||||
if (addr1.m_sourceType != addr2.m_sourceType)
|
||||
{
|
||||
return addr1.m_sourceType < addr2.m_sourceType;
|
||||
}
|
||||
|
||||
if ( addr1.m_sourceType == RifDataSourceForRftPlt::NONE ) return false; //
|
||||
|
||||
if (addr1.m_sourceType == RifDataSourceForRftPlt::OBSERVED)
|
||||
{
|
||||
if(addr1.wellLogFile() && addr2.wellLogFile())
|
||||
if (addr1.m_sourceType == RifDataSourceForRftPlt::NONE) return false; //
|
||||
|
||||
if (addr1.m_sourceType == RifDataSourceForRftPlt::OBSERVED)
|
||||
{
|
||||
if (addr1.wellLogFile() && addr2.wellLogFile())
|
||||
{
|
||||
return addr1.wellLogFile()->fileName() < addr2.wellLogFile()->fileName();
|
||||
}
|
||||
@@ -164,9 +221,31 @@ bool operator<(const RifDataSourceForRftPlt& addr1, const RifDataSourceForRftPlt
|
||||
return addr1.wellLogFile() < addr2.wellLogFile();
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (addr1.m_sourceType == RifDataSourceForRftPlt::SUMMARY_RFT)
|
||||
{
|
||||
if ( addr1.eclCase() && addr2.eclCase() )
|
||||
if (addr1.summaryCase() && addr2.summaryCase())
|
||||
{
|
||||
return addr1.summaryCase()->caseName() < addr2.summaryCase()->caseName();
|
||||
}
|
||||
else
|
||||
{
|
||||
return addr1.summaryCase() < addr2.summaryCase();
|
||||
}
|
||||
}
|
||||
else if (addr1.m_sourceType == RifDataSourceForRftPlt::ENSEMBLE_RFT)
|
||||
{
|
||||
if (addr1.ensemble() && addr2.ensemble())
|
||||
{
|
||||
return addr1.ensemble()->name() < addr2.ensemble()->name();
|
||||
}
|
||||
else
|
||||
{
|
||||
return addr1.ensemble() < addr2.ensemble();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addr1.eclCase() && addr2.eclCase())
|
||||
{
|
||||
return addr1.eclCase()->caseId() < addr2.eclCase()->caseId();
|
||||
}
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
|
||||
class RimWellLogFile;
|
||||
class RimEclipseCase;
|
||||
class RifReaderEclipseRft;
|
||||
class RifReaderRftInterface;
|
||||
class RimSummaryCase;
|
||||
class RimSummaryCaseCollection;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@@ -46,16 +48,22 @@ public:
|
||||
NONE,
|
||||
OBSERVED,
|
||||
RFT,
|
||||
GRID
|
||||
GRID,
|
||||
ENSEMBLE_RFT,
|
||||
SUMMARY_RFT
|
||||
};
|
||||
|
||||
RifDataSourceForRftPlt();
|
||||
RifDataSourceForRftPlt(SourceType sourceType, RimEclipseCase* eclCase);
|
||||
RifDataSourceForRftPlt(SourceType sourceType, RimSummaryCaseCollection* ensemble);
|
||||
RifDataSourceForRftPlt(SourceType sourceType, RimSummaryCase* summaryCase, RimSummaryCaseCollection* ensemble);
|
||||
RifDataSourceForRftPlt(SourceType sourceType, RimWellLogFile* wellLogFile = nullptr);
|
||||
|
||||
SourceType sourceType() const;
|
||||
RimEclipseCase* eclCase() const;
|
||||
RifReaderEclipseRft* rftReader() const;
|
||||
RifReaderRftInterface* rftReader() const;
|
||||
RimSummaryCaseCollection* ensemble() const;
|
||||
RimSummaryCase* summaryCase() const;
|
||||
RimWellLogFile* wellLogFile() const;
|
||||
|
||||
static QString sourceTypeUiText(SourceType sourceType);
|
||||
@@ -64,9 +72,11 @@ public:
|
||||
friend bool operator<(const RifDataSourceForRftPlt& addr1, const RifDataSourceForRftPlt& addr2);
|
||||
|
||||
private:
|
||||
SourceType m_sourceType;
|
||||
caf::PdmPointer<RimEclipseCase> m_eclCase;
|
||||
caf::PdmPointer<RimWellLogFile> m_wellLogFile;
|
||||
SourceType m_sourceType;
|
||||
caf::PdmPointer<RimEclipseCase> m_eclCase;
|
||||
caf::PdmPointer<RimSummaryCase> m_summaryCase;
|
||||
caf::PdmPointer<RimSummaryCaseCollection> m_ensemble;
|
||||
caf::PdmPointer<RimWellLogFile> m_wellLogFile;
|
||||
};
|
||||
|
||||
bool operator==(const RifDataSourceForRftPlt& addr1, const RifDataSourceForRftPlt& addr2);
|
||||
|
||||
@@ -82,3 +82,11 @@ std::string RifDerivedEnsembleReader::unitName(const RifEclipseSummaryAddress& r
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifDerivedEnsembleReader::unitSystem() const
|
||||
{
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
const std::vector<time_t>& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
bool values(const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values) const override;
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
|
||||
private:
|
||||
RimDerivedEnsembleCase* m_derivedCase;
|
||||
|
||||
@@ -36,14 +36,19 @@ public:
|
||||
enum RftWellLogChannelType
|
||||
{
|
||||
NONE,
|
||||
DEPTH,
|
||||
TVD,
|
||||
PRESSURE,
|
||||
SWAT,
|
||||
SOIL,
|
||||
SGAS,
|
||||
WRAT,
|
||||
ORAT,
|
||||
GRAT
|
||||
GRAT,
|
||||
MD,
|
||||
PRESSURE_P10,
|
||||
PRESSURE_P50,
|
||||
PRESSURE_P90,
|
||||
PRESSURE_MEAN
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
@@ -83,6 +83,14 @@ std::string RifEnsembleStatisticsReader::unitName(const RifEclipseSummaryAddress
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifEnsembleStatisticsReader::unitSystem() const
|
||||
{
|
||||
return m_ensembleStatCase->unitSystem();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -37,6 +37,9 @@ public:
|
||||
bool values(const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values) const override;
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
|
||||
private:
|
||||
bool validateAddress(const RifEclipseSummaryAddress& address) const;
|
||||
|
||||
|
||||
@@ -231,6 +231,14 @@ std::string RifKeywordVectorUserData::unitName(const RifEclipseSummaryAddress& r
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifKeywordVectorUserData::unitSystem() const
|
||||
{
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -49,7 +49,8 @@ public:
|
||||
bool values(const RifEclipseSummaryAddress& resultAddress,
|
||||
std::vector<double>* values) const override;
|
||||
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
|
||||
private:
|
||||
static bool isTimeHeader(const std::map<QString, QString>& header);
|
||||
|
||||
@@ -81,39 +81,39 @@ void RifReaderEclipseRft::open()
|
||||
timeStep.setTime_t(timeStepTime_t);
|
||||
|
||||
RifEclipseRftAddress addressPressure(wellName, timeStep, RifEclipseRftAddress::PRESSURE);
|
||||
m_eclipseRftAddresses.push_back(addressPressure);
|
||||
m_eclipseRftAddresses.insert(addressPressure);
|
||||
m_rftAddressToLibeclNodeIdx[addressPressure] = i;
|
||||
|
||||
RifEclipseRftAddress addressDepth(wellName, timeStep, RifEclipseRftAddress::DEPTH);
|
||||
m_eclipseRftAddresses.push_back(addressDepth);
|
||||
RifEclipseRftAddress addressDepth(wellName, timeStep, RifEclipseRftAddress::TVD);
|
||||
m_eclipseRftAddresses.insert(addressDepth);
|
||||
m_rftAddressToLibeclNodeIdx[addressDepth] = i;
|
||||
|
||||
if (ecl_rft_node_is_RFT(node))
|
||||
{
|
||||
RifEclipseRftAddress addressSwat(wellName, timeStep, RifEclipseRftAddress::SWAT);
|
||||
m_eclipseRftAddresses.push_back(addressSwat);
|
||||
m_eclipseRftAddresses.insert(addressSwat);
|
||||
m_rftAddressToLibeclNodeIdx[addressSwat] = i;
|
||||
|
||||
RifEclipseRftAddress addressSoil(wellName, timeStep, RifEclipseRftAddress::SOIL);
|
||||
m_eclipseRftAddresses.push_back(addressSoil);
|
||||
m_eclipseRftAddresses.insert(addressSoil);
|
||||
m_rftAddressToLibeclNodeIdx[addressSoil] = i;
|
||||
|
||||
RifEclipseRftAddress addressSgas(wellName, timeStep, RifEclipseRftAddress::SGAS);
|
||||
m_eclipseRftAddresses.push_back(addressSgas);
|
||||
m_eclipseRftAddresses.insert(addressSgas);
|
||||
m_rftAddressToLibeclNodeIdx[addressSgas] = i;
|
||||
}
|
||||
else if (ecl_rft_node_is_PLT(node))
|
||||
{
|
||||
RifEclipseRftAddress addressWrat(wellName, timeStep, RifEclipseRftAddress::WRAT);
|
||||
m_eclipseRftAddresses.push_back(addressWrat);
|
||||
m_eclipseRftAddresses.insert(addressWrat);
|
||||
m_rftAddressToLibeclNodeIdx[addressWrat] = i;
|
||||
|
||||
RifEclipseRftAddress addressOrat(wellName, timeStep, RifEclipseRftAddress::ORAT);
|
||||
m_eclipseRftAddresses.push_back(addressOrat);
|
||||
m_eclipseRftAddresses.insert(addressOrat);
|
||||
m_rftAddressToLibeclNodeIdx[addressOrat] = i;
|
||||
|
||||
RifEclipseRftAddress addressGrat(wellName, timeStep, RifEclipseRftAddress::GRAT);
|
||||
m_eclipseRftAddresses.push_back(addressGrat);
|
||||
m_eclipseRftAddresses.insert(addressGrat);
|
||||
m_rftAddressToLibeclNodeIdx[addressGrat] = i;
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ void RifReaderEclipseRft::open()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<RifEclipseRftAddress>& RifReaderEclipseRft::eclipseRftAddresses()
|
||||
std::set<RifEclipseRftAddress> RifReaderEclipseRft::eclipseRftAddresses()
|
||||
{
|
||||
if (!m_ecl_rft_file)
|
||||
{
|
||||
@@ -157,7 +157,7 @@ void RifReaderEclipseRft::values(const RifEclipseRftAddress& rftAddress, std::ve
|
||||
|
||||
switch (wellLogChannelName)
|
||||
{
|
||||
case RifEclipseRftAddress::DEPTH:
|
||||
case RifEclipseRftAddress::TVD:
|
||||
{
|
||||
for (int i = 0; i < ecl_rft_node_get_size(node); i++)
|
||||
{
|
||||
@@ -258,14 +258,14 @@ void RifReaderEclipseRft::cellIndices(const RifEclipseRftAddress& rftAddress, st
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<QDateTime> RifReaderEclipseRft::availableTimeSteps(const QString& wellName, const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName)
|
||||
std::set<QDateTime> RifReaderEclipseRft::availableTimeSteps(const QString& wellName, const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName)
|
||||
{
|
||||
if (!m_ecl_rft_file)
|
||||
{
|
||||
open();
|
||||
}
|
||||
|
||||
std::vector<QDateTime> timeSteps;
|
||||
std::set<QDateTime> timeSteps;
|
||||
|
||||
if (wellName == "") return timeSteps;
|
||||
|
||||
@@ -273,7 +273,7 @@ std::vector<QDateTime> RifReaderEclipseRft::availableTimeSteps(const QString& we
|
||||
{
|
||||
if (address.wellName() == wellName && address.wellLogChannel() == wellLogChannelName)
|
||||
{
|
||||
timeSteps.push_back(address.timeStep());
|
||||
timeSteps.insert(address.timeStep());
|
||||
}
|
||||
}
|
||||
return timeSteps;
|
||||
@@ -303,17 +303,26 @@ std::set<QDateTime> RifReaderEclipseRft::availableTimeSteps(const QString& wellN
|
||||
return timeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime> RifReaderEclipseRft::availableTimeSteps(const QString& wellName)
|
||||
{
|
||||
auto wellLogChannels = availableWellLogChannels(wellName);
|
||||
return availableTimeSteps(wellName, wellLogChannels);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RifEclipseRftAddress::RftWellLogChannelType> RifReaderEclipseRft::availableWellLogChannels(const QString& wellName)
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> RifReaderEclipseRft::availableWellLogChannels(const QString& wellName)
|
||||
{
|
||||
if (!m_ecl_rft_file)
|
||||
{
|
||||
open();
|
||||
}
|
||||
|
||||
std::vector<RifEclipseRftAddress::RftWellLogChannelType> wellLogChannelNames;
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> wellLogChannelNames;
|
||||
|
||||
if (wellName == "") return wellLogChannelNames;
|
||||
|
||||
@@ -359,19 +368,19 @@ std::vector<RifEclipseRftAddress::RftWellLogChannelType> RifReaderEclipseRft::av
|
||||
|
||||
if (pressureFound)
|
||||
{
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::PRESSURE);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::PRESSURE);
|
||||
}
|
||||
if (rftFound)
|
||||
{
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::RftWellLogChannelType::SWAT);
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::RftWellLogChannelType::SOIL);
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::RftWellLogChannelType::SGAS);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::RftWellLogChannelType::SWAT);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::RftWellLogChannelType::SOIL);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::RftWellLogChannelType::SGAS);
|
||||
}
|
||||
if (pltFound)
|
||||
{
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::RftWellLogChannelType::WRAT);
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::RftWellLogChannelType::ORAT);
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::RftWellLogChannelType::GRAT);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::RftWellLogChannelType::WRAT);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::RftWellLogChannelType::ORAT);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::RftWellLogChannelType::GRAT);
|
||||
}
|
||||
|
||||
return wellLogChannelNames;
|
||||
@@ -380,7 +389,7 @@ std::vector<RifEclipseRftAddress::RftWellLogChannelType> RifReaderEclipseRft::av
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::set<QString>& RifReaderEclipseRft::wellNames()
|
||||
std::set<QString> RifReaderEclipseRft::wellNames()
|
||||
{
|
||||
if (!m_ecl_rft_file)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RifEclipseRftAddress.h"
|
||||
#include "RifReaderRftInterface.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
@@ -38,26 +38,27 @@ namespace caf
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifReaderEclipseRft : public cvf::Object
|
||||
class RifReaderEclipseRft : public RifReaderRftInterface, public cvf::Object
|
||||
{
|
||||
public:
|
||||
RifReaderEclipseRft(const QString& fileName);
|
||||
~RifReaderEclipseRft() override;
|
||||
|
||||
const std::vector<RifEclipseRftAddress>& eclipseRftAddresses();
|
||||
void values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values);
|
||||
void cellIndices(const RifEclipseRftAddress& rftAddress, std::vector<caf::VecIjk>* indices);
|
||||
std::set<RifEclipseRftAddress> eclipseRftAddresses() override;
|
||||
void values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values) override;
|
||||
void cellIndices(const RifEclipseRftAddress& rftAddress, std::vector<caf::VecIjk>* indices);
|
||||
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName, const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels);
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName) override;
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName, const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels) override;
|
||||
|
||||
std::vector<QDateTime> availableTimeSteps(const QString& wellName, const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName);
|
||||
std::vector<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels(const QString& wellName);
|
||||
const std::set<QString>& wellNames();
|
||||
bool wellHasRftData(QString wellName);
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName, const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName) override;
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels(const QString& wellName) override;
|
||||
std::set<QString> wellNames() override;
|
||||
bool wellHasRftData(QString wellName);
|
||||
|
||||
private:
|
||||
void open();
|
||||
int indexFromAddress(const RifEclipseRftAddress& rftAddress) const;
|
||||
void open();
|
||||
int indexFromAddress(const RifEclipseRftAddress& rftAddress) const;
|
||||
|
||||
private:
|
||||
// Taken from ecl_rft_file.h and ecl_rft_node.h
|
||||
@@ -65,7 +66,7 @@ private:
|
||||
|
||||
QString m_fileName;
|
||||
ecl_rft_file_type* m_ecl_rft_file;
|
||||
std::vector<RifEclipseRftAddress> m_eclipseRftAddresses;
|
||||
std::set<RifEclipseRftAddress> m_eclipseRftAddresses;
|
||||
std::set<QString> m_wellNames;
|
||||
std::map<RifEclipseRftAddress, int> m_rftAddressToLibeclNodeIdx;
|
||||
};
|
||||
|
||||
@@ -57,6 +57,22 @@ std::vector<time_t> getTimeSteps(ecl_sum_type* ecl_sum)
|
||||
return timeSteps;
|
||||
}
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem readUnitSystem(ecl_sum_type* ecl_sum)
|
||||
{
|
||||
ert_ecl_unit_enum eclUnitEnum = ecl_sum_get_unit_system(ecl_sum);
|
||||
switch (eclUnitEnum)
|
||||
{
|
||||
case ECL_METRIC_UNITS:
|
||||
return RiaEclipseUnitTools::UNITS_METRIC;
|
||||
case ECL_FIELD_UNITS:
|
||||
return RiaEclipseUnitTools::UNITS_FIELD;
|
||||
case ECL_LAB_UNITS:
|
||||
return RiaEclipseUnitTools::UNITS_LAB;
|
||||
default:
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -105,6 +121,7 @@ void closeEclSum(ecl_sum_type* ecl_sum)
|
||||
RifReaderEclipseSummary::RifReaderEclipseSummary()
|
||||
: m_ecl_sum(nullptr)
|
||||
, m_ecl_SmSpec(nullptr)
|
||||
, m_unitSystem(RiaEclipseUnitTools::UNITS_METRIC)
|
||||
{
|
||||
m_valuesCache.reset(new ValuesCache());
|
||||
}
|
||||
@@ -135,7 +152,7 @@ bool RifReaderEclipseSummary::open(const QString& headerFileName, bool includeRe
|
||||
m_timeSteps.clear();
|
||||
m_ecl_SmSpec = ecl_sum_get_smspec(m_ecl_sum);
|
||||
m_timeSteps = getTimeSteps(m_ecl_sum);
|
||||
|
||||
m_unitSystem = readUnitSystem(m_ecl_sum);
|
||||
buildMetaData();
|
||||
|
||||
return true;
|
||||
@@ -515,6 +532,14 @@ std::string RifReaderEclipseSummary::unitName(const RifEclipseSummaryAddress& re
|
||||
return ertSumVarNode.get_unit();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifReaderEclipseSummary::unitSystem() const
|
||||
{
|
||||
return m_unitSystem;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaEclipseUnitTools.h"
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
|
||||
@@ -67,7 +68,7 @@ public:
|
||||
|
||||
bool values(const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values) const override;
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
QStringList warnings() const { return m_warnings; }
|
||||
|
||||
void markForCachePurge(const RifEclipseSummaryAddress& address) override;
|
||||
@@ -88,6 +89,8 @@ private:
|
||||
const ecl_smspec_type * m_ecl_SmSpec;
|
||||
std::vector<time_t> m_timeSteps;
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem m_unitSystem;
|
||||
|
||||
std::map<RifEclipseSummaryAddress, int> m_resultAddressToErtNodeIdx;
|
||||
|
||||
QStringList m_warnings;
|
||||
|
||||
258
ApplicationCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp
Normal file
258
ApplicationCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// 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 "RifReaderEnsembleStatisticsRft.h"
|
||||
|
||||
#include "RiaCurveMerger.h"
|
||||
#include "RigStatisticsMath.h"
|
||||
|
||||
#include "RimSummaryCase.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
|
||||
#include "cafAssert.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEnsembleStatisticsRft::RifReaderEnsembleStatisticsRft(const RimSummaryCaseCollection* summaryCaseCollection)
|
||||
: m_summaryCaseCollection(summaryCaseCollection)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RifEclipseRftAddress> RifReaderEnsembleStatisticsRft::eclipseRftAddresses()
|
||||
{
|
||||
std::set<RifEclipseRftAddress> allAddresses;
|
||||
for (auto summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
if (summaryCase->rftReader())
|
||||
{
|
||||
std::set<RifEclipseRftAddress> addresses = summaryCase->rftReader()->eclipseRftAddresses();
|
||||
allAddresses.insert(addresses.begin(), addresses.end());
|
||||
}
|
||||
}
|
||||
|
||||
std::set<RifEclipseRftAddress> statisticsAddresses;
|
||||
for (const RifEclipseRftAddress& regularAddress : allAddresses)
|
||||
{
|
||||
if (regularAddress.wellLogChannel() == RifEclipseRftAddress::TVD)
|
||||
{
|
||||
statisticsAddresses.insert(regularAddress);
|
||||
}
|
||||
else if (regularAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE)
|
||||
{
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> statChannels = {RifEclipseRftAddress::PRESSURE_P10,
|
||||
RifEclipseRftAddress::PRESSURE_P50,
|
||||
RifEclipseRftAddress::PRESSURE_P90,
|
||||
RifEclipseRftAddress::PRESSURE_MEAN};
|
||||
for (auto channel : statChannels)
|
||||
{
|
||||
statisticsAddresses.insert(RifEclipseRftAddress(regularAddress.wellName(), regularAddress.timeStep(), channel));
|
||||
}
|
||||
}
|
||||
}
|
||||
return statisticsAddresses;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderEnsembleStatisticsRft::values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values)
|
||||
{
|
||||
CAF_ASSERT(rftAddress.wellLogChannel() == RifEclipseRftAddress::TVD ||
|
||||
rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_MEAN ||
|
||||
rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_P10 ||
|
||||
rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_P50 ||
|
||||
rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_P90);
|
||||
|
||||
auto it = m_cachedValues.find(rftAddress);
|
||||
if (it == m_cachedValues.end())
|
||||
{
|
||||
calculateStatistics(rftAddress);
|
||||
}
|
||||
*values = m_cachedValues[rftAddress];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime> RifReaderEnsembleStatisticsRft::availableTimeSteps(const QString& wellName)
|
||||
{
|
||||
std::set<QDateTime> allTimeSteps;
|
||||
for (auto summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
if (summaryCase->rftReader())
|
||||
{
|
||||
std::set<QDateTime> timeSteps = summaryCase->rftReader()->availableTimeSteps(wellName);
|
||||
allTimeSteps.insert(timeSteps.begin(), timeSteps.end());
|
||||
}
|
||||
}
|
||||
return allTimeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime>
|
||||
RifReaderEnsembleStatisticsRft::availableTimeSteps(const QString& wellName,
|
||||
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName)
|
||||
{
|
||||
std::set<QDateTime> allTimeSteps;
|
||||
for (auto summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
if (summaryCase->rftReader())
|
||||
{
|
||||
std::set<QDateTime> timeSteps = summaryCase->rftReader()->availableTimeSteps(wellName, wellLogChannelName);
|
||||
allTimeSteps.insert(timeSteps.begin(), timeSteps.end());
|
||||
}
|
||||
}
|
||||
return allTimeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime> RifReaderEnsembleStatisticsRft::availableTimeSteps(
|
||||
const QString& wellName,
|
||||
const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels)
|
||||
{
|
||||
std::set<QDateTime> allTimeSteps;
|
||||
for (auto summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
if (summaryCase->rftReader())
|
||||
{
|
||||
std::set<QDateTime> timeSteps = summaryCase->rftReader()->availableTimeSteps(wellName, relevantChannels);
|
||||
allTimeSteps.insert(timeSteps.begin(), timeSteps.end());
|
||||
}
|
||||
}
|
||||
return allTimeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType>
|
||||
RifReaderEnsembleStatisticsRft::availableWellLogChannels(const QString& wellName)
|
||||
{
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> allWellLogChannels;
|
||||
for (auto summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
if (summaryCase->rftReader())
|
||||
{
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> wellLogChannels =
|
||||
summaryCase->rftReader()->availableWellLogChannels(wellName);
|
||||
allWellLogChannels.insert(wellLogChannels.begin(), wellLogChannels.end());
|
||||
}
|
||||
}
|
||||
return allWellLogChannels;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QString> RifReaderEnsembleStatisticsRft::wellNames()
|
||||
{
|
||||
std::set<QString> allWellNames;
|
||||
for (auto summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
if (summaryCase->rftReader())
|
||||
{
|
||||
std::set<QString> wellNames = summaryCase->rftReader()->wellNames();
|
||||
allWellNames.insert(wellNames.begin(), wellNames.end());
|
||||
}
|
||||
}
|
||||
return allWellNames;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderEnsembleStatisticsRft::calculateStatistics(const RifEclipseRftAddress& rftAddress)
|
||||
{
|
||||
const QString& wellName = rftAddress.wellName();
|
||||
const QDateTime& timeStep = rftAddress.timeStep();
|
||||
RifEclipseRftAddress depthAddress(wellName, timeStep, RifEclipseRftAddress::TVD);
|
||||
RifEclipseRftAddress pressAddress(wellName, timeStep, RifEclipseRftAddress::PRESSURE);
|
||||
|
||||
RifEclipseRftAddress p10Address(wellName, timeStep, RifEclipseRftAddress::PRESSURE_P10);
|
||||
RifEclipseRftAddress p50Address(wellName, timeStep, RifEclipseRftAddress::PRESSURE_P50);
|
||||
RifEclipseRftAddress p90Address(wellName, timeStep, RifEclipseRftAddress::PRESSURE_P90);
|
||||
RifEclipseRftAddress meanAddress(wellName, timeStep, RifEclipseRftAddress::PRESSURE_MEAN);
|
||||
|
||||
RiaCurveMerger<double> curveMerger;
|
||||
|
||||
for (RimSummaryCase* summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
RifReaderRftInterface* reader = summaryCase->rftReader();
|
||||
if (reader)
|
||||
{
|
||||
std::vector<double> depths;
|
||||
std::vector<double> pressures;
|
||||
reader->values(depthAddress, &depths);
|
||||
reader->values(pressAddress, &pressures);
|
||||
|
||||
curveMerger.addCurveData(depths, pressures);
|
||||
}
|
||||
}
|
||||
curveMerger.computeInterpolatedValues(false);
|
||||
|
||||
clearData(wellName, timeStep);
|
||||
|
||||
const std::vector<double>& allDepths = curveMerger.allXValues();
|
||||
if (!allDepths.empty())
|
||||
{
|
||||
m_cachedValues[depthAddress] = allDepths;
|
||||
for (size_t depthIdx = 0; depthIdx < allDepths.size(); ++depthIdx)
|
||||
{
|
||||
std::vector<double> pressuresAtDepth;
|
||||
pressuresAtDepth.reserve(curveMerger.curveCount());
|
||||
for (size_t curveIdx = 0; curveIdx < curveMerger.curveCount(); ++curveIdx)
|
||||
{
|
||||
const std::vector<double>& curvePressures = curveMerger.interpolatedYValuesForAllXValues(curveIdx);
|
||||
pressuresAtDepth.push_back(curvePressures[depthIdx]);
|
||||
}
|
||||
double p10, p50, p90, mean;
|
||||
RigStatisticsMath::calculateStatisticsCurves(pressuresAtDepth, &p10, &p50, &p90, &mean);
|
||||
|
||||
if (p10 != HUGE_VAL) m_cachedValues[p10Address].push_back(p10);
|
||||
if (p50 != HUGE_VAL) m_cachedValues[p50Address].push_back(p50);
|
||||
if (p90 != HUGE_VAL) m_cachedValues[p90Address].push_back(p90);
|
||||
m_cachedValues[meanAddress].push_back(mean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderEnsembleStatisticsRft::clearData(const QString& wellName, const QDateTime& timeStep)
|
||||
{
|
||||
for (auto it = m_cachedValues.begin(); it != m_cachedValues.end(); )
|
||||
{
|
||||
if (it->first.wellName() == wellName && it->first.timeStep() == timeStep)
|
||||
{
|
||||
it = m_cachedValues.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// 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 "RifReaderEclipseRft.h"
|
||||
|
||||
#include "cvfObject.h"
|
||||
|
||||
class RimSummaryCaseCollection;
|
||||
|
||||
class RifReaderEnsembleStatisticsRft : public RifReaderRftInterface, public cvf::Object
|
||||
{
|
||||
public:
|
||||
RifReaderEnsembleStatisticsRft(const RimSummaryCaseCollection* summaryCaseCollection);
|
||||
|
||||
std::set<RifEclipseRftAddress> eclipseRftAddresses() override;
|
||||
void values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values) override;
|
||||
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName) override;
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName,
|
||||
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName) override;
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName,
|
||||
const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels) override;
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels(const QString& wellName) override;
|
||||
std::set<QString> wellNames() override;
|
||||
|
||||
private:
|
||||
void calculateStatistics(const RifEclipseRftAddress& rftAddress);
|
||||
void clearData(const QString& wellName, const QDateTime& timeStep);
|
||||
private:
|
||||
|
||||
const RimSummaryCaseCollection* m_summaryCaseCollection;
|
||||
|
||||
std::map<RifEclipseRftAddress, std::vector<double>> m_cachedValues;
|
||||
};
|
||||
506
ApplicationCode/FileInterface/RifReaderFmuRft.cpp
Normal file
506
ApplicationCode/FileInterface/RifReaderFmuRft.cpp
Normal file
@@ -0,0 +1,506 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// 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 "RifReaderFmuRft.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "cafAssert.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QTextStream>
|
||||
|
||||
#include <limits>
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderFmuRft::Observation::Observation()
|
||||
: utmx(-std::numeric_limits<double>::infinity())
|
||||
, utmy(-std::numeric_limits<double>::infinity())
|
||||
, mdrkb(-std::numeric_limits<double>::infinity())
|
||||
, tvdmsl(-std::numeric_limits<double>::infinity())
|
||||
, pressure(-std::numeric_limits<double>::infinity())
|
||||
, pressureError(-std::numeric_limits<double>::infinity())
|
||||
, formation()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderFmuRft::Observation::valid() const
|
||||
{
|
||||
return utmx != std::numeric_limits<double>::infinity() && utmy != std::numeric_limits<double>::infinity() &&
|
||||
mdrkb != std::numeric_limits<double>::infinity() && tvdmsl != std::numeric_limits<double>::infinity() &&
|
||||
pressure != std::numeric_limits<double>::infinity() && pressureError != std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderFmuRft::WellObservationSet::WellObservationSet(const QDateTime& dateTime, int measurementIndex)
|
||||
: dateTime(dateTime)
|
||||
, measurementIndex(measurementIndex)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderFmuRft::RifReaderFmuRft(const QString& filePath)
|
||||
: m_filePath(filePath)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QStringList RifReaderFmuRft::findSubDirectoriesWithFmuRftData(const QString& filePath)
|
||||
{
|
||||
QStringList subDirsContainingFmuRftData;
|
||||
|
||||
QFileInfo fileInfo(filePath);
|
||||
if (!(fileInfo.exists() && fileInfo.isDir() && fileInfo.isReadable()))
|
||||
{
|
||||
return subDirsContainingFmuRftData;
|
||||
}
|
||||
|
||||
if (directoryContainsFmuRftData(filePath))
|
||||
{
|
||||
subDirsContainingFmuRftData.push_back(filePath);
|
||||
}
|
||||
|
||||
QDir dir(filePath);
|
||||
|
||||
QStringList subDirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Readable, QDir::Name);
|
||||
for (QString subDir : subDirs)
|
||||
{
|
||||
QString absDir = dir.absoluteFilePath(subDir);
|
||||
subDirsContainingFmuRftData.append(findSubDirectoriesWithFmuRftData(absDir));
|
||||
}
|
||||
|
||||
return subDirsContainingFmuRftData;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderFmuRft::directoryContainsFmuRftData(const QString& filePath)
|
||||
{
|
||||
QFileInfo baseFileInfo(filePath);
|
||||
if (!(baseFileInfo.exists() && baseFileInfo.isDir() && baseFileInfo.isReadable()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QDir dir(filePath);
|
||||
if (!dir.exists("well_date_rft.txt"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList obsFiles;
|
||||
obsFiles << "*.obs"
|
||||
<< "*.txt";
|
||||
QFileInfoList fileInfos = dir.entryInfoList(obsFiles, QDir::Files, QDir::Name);
|
||||
|
||||
std::map<QString, int> fileStemCounts;
|
||||
for (QFileInfo fileInfo : fileInfos)
|
||||
{
|
||||
// TODO:
|
||||
// Uses completeBaseName() to support wells with a dot in the name.
|
||||
// Not sure if this is necessary or desired
|
||||
fileStemCounts[fileInfo.completeBaseName()]++;
|
||||
if (fileStemCounts[fileInfo.completeBaseName()] == 2)
|
||||
{
|
||||
// At least one matching obs and txt file.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RifEclipseRftAddress> RifReaderFmuRft::eclipseRftAddresses()
|
||||
{
|
||||
if (m_allWellObservations.empty())
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
std::set<RifEclipseRftAddress> allAddresses;
|
||||
for (const WellObservationPair& wellObservationPair : m_allWellObservations)
|
||||
{
|
||||
const QString& wellName = wellObservationPair.first;
|
||||
const QDateTime& dateTime = wellObservationPair.second.dateTime;
|
||||
const std::vector<Observation>& observations = wellObservationPair.second.observations;
|
||||
|
||||
for (const Observation& observation : observations)
|
||||
{
|
||||
if (observation.valid())
|
||||
{
|
||||
RifEclipseRftAddress tvdAddress(wellName, dateTime, RifEclipseRftAddress::TVD);
|
||||
RifEclipseRftAddress mdAddress(wellName, dateTime, RifEclipseRftAddress::MD);
|
||||
RifEclipseRftAddress pressureAddress(wellName, dateTime, RifEclipseRftAddress::PRESSURE);
|
||||
allAddresses.insert(tvdAddress);
|
||||
allAddresses.insert(mdAddress);
|
||||
allAddresses.insert(pressureAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
return allAddresses;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderFmuRft::values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values)
|
||||
{
|
||||
CAF_ASSERT(values);
|
||||
|
||||
if (m_allWellObservations.empty())
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
auto it = m_allWellObservations.find(rftAddress.wellName());
|
||||
if (it != m_allWellObservations.end())
|
||||
{
|
||||
const std::vector<Observation>& observations = it->second.observations;
|
||||
values->clear();
|
||||
values->reserve(observations.size());
|
||||
for (const Observation& observation : observations)
|
||||
{
|
||||
switch (rftAddress.wellLogChannel())
|
||||
{
|
||||
case RifEclipseRftAddress::TVD:
|
||||
values->push_back(observation.tvdmsl);
|
||||
break;
|
||||
case RifEclipseRftAddress::MD:
|
||||
values->push_back(observation.mdrkb);
|
||||
break;
|
||||
case RifEclipseRftAddress::PRESSURE:
|
||||
values->push_back(observation.pressure);
|
||||
break;
|
||||
default:
|
||||
CAF_ASSERT(false && "Wrong channel type sent to Fmu RFT reader");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderFmuRft::load()
|
||||
{
|
||||
QString errorMsg;
|
||||
|
||||
QFileInfo fileInfo(m_filePath);
|
||||
if (!(fileInfo.exists() && fileInfo.isDir() && fileInfo.isReadable()))
|
||||
{
|
||||
errorMsg = QString("Directory '%s' does not exist or isn't readable").arg(m_filePath);
|
||||
RiaLogging::error(errorMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
QDir dir(m_filePath);
|
||||
|
||||
WellObservationMap wellObservations = loadWellDates(dir, &errorMsg);
|
||||
if (wellObservations.empty())
|
||||
{
|
||||
if (errorMsg.isEmpty())
|
||||
{
|
||||
errorMsg = QString("'%1' contains no valid FMU RFT data").arg(m_filePath);
|
||||
}
|
||||
RiaLogging::error(errorMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = wellObservations.begin(); it != wellObservations.end(); ++it)
|
||||
{
|
||||
const QString& wellName = it->first;
|
||||
WellObservationSet& wellObservationSet = it->second;
|
||||
QString txtFile = QString("%1.txt").arg(wellName);
|
||||
QString obsFile = QString("%1.obs").arg(wellName);
|
||||
QFileInfo txtFileInfo(dir.absoluteFilePath(txtFile));
|
||||
QFileInfo obsFileInfo(dir.absoluteFilePath(obsFile));
|
||||
|
||||
if (!readTxtFile(txtFile, &errorMsg, &wellObservationSet))
|
||||
{
|
||||
RiaLogging::error(errorMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!readObsFile(obsFile, &errorMsg, &wellObservationSet))
|
||||
{
|
||||
RiaLogging::error(errorMsg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_allWellObservations.swap(wellObservations);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime> RifReaderFmuRft::availableTimeSteps(const QString& wellName,
|
||||
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName)
|
||||
{
|
||||
if (wellLogChannelName == RifEclipseRftAddress::TVD || wellLogChannelName == RifEclipseRftAddress::MD ||
|
||||
wellLogChannelName == RifEclipseRftAddress::PRESSURE)
|
||||
{
|
||||
return availableTimeSteps(wellName);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime> RifReaderFmuRft::availableTimeSteps(const QString& wellName)
|
||||
{
|
||||
if (m_allWellObservations.empty())
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
auto it = m_allWellObservations.find(wellName);
|
||||
if (it != m_allWellObservations.end())
|
||||
{
|
||||
return {it->second.dateTime};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime>
|
||||
RifReaderFmuRft::availableTimeSteps(const QString& wellName,
|
||||
const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels)
|
||||
{
|
||||
if (relevantChannels.count(RifEclipseRftAddress::TVD) || relevantChannels.count(RifEclipseRftAddress::MD) ||
|
||||
relevantChannels.count(RifEclipseRftAddress::PRESSURE))
|
||||
{
|
||||
return availableTimeSteps(wellName);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> RifReaderFmuRft::availableWellLogChannels(const QString& wellName)
|
||||
{
|
||||
if (m_allWellObservations.empty())
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
if (!m_allWellObservations.empty())
|
||||
{
|
||||
return {RifEclipseRftAddress::TVD, RifEclipseRftAddress::MD, RifEclipseRftAddress::PRESSURE};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QString> RifReaderFmuRft::wellNames()
|
||||
{
|
||||
if (m_allWellObservations.empty())
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
std::set<QString> wellNames;
|
||||
for (auto it = m_allWellObservations.begin(); it != m_allWellObservations.end(); ++it)
|
||||
{
|
||||
wellNames.insert(it->first);
|
||||
}
|
||||
return wellNames;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderFmuRft::WellObservationMap RifReaderFmuRft::loadWellDates(QDir& dir, QString* errorMsg)
|
||||
{
|
||||
CAF_ASSERT(errorMsg);
|
||||
|
||||
WellObservationMap validObservations;
|
||||
|
||||
QFileInfo wellDateFileInfo(dir.absoluteFilePath("well_date_rft.txt"));
|
||||
if (!(wellDateFileInfo.exists() && wellDateFileInfo.isFile() && wellDateFileInfo.isReadable()))
|
||||
{
|
||||
*errorMsg = QString("well_date_rft.txt cannot be found at '%s'").arg(m_filePath);
|
||||
return WellObservationMap();
|
||||
}
|
||||
|
||||
{
|
||||
QFile wellDateFile(wellDateFileInfo.absoluteFilePath());
|
||||
if (!wellDateFile.open(QIODevice::Text | QIODevice::ReadOnly))
|
||||
{
|
||||
*errorMsg = QString("Could not read '%1'").arg(wellDateFileInfo.absoluteFilePath());
|
||||
return WellObservationMap();
|
||||
}
|
||||
QTextStream fileStream(&wellDateFile);
|
||||
while (true)
|
||||
{
|
||||
QString line = fileStream.readLine();
|
||||
if (line.isNull())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
QTextStream lineStream(&line);
|
||||
|
||||
QString wellName;
|
||||
int day, month, year, measurementIndex;
|
||||
|
||||
lineStream >> wellName >> day >> month >> year >> measurementIndex;
|
||||
if (lineStream.status() != QTextStream::Ok)
|
||||
{
|
||||
*errorMsg = QString("Failed to parse '%1'").arg(wellDateFileInfo.absoluteFilePath());
|
||||
return WellObservationMap();
|
||||
}
|
||||
|
||||
QDateTime dateTime(QDate(year, month, day));
|
||||
WellObservationSet observationSet(dateTime, measurementIndex);
|
||||
validObservations.insert(std::make_pair(wellName, observationSet));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return validObservations;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderFmuRft::readTxtFile(const QString& fileName, QString* errorMsg, WellObservationSet* wellObservationSet)
|
||||
{
|
||||
CAF_ASSERT(wellObservationSet);
|
||||
|
||||
QFile file(fileName);
|
||||
if (!(file.open(QIODevice::Text | QIODevice::ReadOnly)))
|
||||
{
|
||||
*errorMsg = QString("Could not open '%1'").arg(fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
QTextStream stream(&file);
|
||||
while (true)
|
||||
{
|
||||
QString line = stream.readLine();
|
||||
if (line.isNull())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
QTextStream lineStream(&line);
|
||||
|
||||
double utmx, utmy, mdrkb, tvdmsl;
|
||||
QString formationName;
|
||||
|
||||
lineStream >> utmx >> utmy >> mdrkb >> tvdmsl >> formationName;
|
||||
|
||||
if (lineStream.status() != QTextStream::Ok)
|
||||
{
|
||||
*errorMsg = QString("Failed to parse '%1'").arg(fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Observation observation;
|
||||
observation.utmx = utmx;
|
||||
observation.utmy = utmy;
|
||||
observation.mdrkb = mdrkb;
|
||||
observation.tvdmsl = tvdmsl;
|
||||
observation.formation = formationName;
|
||||
wellObservationSet->observations.push_back(observation);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderFmuRft::readObsFile(const QString& fileName, QString* errorMsg, WellObservationSet* wellObservationSet)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!(file.open(QIODevice::Text | QIODevice::ReadOnly)))
|
||||
{
|
||||
*errorMsg = QString("Could not open '%1'").arg(fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t lineNumber = 0u;
|
||||
|
||||
QTextStream stream(&file);
|
||||
while (true)
|
||||
{
|
||||
if (lineNumber >= wellObservationSet->observations.size())
|
||||
{
|
||||
*errorMsg = QString("'%1' has more lines than corresponding txt file").arg(fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
QString line = stream.readLine();
|
||||
if (line.isNull())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
QTextStream lineStream(&line);
|
||||
|
||||
double pressure, pressureError;
|
||||
|
||||
lineStream >> pressure >> pressureError;
|
||||
|
||||
if (lineStream.status() != QTextStream::Ok)
|
||||
{
|
||||
*errorMsg = QString("Failed to parse line %1 of '%2'").arg(lineNumber + 1).arg(fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Observation& observation = wellObservationSet->observations[lineNumber];
|
||||
observation.pressure = pressure;
|
||||
observation.pressureError = pressureError;
|
||||
}
|
||||
lineNumber++;
|
||||
}
|
||||
|
||||
if (lineNumber != wellObservationSet->observations.size())
|
||||
{
|
||||
*errorMsg = QString("'%1' has less lines than corresponding txt file").arg(fileName);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
98
ApplicationCode/FileInterface/RifReaderFmuRft.h
Normal file
98
ApplicationCode/FileInterface/RifReaderFmuRft.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// 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 "RifEclipseRftAddress.h"
|
||||
#include "RifReaderRftInterface.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifReaderFmuRft : public RifReaderRftInterface, public cvf::Object
|
||||
{
|
||||
public:
|
||||
struct Observation
|
||||
{
|
||||
double utmx;
|
||||
double utmy;
|
||||
double mdrkb;
|
||||
double tvdmsl;
|
||||
|
||||
double pressure;
|
||||
double pressureError;
|
||||
QString formation;
|
||||
|
||||
Observation();
|
||||
|
||||
bool valid() const;
|
||||
};
|
||||
|
||||
struct WellObservationSet
|
||||
{
|
||||
QDateTime dateTime;
|
||||
int measurementIndex;
|
||||
std::vector<Observation> observations;
|
||||
|
||||
WellObservationSet(const QDateTime& dateTime, int measurementIndex);
|
||||
};
|
||||
|
||||
public:
|
||||
RifReaderFmuRft(const QString& filePath);
|
||||
~RifReaderFmuRft() = default;
|
||||
|
||||
static QStringList findSubDirectoriesWithFmuRftData(const QString& filePath);
|
||||
static bool directoryContainsFmuRftData(const QString& filePath);
|
||||
|
||||
std::set<RifEclipseRftAddress> eclipseRftAddresses() override;
|
||||
void values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values) override;
|
||||
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName,
|
||||
const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels) override;
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName) override;
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName,
|
||||
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName) override;
|
||||
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels(const QString& wellName) override;
|
||||
std::set<QString> wellNames() override;
|
||||
|
||||
public:
|
||||
void load();
|
||||
|
||||
private:
|
||||
typedef std::pair<QString, WellObservationSet> WellObservationPair;
|
||||
typedef std::map<QString, WellObservationSet> WellObservationMap;
|
||||
|
||||
WellObservationMap loadWellDates(QDir& dir, QString* errorMsg);
|
||||
static bool readTxtFile(const QString& txtFileName, QString* errorMsg, WellObservationSet* wellObservationSet);
|
||||
static bool readObsFile(const QString& obsFileName, QString* errorMsg, WellObservationSet* wellObservationSet);
|
||||
|
||||
private:
|
||||
QString m_filePath;
|
||||
WellObservationMap m_allWellObservations;
|
||||
};
|
||||
@@ -183,3 +183,11 @@ std::string RifReaderObservedData::unitName(const RifEclipseSummaryAddress& resu
|
||||
std::string str = "";
|
||||
return str;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifReaderObservedData::unitSystem() const
|
||||
{
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,9 @@ public:
|
||||
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
|
||||
private:
|
||||
RifEclipseSummaryAddress address(const QString& quantity,
|
||||
const QString& identifierName,
|
||||
|
||||
37
ApplicationCode/FileInterface/RifReaderRftInterface.cpp
Normal file
37
ApplicationCode/FileInterface/RifReaderRftInterface.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// 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 "RifReaderRftInterface.h"
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RifEclipseRftAddress> RifReaderRftInterface::eclipseRftAddresses(const QString& wellName, const QDateTime& timeStep)
|
||||
{
|
||||
std::set<RifEclipseRftAddress> matchingAddresses;
|
||||
std::set<RifEclipseRftAddress> allAddresses = this->eclipseRftAddresses();
|
||||
for (const RifEclipseRftAddress& address : allAddresses)
|
||||
{
|
||||
if (address.wellName() == wellName && address.timeStep() == timeStep)
|
||||
{
|
||||
matchingAddresses.insert(address);
|
||||
}
|
||||
}
|
||||
return matchingAddresses;
|
||||
}
|
||||
44
ApplicationCode/FileInterface/RifReaderRftInterface.h
Normal file
44
ApplicationCode/FileInterface/RifReaderRftInterface.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// 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 "RifEclipseRftAddress.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QString>
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
class RifReaderRftInterface
|
||||
{
|
||||
public:
|
||||
std::set<RifEclipseRftAddress> eclipseRftAddresses(const QString& wellName, const QDateTime& timeStep);
|
||||
virtual std::set<RifEclipseRftAddress> eclipseRftAddresses() = 0;
|
||||
virtual void values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values) = 0;
|
||||
|
||||
virtual std::set<QDateTime>
|
||||
availableTimeSteps(const QString& wellName,
|
||||
const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels) = 0;
|
||||
virtual std::set<QDateTime> availableTimeSteps(const QString& wellName) = 0;
|
||||
virtual std::set<QDateTime> availableTimeSteps(const QString& wellName,
|
||||
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName) = 0;
|
||||
virtual std::set<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels(const QString& wellName) = 0;
|
||||
virtual std::set<QString> wellNames() = 0;
|
||||
};
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaEclipseUnitTools.h"
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
|
||||
#include "cvfObject.h"
|
||||
@@ -50,7 +51,7 @@ public:
|
||||
std::vector<double>* values) const = 0;
|
||||
|
||||
virtual std::string unitName(const RifEclipseSummaryAddress& resultAddress) const = 0;
|
||||
|
||||
virtual RiaEclipseUnitTools::UnitSystem unitSystem() const = 0;
|
||||
|
||||
virtual void markForCachePurge(const RifEclipseSummaryAddress& address) {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user