mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Grid import using opm-common improvements (#11438)
* Update opm-common EGRID reader to support LGRs, NNCs, dual porosity, unit system info and time step filters * Rearrange well reading code into separate class * Update resdata library to not require an ecl_grid when reading well information. Only lgr names are needed, allows reused by opm_common reader
This commit is contained in:
parent
ccda815bde
commit
4365b0dfb9
@ -201,12 +201,12 @@ QDateTime RiaQDateTimeTools::subtractPeriod( const QDateTime& dt, RiaDefines::Da
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
QDateTime RiaQDateTimeTools::createDateTime( const QDate& date )
|
QDateTime RiaQDateTimeTools::createDateTime( const QDate& date, Qt::TimeSpec timeSpec /*= Qt::LocalTime*/ )
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK( 5, 14, 0 )
|
#if QT_VERSION >= QT_VERSION_CHECK( 5, 14, 0 )
|
||||||
return date.startOfDay();
|
return date.startOfDay( timeSpec );
|
||||||
#else
|
#else
|
||||||
return QDateTime( date, QTime( 0, 0 ) );
|
return QDateTime( date, QTime( 0, 0 ), timeSpec );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public:
|
|||||||
static QDateTime addPeriod( const QDateTime& dt, RiaDefines::DateTimePeriod period );
|
static QDateTime addPeriod( const QDateTime& dt, RiaDefines::DateTimePeriod period );
|
||||||
static QDateTime subtractPeriod( const QDateTime& dt, RiaDefines::DateTimePeriod period );
|
static QDateTime subtractPeriod( const QDateTime& dt, RiaDefines::DateTimePeriod period );
|
||||||
|
|
||||||
static QDateTime createDateTime( const QDate& date );
|
static QDateTime createDateTime( const QDate& date, Qt::TimeSpec timeSpec = Qt::LocalTime );
|
||||||
|
|
||||||
static QDateTime epoch();
|
static QDateTime epoch();
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RifPerforationIntervalReader.h
|
${CMAKE_CURRENT_LIST_DIR}/RifPerforationIntervalReader.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseInput.h
|
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseInput.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseOutput.h
|
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseOutput.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseWell.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifSummaryReaderInterface.h
|
${CMAKE_CURRENT_LIST_DIR}/RifSummaryReaderInterface.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseUserDataParserTools.h
|
${CMAKE_CURRENT_LIST_DIR}/RifEclipseUserDataParserTools.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifColumnBasedUserDataParser.h
|
${CMAKE_CURRENT_LIST_DIR}/RifColumnBasedUserDataParser.h
|
||||||
@ -79,12 +80,13 @@ set(SOURCE_GROUP_HEADER_FILES
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RifSeismicReader.h
|
${CMAKE_CURRENT_LIST_DIR}/RifSeismicReader.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifSeismicZGYReader.h
|
${CMAKE_CURRENT_LIST_DIR}/RifSeismicZGYReader.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifOpenVDSReader.h
|
${CMAKE_CURRENT_LIST_DIR}/RifOpenVDSReader.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifOpmGridTools.h
|
${CMAKE_CURRENT_LIST_DIR}/RifOpmRadialGridTools.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifCsvSummaryReader.h
|
${CMAKE_CURRENT_LIST_DIR}/RifCsvSummaryReader.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifRevealSummaryCsvReader.h
|
${CMAKE_CURRENT_LIST_DIR}/RifRevealSummaryCsvReader.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSectionSummaryReader.h
|
${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSectionSummaryReader.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifStimPlanCsvSummaryReader.h
|
${CMAKE_CURRENT_LIST_DIR}/RifStimPlanCsvSummaryReader.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommon.h
|
${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommon.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RifEclipseReportKeywords.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifInpExportTools.h
|
${CMAKE_CURRENT_LIST_DIR}/RifInpExportTools.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifFaultReactivationModelExporter.h
|
${CMAKE_CURRENT_LIST_DIR}/RifFaultReactivationModelExporter.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifThermalToStimPlanFractureXmlOutput.h
|
${CMAKE_CURRENT_LIST_DIR}/RifThermalToStimPlanFractureXmlOutput.h
|
||||||
@ -107,13 +109,13 @@ set(SOURCE_GROUP_SOURCE_FILES
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseInputFileTools.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifEclipseInputFileTools.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifRoffFileTools.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifRoffFileTools.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseOutputFileTools.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifEclipseOutputFileTools.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseRestartDataAccess.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseRestartFilesetAccess.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifEclipseRestartFilesetAccess.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseUnifiedRestartFileAccess.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifEclipseUnifiedRestartFileAccess.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseSummaryTools.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifEclipseSummaryTools.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifPerforationIntervalReader.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifPerforationIntervalReader.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseInput.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseInput.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseOutput.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseOutput.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseWell.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifSummaryReaderInterface.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifSummaryReaderInterface.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseUserDataParserTools.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifEclipseUserDataParserTools.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifColumnBasedUserDataParser.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifColumnBasedUserDataParser.cpp
|
||||||
@ -180,9 +182,10 @@ set(SOURCE_GROUP_SOURCE_FILES
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RifSeismicReader.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifSeismicReader.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifSeismicZGYReader.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifSeismicZGYReader.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifOpenVDSReader.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifOpenVDSReader.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifOpmGridTools.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifOpmRadialGridTools.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifCsvSummaryReader.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifCsvSummaryReader.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSummaryReader.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSummaryReader.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RifEclipseReportKeywords.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSectionSummaryReader.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSectionSummaryReader.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifStimPlanCsvSummaryReader.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifStimPlanCsvSummaryReader.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommon.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommon.cpp
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "RiaQDateTimeTools.h"
|
#include "RiaQDateTimeTools.h"
|
||||||
#include "RiaStringEncodingTools.h"
|
#include "RiaStringEncodingTools.h"
|
||||||
|
|
||||||
|
#include "RifEclipseReportKeywords.h"
|
||||||
#include "RifEclipseRestartFilesetAccess.h"
|
#include "RifEclipseRestartFilesetAccess.h"
|
||||||
#include "RifEclipseUnifiedRestartFileAccess.h"
|
#include "RifEclipseUnifiedRestartFileAccess.h"
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ RifEclipseOutputFileTools::~RifEclipseOutputFileTools()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::vector<RifKeywordValueCount> RifEclipseOutputFileTools::keywordValueCounts( const std::vector<ecl_file_type*>& ecl_files )
|
std::vector<RifEclipseKeywordValueCount> RifEclipseOutputFileTools::keywordValueCounts( const std::vector<ecl_file_type*>& ecl_files )
|
||||||
{
|
{
|
||||||
auto reportstepMetaData = RifEclipseOutputFileTools::createReportStepsMetaData( ecl_files );
|
auto reportstepMetaData = RifEclipseOutputFileTools::createReportStepsMetaData( ecl_files );
|
||||||
return reportstepMetaData.keywordValueCounts();
|
return reportstepMetaData.keywordValueCounts();
|
||||||
@ -76,10 +77,11 @@ std::vector<RifKeywordValueCount> RifEclipseOutputFileTools::keywordValueCounts(
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RifEclipseOutputFileTools::createResultEntries( const std::vector<RifKeywordValueCount>& fileKeywordInfo,
|
void RifEclipseOutputFileTools::createResultEntries( const std::vector<RifEclipseKeywordValueCount>& fileKeywordInfo,
|
||||||
const std::vector<RigEclipseTimeStepInfo>& timeStepInfo,
|
const std::vector<RigEclipseTimeStepInfo>& timeStepInfo,
|
||||||
RiaDefines::ResultCatType resultCategory,
|
RiaDefines::ResultCatType resultCategory,
|
||||||
RigEclipseCaseData* eclipseCaseData )
|
RigEclipseCaseData* eclipseCaseData,
|
||||||
|
size_t totalTimeSteps )
|
||||||
{
|
{
|
||||||
if ( !eclipseCaseData ) return;
|
if ( !eclipseCaseData ) return;
|
||||||
|
|
||||||
@ -91,12 +93,17 @@ void RifEclipseOutputFileTools::createResultEntries( const std::vector<RifKeywor
|
|||||||
eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ),
|
eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ),
|
||||||
eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ),
|
eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ),
|
||||||
RiaDefines::PorosityModelType::MATRIX_MODEL,
|
RiaDefines::PorosityModelType::MATRIX_MODEL,
|
||||||
timeStepInfo.size() );
|
totalTimeSteps );
|
||||||
|
|
||||||
|
if ( resultCategory == RiaDefines::ResultCatType::STATIC_NATIVE )
|
||||||
|
{
|
||||||
|
validKeywords.push_back( RifEclipseKeywordValueCount( "ACTNUM", 0, RifEclipseKeywordValueCount::KeywordDataType::INTEGER ) );
|
||||||
|
}
|
||||||
|
|
||||||
for ( const auto& keywordData : validKeywords )
|
for ( const auto& keywordData : validKeywords )
|
||||||
{
|
{
|
||||||
RigEclipseResultAddress resAddr( resultCategory,
|
RigEclipseResultAddress resAddr( resultCategory,
|
||||||
RifKeywordValueCount::mapType( keywordData.dataType() ),
|
RifEclipseKeywordValueCount::mapType( keywordData.dataType() ),
|
||||||
QString::fromStdString( keywordData.keyword() ) );
|
QString::fromStdString( keywordData.keyword() ) );
|
||||||
matrixModelResults->createResultEntry( resAddr, false );
|
matrixModelResults->createResultEntry( resAddr, false );
|
||||||
matrixModelResults->setTimeStepInfos( resAddr, timeStepInfo );
|
matrixModelResults->setTimeStepInfos( resAddr, timeStepInfo );
|
||||||
@ -108,12 +115,17 @@ void RifEclipseOutputFileTools::createResultEntries( const std::vector<RifKeywor
|
|||||||
eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ),
|
eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ),
|
||||||
eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ),
|
eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ),
|
||||||
RiaDefines::PorosityModelType::FRACTURE_MODEL,
|
RiaDefines::PorosityModelType::FRACTURE_MODEL,
|
||||||
timeStepInfo.size() );
|
totalTimeSteps );
|
||||||
|
|
||||||
|
if ( resultCategory == RiaDefines::ResultCatType::STATIC_NATIVE )
|
||||||
|
{
|
||||||
|
validKeywords.push_back( RifEclipseKeywordValueCount( "ACTNUM", 0, RifEclipseKeywordValueCount::KeywordDataType::INTEGER ) );
|
||||||
|
}
|
||||||
|
|
||||||
for ( const auto& keywordData : validKeywords )
|
for ( const auto& keywordData : validKeywords )
|
||||||
{
|
{
|
||||||
RigEclipseResultAddress resAddr( resultCategory,
|
RigEclipseResultAddress resAddr( resultCategory,
|
||||||
RifKeywordValueCount::mapType( keywordData.dataType() ),
|
RifEclipseKeywordValueCount::mapType( keywordData.dataType() ),
|
||||||
QString::fromStdString( keywordData.keyword() ) );
|
QString::fromStdString( keywordData.keyword() ) );
|
||||||
fractureModelResults->createResultEntry( resAddr, false );
|
fractureModelResults->createResultEntry( resAddr, false );
|
||||||
fractureModelResults->setTimeStepInfos( resAddr, timeStepInfo );
|
fractureModelResults->setTimeStepInfos( resAddr, timeStepInfo );
|
||||||
@ -124,7 +136,7 @@ void RifEclipseOutputFileTools::createResultEntries( const std::vector<RifKeywor
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void getDayMonthYear( const ecl_kw_type* intehead_kw, int* day, int* month, int* year )
|
void RifEclipseOutputFileTools::getDayMonthYear( const ecl_kw_type* intehead_kw, int* day, int* month, int* year )
|
||||||
{
|
{
|
||||||
assert( day && month && year );
|
assert( day && month && year );
|
||||||
|
|
||||||
@ -714,9 +726,9 @@ bool RifEclipseOutputFileTools::assignActiveCellData( std::vector<std::vector<in
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
RifRestartReportKeywords RifEclipseOutputFileTools::createReportStepsMetaData( const std::vector<ecl_file_type*>& ecl_files )
|
RifEclipseReportKeywords RifEclipseOutputFileTools::createReportStepsMetaData( const std::vector<ecl_file_type*>& ecl_files )
|
||||||
{
|
{
|
||||||
RifRestartReportKeywords reportSteps;
|
RifEclipseReportKeywords reportSteps;
|
||||||
|
|
||||||
for ( auto ecl_file : ecl_files )
|
for ( auto ecl_file : ecl_files )
|
||||||
{
|
{
|
||||||
@ -753,18 +765,18 @@ RifRestartReportKeywords RifEclipseOutputFileTools::createReportStepsMetaData( c
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
RifKeywordValueCount::KeywordDataType dataType = RifKeywordValueCount::KeywordDataType::UNKNOWN;
|
auto dataType = RifEclipseKeywordValueCount::KeywordDataType::UNKNOWN;
|
||||||
if ( dataTypeEnumOnFile == ECL_DOUBLE_TYPE )
|
if ( dataTypeEnumOnFile == ECL_DOUBLE_TYPE )
|
||||||
{
|
{
|
||||||
dataType = RifKeywordValueCount::KeywordDataType::DOUBLE;
|
dataType = RifEclipseKeywordValueCount::KeywordDataType::DOUBLE;
|
||||||
}
|
}
|
||||||
else if ( dataTypeEnumOnFile == ECL_FLOAT_TYPE )
|
else if ( dataTypeEnumOnFile == ECL_FLOAT_TYPE )
|
||||||
{
|
{
|
||||||
dataType = RifKeywordValueCount::KeywordDataType::FLOAT;
|
dataType = RifEclipseKeywordValueCount::KeywordDataType::FLOAT;
|
||||||
}
|
}
|
||||||
else if ( dataTypeEnumOnFile == ECL_INT_TYPE )
|
else if ( dataTypeEnumOnFile == ECL_INT_TYPE )
|
||||||
{
|
{
|
||||||
dataType = RifKeywordValueCount::KeywordDataType::INTEGER;
|
dataType = RifEclipseKeywordValueCount::KeywordDataType::INTEGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
int itemCount = ecl_file_iget_named_size( ecl_file, kw, iOcc );
|
int itemCount = ecl_file_iget_named_size( ecl_file, kw, iOcc );
|
||||||
@ -786,12 +798,12 @@ RifRestartReportKeywords RifEclipseOutputFileTools::createReportStepsMetaData( c
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::vector<RifKeywordValueCount>
|
std::vector<RifEclipseKeywordValueCount>
|
||||||
RifEclipseOutputFileTools::validKeywordsForPorosityModel( const std::vector<RifKeywordValueCount>& keywordItemCounts,
|
RifEclipseOutputFileTools::validKeywordsForPorosityModel( const std::vector<RifEclipseKeywordValueCount>& keywordItemCounts,
|
||||||
const RigActiveCellInfo* matrixActiveCellInfo,
|
const RigActiveCellInfo* matrixActiveCellInfo,
|
||||||
const RigActiveCellInfo* fractureActiveCellInfo,
|
const RigActiveCellInfo* fractureActiveCellInfo,
|
||||||
RiaDefines::PorosityModelType porosityModel,
|
RiaDefines::PorosityModelType porosityModel,
|
||||||
size_t timeStepCount )
|
size_t timeStepCount )
|
||||||
{
|
{
|
||||||
if ( !matrixActiveCellInfo ) return {};
|
if ( !matrixActiveCellInfo ) return {};
|
||||||
|
|
||||||
@ -800,7 +812,7 @@ std::vector<RifKeywordValueCount>
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<RifKeywordValueCount> keywordsWithCorrectNumberOfDataItems;
|
std::vector<RifEclipseKeywordValueCount> keywordsWithCorrectNumberOfDataItems;
|
||||||
|
|
||||||
for ( const auto& keywordValueCount : keywordItemCounts )
|
for ( const auto& keywordValueCount : keywordItemCounts )
|
||||||
{
|
{
|
||||||
@ -809,39 +821,39 @@ std::vector<RifKeywordValueCount>
|
|||||||
|
|
||||||
bool validKeyword = false;
|
bool validKeyword = false;
|
||||||
|
|
||||||
size_t timeStepsAllCellsRest = valueCount % matrixActiveCellInfo->reservoirCellCount();
|
auto matrixActiveCellCount = matrixActiveCellInfo->reservoirActiveCellCount();
|
||||||
if ( timeStepsAllCellsRest == 0 && valueCount <= timeStepCount * matrixActiveCellInfo->reservoirCellCount() )
|
auto fractureActiveCellCount = fractureActiveCellInfo->reservoirActiveCellCount();
|
||||||
|
|
||||||
|
size_t timeStepsAllCellsRest = valueCount % matrixActiveCellCount;
|
||||||
|
if ( timeStepsAllCellsRest == 0 && valueCount <= timeStepCount * matrixActiveCellCount )
|
||||||
{
|
{
|
||||||
// Found result for all cells for N time steps, usually a static dataset for one time step
|
// Found result for all cells for N time steps, usually a static dataset for one time step
|
||||||
validKeyword = true;
|
validKeyword = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t timeStepsMatrixRest = valueCount % matrixActiveCellInfo->reservoirActiveCellCount();
|
size_t timeStepsMatrixRest = valueCount % matrixActiveCellCount;
|
||||||
|
|
||||||
size_t timeStepsFractureRest = 0;
|
size_t timeStepsFractureRest = 0;
|
||||||
if ( fractureActiveCellInfo->reservoirActiveCellCount() > 0 )
|
if ( fractureActiveCellCount > 0 )
|
||||||
{
|
{
|
||||||
timeStepsFractureRest = valueCount % fractureActiveCellInfo->reservoirActiveCellCount();
|
timeStepsFractureRest = valueCount % fractureActiveCellCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t sumFractureMatrixActiveCellCount = matrixActiveCellInfo->reservoirActiveCellCount() +
|
size_t sumFractureMatrixActiveCellCount = matrixActiveCellCount + fractureActiveCellCount;
|
||||||
fractureActiveCellInfo->reservoirActiveCellCount();
|
size_t timeStepsMatrixAndFractureRest = valueCount % sumFractureMatrixActiveCellCount;
|
||||||
size_t timeStepsMatrixAndFractureRest = valueCount % sumFractureMatrixActiveCellCount;
|
|
||||||
|
|
||||||
if ( porosityModel == RiaDefines::PorosityModelType::MATRIX_MODEL && timeStepsMatrixRest == 0 )
|
if ( porosityModel == RiaDefines::PorosityModelType::MATRIX_MODEL && timeStepsMatrixRest == 0 )
|
||||||
{
|
{
|
||||||
if ( valueCount <=
|
if ( valueCount <= timeStepCount * std::max( matrixActiveCellCount, sumFractureMatrixActiveCellCount ) )
|
||||||
timeStepCount * std::max( matrixActiveCellInfo->reservoirActiveCellCount(), sumFractureMatrixActiveCellCount ) )
|
|
||||||
{
|
{
|
||||||
validKeyword = true;
|
validKeyword = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( porosityModel == RiaDefines::PorosityModelType::FRACTURE_MODEL &&
|
else if ( porosityModel == RiaDefines::PorosityModelType::FRACTURE_MODEL && fractureActiveCellCount > 0 &&
|
||||||
fractureActiveCellInfo->reservoirActiveCellCount() > 0 && timeStepsFractureRest == 0 )
|
timeStepsFractureRest == 0 )
|
||||||
{
|
{
|
||||||
if ( valueCount <=
|
if ( valueCount <= timeStepCount * std::max( fractureActiveCellCount, sumFractureMatrixActiveCellCount ) )
|
||||||
timeStepCount * std::max( fractureActiveCellInfo->reservoirActiveCellCount(), sumFractureMatrixActiveCellCount ) )
|
|
||||||
{
|
{
|
||||||
validKeyword = true;
|
validKeyword = true;
|
||||||
}
|
}
|
||||||
@ -855,13 +867,23 @@ std::vector<RifKeywordValueCount>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// is this a result with a value for all cells?
|
||||||
|
if ( !validKeyword )
|
||||||
|
{
|
||||||
|
if ( valueCount > 0 && ( porosityModel == RiaDefines::PorosityModelType::MATRIX_MODEL ) &&
|
||||||
|
( valueCount % matrixActiveCellInfo->reservoirCellCount() == 0 ) )
|
||||||
|
{
|
||||||
|
validKeyword = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check for INIT values that has only values for main grid active cells
|
// Check for INIT values that has only values for main grid active cells
|
||||||
if ( !validKeyword )
|
if ( !validKeyword )
|
||||||
{
|
{
|
||||||
if ( timeStepCount == 1 )
|
if ( timeStepCount == 1 )
|
||||||
{
|
{
|
||||||
size_t mainGridMatrixActiveCellCount = matrixActiveCellInfo->gridActiveCellCounts( 0 );
|
size_t mainGridMatrixActiveCellCount = matrixActiveCellInfo->reservoirActiveCellCount();
|
||||||
size_t mainGridFractureActiveCellCount = fractureActiveCellInfo->gridActiveCellCounts( 0 );
|
size_t mainGridFractureActiveCellCount = fractureActiveCellInfo->reservoirActiveCellCount();
|
||||||
|
|
||||||
if ( valueCount == mainGridMatrixActiveCellCount || valueCount == mainGridFractureActiveCellCount ||
|
if ( valueCount == mainGridMatrixActiveCellCount || valueCount == mainGridFractureActiveCellCount ||
|
||||||
valueCount == mainGridMatrixActiveCellCount + mainGridFractureActiveCellCount )
|
valueCount == mainGridMatrixActiveCellCount + mainGridFractureActiveCellCount )
|
||||||
@ -879,3 +901,57 @@ std::vector<RifKeywordValueCount>
|
|||||||
|
|
||||||
return keywordsWithCorrectNumberOfDataItems;
|
return keywordsWithCorrectNumberOfDataItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RifEclipseOutputFileTools::extractResultValuesBasedOnPorosityModel( RigEclipseCaseData* eclipseCaseData,
|
||||||
|
RiaDefines::PorosityModelType matrixOrFracture,
|
||||||
|
std::vector<double>* destinationResultValues,
|
||||||
|
const std::vector<double>& sourceResultValues )
|
||||||
|
{
|
||||||
|
if ( sourceResultValues.empty() ) return;
|
||||||
|
|
||||||
|
RigActiveCellInfo* fracActCellInfo = eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL );
|
||||||
|
|
||||||
|
if ( matrixOrFracture == RiaDefines::PorosityModelType::MATRIX_MODEL && fracActCellInfo->reservoirActiveCellCount() == 0 )
|
||||||
|
{
|
||||||
|
destinationResultValues->insert( destinationResultValues->end(), sourceResultValues.begin(), sourceResultValues.end() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RigActiveCellInfo* actCellInfo = eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||||
|
|
||||||
|
size_t sourceStartPosition = 0;
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < eclipseCaseData->mainGrid()->gridCount(); i++ )
|
||||||
|
{
|
||||||
|
if ( eclipseCaseData->mainGrid()->gridByIndex( i )->isTempGrid() ) continue;
|
||||||
|
|
||||||
|
size_t matrixActiveCellCount = actCellInfo->gridActiveCellCounts( i );
|
||||||
|
size_t fractureActiveCellCount = fracActCellInfo->gridActiveCellCounts( i );
|
||||||
|
|
||||||
|
if ( matrixOrFracture == RiaDefines::PorosityModelType::MATRIX_MODEL )
|
||||||
|
{
|
||||||
|
destinationResultValues->insert( destinationResultValues->end(),
|
||||||
|
sourceResultValues.begin() + sourceStartPosition,
|
||||||
|
sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( ( matrixActiveCellCount + fractureActiveCellCount ) > sourceResultValues.size() )
|
||||||
|
{
|
||||||
|
// Special handling of the situation where we only have data for one fracture mode
|
||||||
|
matrixActiveCellCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
destinationResultValues->insert( destinationResultValues->end(),
|
||||||
|
sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount,
|
||||||
|
sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount +
|
||||||
|
fractureActiveCellCount );
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceStartPosition += ( matrixActiveCellCount + fractureActiveCellCount );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -20,8 +20,13 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "RifEclipseRestartDataAccess.h"
|
#include "RifEclipseReportKeywords.h"
|
||||||
|
|
||||||
|
#include "RiaDefines.h"
|
||||||
|
#include "RiaPorosityModel.h"
|
||||||
|
|
||||||
|
#include "ert/ecl/ecl_file_view.h"
|
||||||
|
#include "ert/ecl/ecl_grid.h"
|
||||||
#include "ert/ecl/ecl_util.h"
|
#include "ert/ecl/ecl_util.h"
|
||||||
|
|
||||||
#include "cvfObject.h"
|
#include "cvfObject.h"
|
||||||
@ -37,6 +42,8 @@ using ecl_file_type = struct ecl_file_struct;
|
|||||||
class RifEclipseRestartDataAccess;
|
class RifEclipseRestartDataAccess;
|
||||||
class RigEclipseTimeStepInfo;
|
class RigEclipseTimeStepInfo;
|
||||||
class RigActiveCellInfo;
|
class RigActiveCellInfo;
|
||||||
|
class RigEclipseCaseData;
|
||||||
|
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
@ -50,12 +57,13 @@ public:
|
|||||||
RifEclipseOutputFileTools();
|
RifEclipseOutputFileTools();
|
||||||
virtual ~RifEclipseOutputFileTools();
|
virtual ~RifEclipseOutputFileTools();
|
||||||
|
|
||||||
static std::vector<RifKeywordValueCount> keywordValueCounts( const std::vector<ecl_file_type*>& ecl_files );
|
static std::vector<RifEclipseKeywordValueCount> keywordValueCounts( const std::vector<ecl_file_type*>& ecl_files );
|
||||||
|
|
||||||
static void createResultEntries( const std::vector<RifKeywordValueCount>& fileKeywordInfo,
|
static void createResultEntries( const std::vector<RifEclipseKeywordValueCount>& fileKeywordInfo,
|
||||||
const std::vector<RigEclipseTimeStepInfo>& timeStepInfo,
|
const std::vector<RigEclipseTimeStepInfo>& timeStepInfo,
|
||||||
RiaDefines::ResultCatType resultCategory,
|
RiaDefines::ResultCatType resultCategory,
|
||||||
RigEclipseCaseData* eclipseCaseData );
|
RigEclipseCaseData* eclipseCaseData,
|
||||||
|
size_t totalTimeSteps );
|
||||||
|
|
||||||
static bool keywordData( const ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector<double>* values );
|
static bool keywordData( const ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector<double>* values );
|
||||||
static bool keywordData( const ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector<int>* values );
|
static bool keywordData( const ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector<int>* values );
|
||||||
@ -94,11 +102,19 @@ public:
|
|||||||
|
|
||||||
static bool assignActiveCellData( std::vector<std::vector<int>>& actnumValuesPerGrid, RigEclipseCaseData* eclipseCaseData );
|
static bool assignActiveCellData( std::vector<std::vector<int>>& actnumValuesPerGrid, RigEclipseCaseData* eclipseCaseData );
|
||||||
|
|
||||||
|
static std::vector<RifEclipseKeywordValueCount>
|
||||||
|
validKeywordsForPorosityModel( const std::vector<RifEclipseKeywordValueCount>& keywordItemCounts,
|
||||||
|
const RigActiveCellInfo* activeCellInfo,
|
||||||
|
const RigActiveCellInfo* fractureActiveCellInfo,
|
||||||
|
RiaDefines::PorosityModelType matrixOrFracture,
|
||||||
|
size_t timeStepCount );
|
||||||
|
|
||||||
|
static void extractResultValuesBasedOnPorosityModel( RigEclipseCaseData* eclipseCaseData,
|
||||||
|
RiaDefines::PorosityModelType matrixOrFracture,
|
||||||
|
std::vector<double>* values,
|
||||||
|
const std::vector<double>& fileValues );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static RifRestartReportKeywords createReportStepsMetaData( const std::vector<ecl_file_type*>& ecl_files );
|
static void getDayMonthYear( const ecl_kw_type* intehead_kw, int* day, int* month, int* year );
|
||||||
static std::vector<RifKeywordValueCount> validKeywordsForPorosityModel( const std::vector<RifKeywordValueCount>& keywordItemCounts,
|
static RifEclipseReportKeywords createReportStepsMetaData( const std::vector<ecl_file_type*>& ecl_files );
|
||||||
const RigActiveCellInfo* activeCellInfo,
|
|
||||||
const RigActiveCellInfo* fractureActiveCellInfo,
|
|
||||||
RiaDefines::PorosityModelType matrixOrFracture,
|
|
||||||
size_t timeStepCount );
|
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
// Copyright (C) 2024 Equinor ASA
|
||||||
//
|
//
|
||||||
// ResInsight is free software: you can redistribute it and/or modify
|
// ResInsight is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
@ -16,32 +16,20 @@
|
|||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "RifEclipseRestartDataAccess.h"
|
#include "RifEclipseReportKeywords.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
/// Constructor
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
RifEclipseRestartDataAccess::RifEclipseRestartDataAccess()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
/// Destructor
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
RifEclipseRestartDataAccess::~RifEclipseRestartDataAccess()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RifRestartReportKeywords::appendKeywordCount( const std::string& keyword, size_t valueCount, RifKeywordValueCount::KeywordDataType dataType )
|
void RifEclipseReportKeywords::appendKeywordCount( const std::string& keyword,
|
||||||
|
size_t valueCount,
|
||||||
|
RifEclipseKeywordValueCount::KeywordDataType dataType )
|
||||||
{
|
{
|
||||||
auto it = m_keywordValueCounts.find( keyword );
|
auto it = m_keywordValueCounts.find( keyword );
|
||||||
|
|
||||||
if ( it == m_keywordValueCounts.end() )
|
if ( it == m_keywordValueCounts.end() )
|
||||||
{
|
{
|
||||||
m_keywordValueCounts[keyword] = RifKeywordValueCount( keyword, valueCount, dataType );
|
m_keywordValueCounts[keyword] = RifEclipseKeywordValueCount( keyword, valueCount, dataType );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -52,7 +40,7 @@ void RifRestartReportKeywords::appendKeywordCount( const std::string& keyword, s
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RifRestartReportKeywords::appendKeywordCount( const RifRestartReportKeywords& other )
|
void RifEclipseReportKeywords::appendKeywordCount( const RifEclipseReportKeywords& other )
|
||||||
{
|
{
|
||||||
for ( const auto& [keyword, keywordInfo] : other.m_keywordValueCounts )
|
for ( const auto& [keyword, keywordInfo] : other.m_keywordValueCounts )
|
||||||
{
|
{
|
||||||
@ -63,9 +51,9 @@ void RifRestartReportKeywords::appendKeywordCount( const RifRestartReportKeyword
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::vector<RifKeywordValueCount> RifRestartReportKeywords::keywordValueCounts() const
|
std::vector<RifEclipseKeywordValueCount> RifEclipseReportKeywords::keywordValueCounts() const
|
||||||
{
|
{
|
||||||
std::vector<RifKeywordValueCount> tmp;
|
std::vector<RifEclipseKeywordValueCount> tmp;
|
||||||
for ( const auto& [keyword, info] : m_keywordValueCounts )
|
for ( const auto& [keyword, info] : m_keywordValueCounts )
|
||||||
{
|
{
|
||||||
tmp.push_back( info );
|
tmp.push_back( info );
|
91
ApplicationLibCode/FileInterface/RifEclipseReportKeywords.h
Normal file
91
ApplicationLibCode/FileInterface/RifEclipseReportKeywords.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2024 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 "RiaDefines.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class RifEclipseKeywordValueCount
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class KeywordDataType
|
||||||
|
{
|
||||||
|
UNKNOWN,
|
||||||
|
FLOAT,
|
||||||
|
DOUBLE,
|
||||||
|
INTEGER,
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
RifEclipseKeywordValueCount( const std::string& keyword, size_t itemCount, KeywordDataType dataType )
|
||||||
|
: m_keyword( keyword )
|
||||||
|
, m_valueCount( itemCount )
|
||||||
|
, m_dataType( dataType )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RifEclipseKeywordValueCount()
|
||||||
|
: m_valueCount( 0 )
|
||||||
|
, m_dataType( KeywordDataType::UNKNOWN )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void addValueCount( size_t valueCount ) { m_valueCount += valueCount; }
|
||||||
|
|
||||||
|
std::string keyword() const { return m_keyword; }
|
||||||
|
size_t valueCount() const { return m_valueCount; }
|
||||||
|
KeywordDataType dataType() const { return m_dataType; }
|
||||||
|
|
||||||
|
static RiaDefines::ResultDataType mapType( RifEclipseKeywordValueCount::KeywordDataType dataType )
|
||||||
|
{
|
||||||
|
switch ( dataType )
|
||||||
|
{
|
||||||
|
case RifEclipseKeywordValueCount::KeywordDataType::FLOAT:
|
||||||
|
return RiaDefines::ResultDataType::FLOAT;
|
||||||
|
case RifEclipseKeywordValueCount::KeywordDataType::DOUBLE:
|
||||||
|
return RiaDefines::ResultDataType::DOUBLE;
|
||||||
|
case RifEclipseKeywordValueCount::KeywordDataType::INTEGER:
|
||||||
|
return RiaDefines::ResultDataType::INTEGER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RiaDefines::ResultDataType::UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_keyword;
|
||||||
|
size_t m_valueCount;
|
||||||
|
KeywordDataType m_dataType;
|
||||||
|
};
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
//
|
||||||
|
//==================================================================================================
|
||||||
|
class RifEclipseReportKeywords
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void appendKeywordCount( const RifEclipseReportKeywords& other );
|
||||||
|
void appendKeywordCount( const std::string& keyword, size_t valueCount, RifEclipseKeywordValueCount::KeywordDataType dataType );
|
||||||
|
|
||||||
|
std::vector<RifEclipseKeywordValueCount> keywordValueCounts() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<std::string, RifEclipseKeywordValueCount> m_keywordValueCounts;
|
||||||
|
};
|
@ -29,78 +29,9 @@
|
|||||||
|
|
||||||
#include "ert/ecl_well/well_info.hpp"
|
#include "ert/ecl_well/well_info.hpp"
|
||||||
|
|
||||||
|
#include "RifEclipseReportKeywords.h"
|
||||||
#include "RifReaderInterface.h"
|
#include "RifReaderInterface.h"
|
||||||
|
|
||||||
//==================================================================================================
|
|
||||||
//
|
|
||||||
//==================================================================================================
|
|
||||||
class RifKeywordValueCount
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum class KeywordDataType
|
|
||||||
{
|
|
||||||
UNKNOWN,
|
|
||||||
FLOAT,
|
|
||||||
DOUBLE,
|
|
||||||
INTEGER,
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
RifKeywordValueCount( const std::string& keyword, size_t itemCount, KeywordDataType dataType )
|
|
||||||
: m_keyword( keyword )
|
|
||||||
, m_valueCount( itemCount )
|
|
||||||
, m_dataType( dataType )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
RifKeywordValueCount()
|
|
||||||
: m_valueCount( 0 )
|
|
||||||
, m_dataType( KeywordDataType::UNKNOWN )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void addValueCount( size_t valueCount ) { m_valueCount += valueCount; }
|
|
||||||
|
|
||||||
std::string keyword() const { return m_keyword; }
|
|
||||||
size_t valueCount() const { return m_valueCount; }
|
|
||||||
KeywordDataType dataType() const { return m_dataType; }
|
|
||||||
|
|
||||||
static RiaDefines::ResultDataType mapType( RifKeywordValueCount::KeywordDataType dataType )
|
|
||||||
{
|
|
||||||
switch ( dataType )
|
|
||||||
{
|
|
||||||
case RifKeywordValueCount::KeywordDataType::FLOAT:
|
|
||||||
return RiaDefines::ResultDataType::FLOAT;
|
|
||||||
case RifKeywordValueCount::KeywordDataType::DOUBLE:
|
|
||||||
return RiaDefines::ResultDataType::DOUBLE;
|
|
||||||
case RifKeywordValueCount::KeywordDataType::INTEGER:
|
|
||||||
return RiaDefines::ResultDataType::INTEGER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RiaDefines::ResultDataType::UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_keyword;
|
|
||||||
size_t m_valueCount;
|
|
||||||
KeywordDataType m_dataType;
|
|
||||||
};
|
|
||||||
|
|
||||||
//==================================================================================================
|
|
||||||
//
|
|
||||||
//==================================================================================================
|
|
||||||
class RifRestartReportKeywords
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void appendKeywordCount( const RifRestartReportKeywords& other );
|
|
||||||
void appendKeywordCount( const std::string& keyword, size_t valueCount, RifKeywordValueCount::KeywordDataType dataType );
|
|
||||||
|
|
||||||
std::vector<RifKeywordValueCount> keywordValueCounts() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::map<std::string, RifKeywordValueCount> m_keywordValueCounts;
|
|
||||||
};
|
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
//
|
//
|
||||||
// Abstract class for results access
|
// Abstract class for results access
|
||||||
@ -109,8 +40,8 @@ private:
|
|||||||
class RifEclipseRestartDataAccess : public cvf::Object
|
class RifEclipseRestartDataAccess : public cvf::Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RifEclipseRestartDataAccess();
|
RifEclipseRestartDataAccess(){};
|
||||||
~RifEclipseRestartDataAccess() override;
|
~RifEclipseRestartDataAccess() override{};
|
||||||
|
|
||||||
virtual bool open() = 0;
|
virtual bool open() = 0;
|
||||||
virtual void setRestartFiles( const QStringList& fileSet ) = 0;
|
virtual void setRestartFiles( const QStringList& fileSet ) = 0;
|
||||||
@ -121,7 +52,7 @@ public:
|
|||||||
virtual void timeSteps( std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart ) = 0;
|
virtual void timeSteps( std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart ) = 0;
|
||||||
virtual std::vector<int> reportNumbers() = 0;
|
virtual std::vector<int> reportNumbers() = 0;
|
||||||
|
|
||||||
virtual std::vector<RifKeywordValueCount> keywordValueCounts() = 0;
|
virtual std::vector<RifEclipseKeywordValueCount> keywordValueCounts() = 0;
|
||||||
virtual bool results( const QString& resultName, size_t timeStep, size_t gridCount, std::vector<double>* values ) = 0;
|
virtual bool results( const QString& resultName, size_t timeStep, size_t gridCount, std::vector<double>* values ) = 0;
|
||||||
|
|
||||||
virtual bool dynamicNNCResults( const ecl_grid_type* grid,
|
virtual bool dynamicNNCResults( const ecl_grid_type* grid,
|
||||||
|
@ -158,7 +158,7 @@ void RifEclipseRestartFilesetAccess::timeSteps( std::vector<QDateTime>* timeStep
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
/// Get list of result names
|
/// Get list of result names
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::vector<RifKeywordValueCount> RifEclipseRestartFilesetAccess::keywordValueCounts()
|
std::vector<RifEclipseKeywordValueCount> RifEclipseRestartFilesetAccess::keywordValueCounts()
|
||||||
{
|
{
|
||||||
CVF_ASSERT( timeStepCount() > 0 );
|
CVF_ASSERT( timeStepCount() > 0 );
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
void timeSteps( std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart ) override;
|
void timeSteps( std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart ) override;
|
||||||
std::vector<int> reportNumbers() override;
|
std::vector<int> reportNumbers() override;
|
||||||
|
|
||||||
std::vector<RifKeywordValueCount> keywordValueCounts() override;
|
std::vector<RifEclipseKeywordValueCount> keywordValueCounts() override;
|
||||||
bool results( const QString& resultName, size_t timeStep, size_t gridCount, std::vector<double>* values ) override;
|
bool results( const QString& resultName, size_t timeStep, size_t gridCount, std::vector<double>* values ) override;
|
||||||
|
|
||||||
bool dynamicNNCResults( const ecl_grid_type* grid,
|
bool dynamicNNCResults( const ecl_grid_type* grid,
|
||||||
|
@ -214,7 +214,7 @@ void RifEclipseUnifiedRestartFileAccess::timeSteps( std::vector<QDateTime>* time
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
/// Get list of result names
|
/// Get list of result names
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::vector<RifKeywordValueCount> RifEclipseUnifiedRestartFileAccess::keywordValueCounts()
|
std::vector<RifEclipseKeywordValueCount> RifEclipseUnifiedRestartFileAccess::keywordValueCounts()
|
||||||
{
|
{
|
||||||
if ( openFile() )
|
if ( openFile() )
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,7 @@ public:
|
|||||||
void timeSteps( std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart ) override;
|
void timeSteps( std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart ) override;
|
||||||
std::vector<int> reportNumbers() override;
|
std::vector<int> reportNumbers() override;
|
||||||
|
|
||||||
std::vector<RifKeywordValueCount> keywordValueCounts() override;
|
std::vector<RifEclipseKeywordValueCount> keywordValueCounts() override;
|
||||||
bool results( const QString& resultName, size_t timeStep, size_t gridCount, std::vector<double>* values ) override;
|
bool results( const QString& resultName, size_t timeStep, size_t gridCount, std::vector<double>* values ) override;
|
||||||
|
|
||||||
bool dynamicNNCResults( const ecl_grid_type* grid,
|
bool dynamicNNCResults( const ecl_grid_type* grid,
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "RifOpmGridTools.h"
|
#include "RifOpmRadialGridTools.h"
|
||||||
|
|
||||||
#include "RiaLogging.h"
|
#include "RiaLogging.h"
|
||||||
#include "RiaWeightedMeanCalculator.h"
|
#include "RiaWeightedMeanCalculator.h"
|
||||||
@ -37,7 +37,7 @@
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RifOpmGridTools::importCoordinatesForRadialGrid( const std::string& gridFilePath, RigMainGrid* riMainGrid )
|
void RifOpmRadialGridTools::importCoordinatesForRadialGrid( const std::string& gridFilePath, RigMainGrid* riMainGrid )
|
||||||
{
|
{
|
||||||
CAF_ASSERT( riMainGrid );
|
CAF_ASSERT( riMainGrid );
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ void RifOpmGridTools::importCoordinatesForRadialGrid( const std::string& gridFil
|
|||||||
|
|
||||||
if ( opmMainGrid.is_radial() )
|
if ( opmMainGrid.is_radial() )
|
||||||
{
|
{
|
||||||
transferCoordinates( opmMainGrid, opmMainGrid, riMainGrid, riMainGrid );
|
transferCoordinatesRadial( opmMainGrid, opmMainGrid, riMainGrid, riMainGrid );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lgrNames = opmMainGrid.list_of_lgrs();
|
auto lgrNames = opmMainGrid.list_of_lgrs();
|
||||||
@ -88,7 +88,7 @@ void RifOpmGridTools::importCoordinatesForRadialGrid( const std::string& gridFil
|
|||||||
auto riLgrGrid = riMainGrid->gridByIndex( i );
|
auto riLgrGrid = riMainGrid->gridByIndex( i );
|
||||||
if ( riLgrGrid->gridName() == lgrName )
|
if ( riLgrGrid->gridName() == lgrName )
|
||||||
{
|
{
|
||||||
transferCoordinates( opmMainGrid, opmLgrGrid, riMainGrid, riLgrGrid );
|
transferCoordinatesRadial( opmMainGrid, opmLgrGrid, riMainGrid, riLgrGrid );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,87 +101,6 @@ void RifOpmGridTools::importCoordinatesForRadialGrid( const std::string& gridFil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
size_t RifOpmGridTools::cellCount( const std::string& gridFilePath )
|
|
||||||
{
|
|
||||||
Opm::EclIO::EGrid opmGrid( gridFilePath );
|
|
||||||
|
|
||||||
return opmGrid.totalNumberOfCells();
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
bool RifOpmGridTools::importGrid( const std::string& gridFilePath, RigMainGrid* mainGrid, RigEclipseCaseData* caseData )
|
|
||||||
{
|
|
||||||
Opm::EclIO::EGrid opmGrid( gridFilePath );
|
|
||||||
|
|
||||||
auto dims = opmGrid.dimension();
|
|
||||||
mainGrid->setGridPointDimensions( cvf::Vec3st( dims[0] + 1, dims[1] + 1, dims[2] + 1 ) );
|
|
||||||
|
|
||||||
RigCell defaultCell;
|
|
||||||
defaultCell.setHostGrid( mainGrid );
|
|
||||||
auto cellCount = opmGrid.totalNumberOfCells();
|
|
||||||
mainGrid->globalCellArray().resize( cellCount, defaultCell );
|
|
||||||
mainGrid->nodes().resize( 8 * cellCount );
|
|
||||||
|
|
||||||
transferCoordinatesCartesian( opmGrid, opmGrid, mainGrid, mainGrid, caseData );
|
|
||||||
|
|
||||||
auto opmMapAxes = opmGrid.get_mapaxes();
|
|
||||||
if ( opmMapAxes.size() == 6 )
|
|
||||||
{
|
|
||||||
std::array<double, 6> mapAxes;
|
|
||||||
for ( size_t i = 0; i < opmMapAxes.size(); ++i )
|
|
||||||
{
|
|
||||||
mapAxes[i] = opmMapAxes[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the map axes transformation matrix on the main grid
|
|
||||||
mainGrid->setMapAxes( mapAxes );
|
|
||||||
mainGrid->setUseMapAxes( true );
|
|
||||||
|
|
||||||
auto transform = mainGrid->mapAxisTransform();
|
|
||||||
|
|
||||||
// Invert the transformation matrix to convert from file coordinates to domain coordinates
|
|
||||||
transform.invert();
|
|
||||||
|
|
||||||
#pragma omp parallel for
|
|
||||||
for ( long i = 0; i < static_cast<long>( mainGrid->nodes().size() ); i++ )
|
|
||||||
{
|
|
||||||
auto& n = mainGrid->nodes()[i];
|
|
||||||
n.transformPoint( transform );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
std::vector<std::vector<int>> RifOpmGridTools::activeCellsFromActnumKeyword( Opm::EclIO::EGrid& grid )
|
|
||||||
{
|
|
||||||
auto arrayNames = grid.arrayNames();
|
|
||||||
int actnumArrayIndex = -1;
|
|
||||||
|
|
||||||
for ( size_t i = 0; i < arrayNames.size(); i++ )
|
|
||||||
{
|
|
||||||
if ( arrayNames[i] == "ACTNUM" )
|
|
||||||
{
|
|
||||||
actnumArrayIndex = static_cast<int>( i );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( actnumArrayIndex < 0 ) return {};
|
|
||||||
|
|
||||||
auto actnumMainGrid = grid.get<int>( actnumArrayIndex );
|
|
||||||
|
|
||||||
return { actnumMainGrid };
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// A radial grid is defined by a center point and a set of cylindrical coordinates. The coordinates at the
|
// A radial grid is defined by a center point and a set of cylindrical coordinates. The coordinates at the
|
||||||
@ -213,7 +132,10 @@ std::vector<std::vector<int>> RifOpmGridTools::activeCellsFromActnumKeyword( Opm
|
|||||||
// 3. Find the closest point on this pillar, and use this point as the adjusted coordinate for the node
|
// 3. Find the closest point on this pillar, and use this point as the adjusted coordinate for the node
|
||||||
//
|
//
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RifOpmGridTools::transferCoordinates( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, RigMainGrid* riMainGrid, RigGridBase* riGrid )
|
void RifOpmRadialGridTools::transferCoordinatesRadial( Opm::EclIO::EGrid& opmMainGrid,
|
||||||
|
Opm::EclIO::EGrid& opmGrid,
|
||||||
|
RigMainGrid* riMainGrid,
|
||||||
|
RigGridBase* riGrid )
|
||||||
{
|
{
|
||||||
size_t cellCount = opmGrid.totalNumberOfCells();
|
size_t cellCount = opmGrid.totalNumberOfCells();
|
||||||
if ( cellCount != riGrid->cellCount() ) return;
|
if ( cellCount != riGrid->cellCount() ) return;
|
||||||
@ -266,153 +188,102 @@ void RifOpmGridTools::transferCoordinates( Opm::EclIO::EGrid& opmMainGrid, Opm::
|
|||||||
// First grid dimension is radius, check if cell has are at the outer-most slice
|
// First grid dimension is radius, check if cell has are at the outer-most slice
|
||||||
if ( !hostCellGlobalIndices.empty() && ( gridDimension[0] - 1 == ijkCell[0] ) )
|
if ( !hostCellGlobalIndices.empty() && ( gridDimension[0] - 1 == ijkCell[0] ) )
|
||||||
{
|
{
|
||||||
std::array<double, 8> cellRadius{};
|
auto hostCellIndex = hostCellGlobalIndices[opmCellIndex];
|
||||||
std::array<double, 8> cellTheta{};
|
|
||||||
std::array<double, 8> cellZ{};
|
|
||||||
opmGrid.getRadialCellCorners( ijkCell, cellRadius, cellTheta, cellZ );
|
|
||||||
|
|
||||||
double maxRadius = *std::max_element( cellRadius.begin(), cellRadius.end() );
|
lockToHostPillars( riNode, opmMainGrid, opmGrid, ijkCell, hostCellIndex, opmCellIndex, opmNodeIndex, xCenterCoordOpm, yCenterCoordOpm );
|
||||||
|
|
||||||
// Check if the radius is at the outer surface of the radial grid
|
|
||||||
// Adjust the outer nodes to match the corner pillars of the host cell
|
|
||||||
const double epsilon = 0.15;
|
|
||||||
if ( fabs( maxRadius - cellRadius[opmNodeIndex] ) < epsilon * cellRadius[opmNodeIndex] )
|
|
||||||
{
|
|
||||||
const auto hostCellIndex = hostCellGlobalIndices[opmCellIndex];
|
|
||||||
|
|
||||||
double closestPillarDistance = std::numeric_limits<double>::max();
|
|
||||||
int closestPillarIndex = -1;
|
|
||||||
|
|
||||||
const auto cylinderCoordX = opmX[opmNodeIndex] + xCenterCoordOpm;
|
|
||||||
const auto cylinderCoordY = opmY[opmNodeIndex] + yCenterCoordOpm;
|
|
||||||
const auto cylinderCoordZ = opmZ[opmNodeIndex];
|
|
||||||
|
|
||||||
const cvf::Vec3d coordinateOnCylinder = cvf::Vec3d( cylinderCoordX, cylinderCoordY, cylinderCoordZ );
|
|
||||||
|
|
||||||
const auto candidates = computeSnapToCoordinates( opmMainGrid, opmGrid, hostCellIndex, opmCellIndex );
|
|
||||||
for ( int pillarIndex = 0; pillarIndex < static_cast<int>( candidates.size() ); pillarIndex++ )
|
|
||||||
{
|
|
||||||
for ( const auto& c : candidates[pillarIndex] )
|
|
||||||
{
|
|
||||||
double distance = coordinateOnCylinder.pointDistance( c );
|
|
||||||
if ( distance < closestPillarDistance )
|
|
||||||
{
|
|
||||||
closestPillarDistance = distance;
|
|
||||||
closestPillarIndex = pillarIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( closestPillarDistance < std::numeric_limits<double>::max() )
|
|
||||||
{
|
|
||||||
const auto& pillarCordinates = candidates[closestPillarIndex];
|
|
||||||
|
|
||||||
int layerCount = static_cast<int>( pillarCordinates.size() / 2 );
|
|
||||||
int layerIndexInMainGridCell = ijkCell[2] % layerCount;
|
|
||||||
int localNodeIndex = opmNodeIndex % 8;
|
|
||||||
|
|
||||||
cvf::Vec3d closestPillarCoord;
|
|
||||||
if ( localNodeIndex < 4 )
|
|
||||||
{
|
|
||||||
// Top of cell
|
|
||||||
int pillarCoordIndex = layerIndexInMainGridCell * 2;
|
|
||||||
closestPillarCoord = pillarCordinates[pillarCoordIndex];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Bottom of cell
|
|
||||||
int pillarCoordIndex = layerIndexInMainGridCell * 2 + 1;
|
|
||||||
closestPillarCoord = pillarCordinates[pillarCoordIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
riNode.x() = closestPillarCoord.x();
|
|
||||||
riNode.y() = closestPillarCoord.y();
|
|
||||||
riNode.z() = -closestPillarCoord.z();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
//
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RifOpmGridTools::transferCoordinatesCartesian( Opm::EclIO::EGrid& opmMainGrid,
|
void RifOpmRadialGridTools::lockToHostPillars( cvf::Vec3d& riNode,
|
||||||
Opm::EclIO::EGrid& opmGrid,
|
Opm::EclIO::EGrid& opmMainGrid,
|
||||||
RigMainGrid* riMainGrid,
|
Opm::EclIO::EGrid& opmGrid,
|
||||||
RigGridBase* riGrid,
|
std::array<int, 3>& ijkCell,
|
||||||
RigEclipseCaseData* caseData )
|
int hostCellIndex,
|
||||||
|
int opmCellIndex,
|
||||||
|
size_t opmNodeIndex,
|
||||||
|
double xCenterCoordOpm,
|
||||||
|
double yCenterCoordOpm )
|
||||||
{
|
{
|
||||||
// Prefix OPM structures with _opm_and ResInsight structures with _ri_
|
std::array<double, 8> cellRadius{};
|
||||||
|
std::array<double, 8> cellTheta{};
|
||||||
|
std::array<double, 8> cellZ{};
|
||||||
|
opmGrid.getRadialCellCorners( ijkCell, cellRadius, cellTheta, cellZ );
|
||||||
|
|
||||||
auto& riNodes = riMainGrid->nodes();
|
double maxRadius = *std::max_element( cellRadius.begin(), cellRadius.end() );
|
||||||
|
|
||||||
opmGrid.loadData();
|
// Check if the radius is at the outer surface of the radial grid
|
||||||
opmGrid.load_grid_data();
|
// Adjust the outer nodes to match the corner pillars of the host cell
|
||||||
|
const double epsilon = 0.15;
|
||||||
auto riActiveCells = caseData->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
if ( fabs( maxRadius - cellRadius[opmNodeIndex] ) < epsilon * cellRadius[opmNodeIndex] )
|
||||||
auto riActiveCellsFrac = caseData->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL );
|
|
||||||
riActiveCellsFrac->setGridCount( 1 );
|
|
||||||
riActiveCellsFrac->setGridActiveCellCounts( 0, 0 );
|
|
||||||
|
|
||||||
riActiveCells->setReservoirCellCount( riMainGrid->cellCount() );
|
|
||||||
|
|
||||||
// same mapping as resdata
|
|
||||||
const size_t cellMappingECLRi[8] = { 0, 1, 3, 2, 4, 5, 7, 6 };
|
|
||||||
|
|
||||||
#pragma omp parallel for
|
|
||||||
for ( int opmCellIndex = 0; opmCellIndex < static_cast<int>( riMainGrid->cellCount() ); opmCellIndex++ )
|
|
||||||
{
|
{
|
||||||
auto opmIJK = opmGrid.ijk_from_global_index( opmCellIndex );
|
|
||||||
|
|
||||||
auto riReservoirIndex = riGrid->cellIndexFromIJK( opmIJK[0], opmIJK[1], opmIJK[2] );
|
|
||||||
RigCell& cell = riMainGrid->globalCellArray()[riReservoirIndex];
|
|
||||||
cell.setGridLocalCellIndex( riReservoirIndex );
|
|
||||||
|
|
||||||
std::array<double, 8> opmX{};
|
std::array<double, 8> opmX{};
|
||||||
std::array<double, 8> opmY{};
|
std::array<double, 8> opmY{};
|
||||||
std::array<double, 8> opmZ{};
|
std::array<double, 8> opmZ{};
|
||||||
|
|
||||||
opmGrid.getCellCorners( opmCellIndex, opmX, opmY, opmZ );
|
opmGrid.getCellCorners( opmCellIndex, opmX, opmY, opmZ );
|
||||||
|
|
||||||
// Each cell has 8 nodes, use reservoir cell index and multiply to find first node index for cell
|
double closestPillarDistance = std::numeric_limits<double>::max();
|
||||||
auto riNodeStartIndex = riReservoirIndex * 8;
|
int closestPillarIndex = -1;
|
||||||
|
|
||||||
for ( size_t opmNodeIndex = 0; opmNodeIndex < 8; opmNodeIndex++ )
|
const auto cylinderCoordX = opmX[opmNodeIndex] + xCenterCoordOpm;
|
||||||
|
const auto cylinderCoordY = opmY[opmNodeIndex] + yCenterCoordOpm;
|
||||||
|
const auto cylinderCoordZ = opmZ[opmNodeIndex];
|
||||||
|
|
||||||
|
const cvf::Vec3d coordinateOnCylinder = cvf::Vec3d( cylinderCoordX, cylinderCoordY, cylinderCoordZ );
|
||||||
|
|
||||||
|
const auto candidates = computeSnapToCoordinates( opmMainGrid, opmGrid, hostCellIndex, opmCellIndex );
|
||||||
|
for ( int pillarIndex = 0; pillarIndex < static_cast<int>( candidates.size() ); pillarIndex++ )
|
||||||
{
|
{
|
||||||
auto riCornerIndex = cellMappingECLRi[opmNodeIndex];
|
for ( const auto& c : candidates[pillarIndex] )
|
||||||
size_t riNodeIndex = riNodeStartIndex + riCornerIndex;
|
|
||||||
|
|
||||||
auto& riNode = riNodes[riNodeIndex];
|
|
||||||
riNode.x() = opmX[opmNodeIndex];
|
|
||||||
riNode.y() = opmY[opmNodeIndex];
|
|
||||||
riNode.z() = -opmZ[opmNodeIndex];
|
|
||||||
|
|
||||||
cell.cornerIndices()[riCornerIndex] = riNodeIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( riActiveCells )
|
|
||||||
{
|
|
||||||
auto activeIndex = opmGrid.active_index( opmIJK[0], opmIJK[1], opmIJK[2] );
|
|
||||||
if ( activeIndex > -1 )
|
|
||||||
{
|
{
|
||||||
riActiveCells->setCellResultIndex( riReservoirIndex, activeIndex );
|
double distance = coordinateOnCylinder.pointDistance( c );
|
||||||
|
if ( distance < closestPillarDistance )
|
||||||
|
{
|
||||||
|
closestPillarDistance = distance;
|
||||||
|
closestPillarIndex = pillarIndex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( closestPillarDistance < std::numeric_limits<double>::max() )
|
||||||
|
{
|
||||||
|
const auto& pillarCordinates = candidates[closestPillarIndex];
|
||||||
|
|
||||||
|
int layerCount = static_cast<int>( pillarCordinates.size() / 2 );
|
||||||
|
int layerIndexInMainGridCell = ijkCell[2] % layerCount;
|
||||||
|
int localNodeIndex = opmNodeIndex % 8;
|
||||||
|
|
||||||
|
cvf::Vec3d closestPillarCoord;
|
||||||
|
if ( localNodeIndex < 4 )
|
||||||
|
{
|
||||||
|
// Top of cell
|
||||||
|
int pillarCoordIndex = layerIndexInMainGridCell * 2;
|
||||||
|
closestPillarCoord = pillarCordinates[pillarCoordIndex];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Bottom of cell
|
||||||
|
int pillarCoordIndex = layerIndexInMainGridCell * 2 + 1;
|
||||||
|
closestPillarCoord = pillarCordinates[pillarCoordIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
riNode.x() = closestPillarCoord.x();
|
||||||
|
riNode.y() = closestPillarCoord.y();
|
||||||
|
riNode.z() = -closestPillarCoord.z();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
riActiveCells->setGridCount( 1 );
|
|
||||||
riActiveCells->setGridActiveCellCounts( 0, opmGrid.activeCells() );
|
|
||||||
riActiveCells->computeDerivedData();
|
|
||||||
|
|
||||||
riMainGrid->initAllSubGridsParentGridPointer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::map<int, std::pair<double, double>>
|
std::map<int, std::pair<double, double>>
|
||||||
RifOpmGridTools::computeXyCenterForTopOfCells( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, RigGridBase* riGrid )
|
RifOpmRadialGridTools::computeXyCenterForTopOfCells( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, RigGridBase* riGrid )
|
||||||
{
|
{
|
||||||
if ( !riGrid || riGrid->isMainGrid() ) return {};
|
if ( !riGrid || riGrid->isMainGrid() ) return {};
|
||||||
|
|
||||||
@ -420,7 +291,6 @@ std::map<int, std::pair<double, double>>
|
|||||||
if ( cellCount != riGrid->cellCount() ) return {};
|
if ( cellCount != riGrid->cellCount() ) return {};
|
||||||
|
|
||||||
// Read out the corner coordinates from the EGRID file using radial coordinates.
|
// Read out the corner coordinates from the EGRID file using radial coordinates.
|
||||||
// Prefix OPM structures with _opm_and ResInsight structures with _ri_
|
|
||||||
|
|
||||||
// Compute the center of the LGR radial grid cells for each K layer
|
// Compute the center of the LGR radial grid cells for each K layer
|
||||||
std::map<int, std::pair<double, double>> radialGridCenterTopLayerOpm;
|
std::map<int, std::pair<double, double>> radialGridCenterTopLayerOpm;
|
||||||
@ -471,8 +341,10 @@ std::map<int, std::pair<double, double>>
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::vector<std::vector<cvf::Vec3d>>
|
std::vector<std::vector<cvf::Vec3d>> RifOpmRadialGridTools::computeSnapToCoordinates( Opm::EclIO::EGrid& opmMainGrid,
|
||||||
RifOpmGridTools::computeSnapToCoordinates( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, int mainGridCellIndex, int lgrCellIndex )
|
Opm::EclIO::EGrid& opmGrid,
|
||||||
|
int mainGridCellIndex,
|
||||||
|
int lgrCellIndex )
|
||||||
{
|
{
|
||||||
auto hostCellIndices = opmGrid.hostCellsGlobalIndex();
|
auto hostCellIndices = opmGrid.hostCellsGlobalIndex();
|
||||||
auto lgrIjk = opmGrid.ijk_from_global_index( lgrCellIndex );
|
auto lgrIjk = opmGrid.ijk_from_global_index( lgrCellIndex );
|
@ -39,28 +39,28 @@ class RigEclipseCaseData;
|
|||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
///
|
///
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
class RifOpmGridTools
|
class RifOpmRadialGridTools
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// If the grid is radial, the coordinates are imported and adjusted to fit the host cells
|
// If the grid is radial, the coordinates are imported and adjusted to fit the host cells
|
||||||
static void importCoordinatesForRadialGrid( const std::string& gridFilePath, RigMainGrid* mainGrid );
|
static void importCoordinatesForRadialGrid( const std::string& gridFilePath, RigMainGrid* mainGrid );
|
||||||
|
|
||||||
static size_t cellCount( const std::string& gridFilePath );
|
static void
|
||||||
static bool importGrid( const std::string& gridFilePath, RigMainGrid* mainGrid, RigEclipseCaseData* caseData );
|
transferCoordinatesRadial( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, RigMainGrid* riMainGrid, RigGridBase* riGrid );
|
||||||
|
|
||||||
static std::vector<std::vector<int>> activeCellsFromActnumKeyword( Opm::EclIO::EGrid& grid );
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void transferCoordinates( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, RigMainGrid* riMainGrid, RigGridBase* riGrid );
|
|
||||||
static void transferCoordinatesCartesian( Opm::EclIO::EGrid& opmMainGrid,
|
|
||||||
Opm::EclIO::EGrid& opmGrid,
|
|
||||||
RigMainGrid* riMainGrid,
|
|
||||||
RigGridBase* riGrid,
|
|
||||||
RigEclipseCaseData* caseData );
|
|
||||||
|
|
||||||
static std::map<int, std::pair<double, double>>
|
static std::map<int, std::pair<double, double>>
|
||||||
computeXyCenterForTopOfCells( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, RigGridBase* riGrid );
|
computeXyCenterForTopOfCells( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, RigGridBase* riGrid );
|
||||||
|
|
||||||
static std::vector<std::vector<cvf::Vec3d>>
|
static std::vector<std::vector<cvf::Vec3d>>
|
||||||
computeSnapToCoordinates( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, int mainGridCellIndex, int lgrCellIndex );
|
computeSnapToCoordinates( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, int mainGridCellIndex, int lgrCellIndex );
|
||||||
|
|
||||||
|
static void lockToHostPillars( cvf::Vec3d& riNode,
|
||||||
|
Opm::EclIO::EGrid& opmMainGrid,
|
||||||
|
Opm::EclIO::EGrid& opmGrid,
|
||||||
|
std::array<int, 3>& ijkCell,
|
||||||
|
int hostCellIndex,
|
||||||
|
int opmCellIndex,
|
||||||
|
size_t opmNodeIndex,
|
||||||
|
double xCenterCoordOpm,
|
||||||
|
double yCenterCoordOpm );
|
||||||
};
|
};
|
File diff suppressed because it is too large
Load Diff
@ -36,7 +36,7 @@ class RigEclipseTimeStepInfo;
|
|||||||
class RigGridBase;
|
class RigGridBase;
|
||||||
class RigMainGrid;
|
class RigMainGrid;
|
||||||
class QDateTime;
|
class QDateTime;
|
||||||
class RifKeywordValueCount;
|
class RifEclipseKeywordValueCount;
|
||||||
|
|
||||||
struct RigWellResultPoint;
|
struct RigWellResultPoint;
|
||||||
|
|
||||||
@ -91,43 +91,33 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool readActiveCellInfo();
|
bool readActiveCellInfo();
|
||||||
|
|
||||||
void buildMetaData( ecl_grid_type* grid );
|
|
||||||
void readWellCells( const ecl_grid_type* mainEclGrid, bool importCompleteMswData );
|
|
||||||
|
|
||||||
std::string ertGridName( size_t gridNr );
|
std::string ertGridName( size_t gridNr );
|
||||||
|
|
||||||
RigWellResultPoint createWellResultPoint( const RigGridBase* grid, const well_conn_type* ert_connection, const char* wellName );
|
void buildMetaData( ecl_grid_type* grid );
|
||||||
|
|
||||||
RigWellResultPoint createWellResultPoint( const RigGridBase* grid,
|
|
||||||
const well_conn_type* ert_connection,
|
|
||||||
const well_segment_type* segment,
|
|
||||||
const char* wellName );
|
|
||||||
|
|
||||||
void openInitFile();
|
void openInitFile();
|
||||||
|
|
||||||
void extractResultValuesBasedOnPorosityModel( RiaDefines::PorosityModelType matrixOrFracture,
|
|
||||||
std::vector<double>* values,
|
|
||||||
const std::vector<double>& fileValues );
|
|
||||||
void transferStaticNNCData( const ecl_grid_type* mainEclGrid, ecl_file_type* init_file, RigMainGrid* mainGrid );
|
void transferStaticNNCData( const ecl_grid_type* mainEclGrid, ecl_file_type* init_file, RigMainGrid* mainGrid );
|
||||||
void transferDynamicNNCData( const ecl_grid_type* mainEclGrid, RigMainGrid* mainGrid );
|
void transferDynamicNNCData( const ecl_grid_type* mainEclGrid, RigMainGrid* mainGrid );
|
||||||
|
|
||||||
void ensureDynamicResultAccessIsPresent();
|
void ensureDynamicResultAccessIsPresent();
|
||||||
|
|
||||||
static std::vector<RifKeywordValueCount> validKeywordsForPorosityModel( const std::vector<RifKeywordValueCount>& keywordItemCounts,
|
|
||||||
const RigActiveCellInfo* activeCellInfo,
|
|
||||||
const RigActiveCellInfo* fractureActiveCellInfo,
|
|
||||||
RiaDefines::PorosityModelType matrixOrFracture,
|
|
||||||
size_t timeStepCount );
|
|
||||||
|
|
||||||
std::vector<RigEclipseTimeStepInfo> createFilteredTimeStepInfos();
|
std::vector<RigEclipseTimeStepInfo> createFilteredTimeStepInfos();
|
||||||
|
|
||||||
static bool isEclipseAndSoursimTimeStepsEqual( const QDateTime& eclipseDateTime, const QDateTime& sourSimDateTime );
|
static bool isEclipseAndSoursimTimeStepsEqual( const QDateTime& eclipseDateTime, const QDateTime& sourSimDateTime );
|
||||||
|
static bool transferGridCellData( RigMainGrid* mainGrid,
|
||||||
|
RigActiveCellInfo* activeCellInfo,
|
||||||
|
RigActiveCellInfo* fractureActiveCellInfo,
|
||||||
|
RigGridBase* localGrid,
|
||||||
|
const ecl_grid_type* localEclGrid,
|
||||||
|
size_t matrixActiveStartIndex,
|
||||||
|
size_t fractureActiveStartIndex );
|
||||||
|
|
||||||
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_filesWithSameBaseName; // Set of files in filename's path with same base name as filename
|
QStringList m_filesWithSameBaseName; // Set of files in filename's path with same base name as filename
|
||||||
|
|
||||||
RigEclipseCaseData* m_eclipseCase;
|
RigEclipseCaseData* m_eclipseCaseData;
|
||||||
|
|
||||||
ecl_file_type* m_ecl_init_file; // File access to static results
|
ecl_file_type* m_ecl_init_file; // File access to static results
|
||||||
mutable cvf::ref<RifEclipseRestartDataAccess> m_dynamicResultsAccess; // File access to dynamic results
|
mutable cvf::ref<RifEclipseRestartDataAccess> m_dynamicResultsAccess; // File access to dynamic results
|
||||||
|
1006
ApplicationLibCode/FileInterface/RifReaderEclipseWell.cpp
Normal file
1006
ApplicationLibCode/FileInterface/RifReaderEclipseWell.cpp
Normal file
File diff suppressed because it is too large
Load Diff
78
ApplicationLibCode/FileInterface/RifReaderEclipseWell.h
Normal file
78
ApplicationLibCode/FileInterface/RifReaderEclipseWell.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2024 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 <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "cvfVector3.h"
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
|
class RifEclipseRestartDataAccess;
|
||||||
|
class RigGridBase;
|
||||||
|
class RigEclipseCaseData;
|
||||||
|
|
||||||
|
struct RigWellResultPoint;
|
||||||
|
struct SegmentPositionContribution;
|
||||||
|
|
||||||
|
// NOLINTBEGIN(modernize-use-using)
|
||||||
|
typedef struct well_conn_struct well_conn_type;
|
||||||
|
typedef struct well_segment_struct well_segment_type;
|
||||||
|
typedef struct well_segment_collection_struct well_segment_collection_type;
|
||||||
|
// NOLINTEND(modernize-use-using)
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==================================================================================================
|
||||||
|
class RifReaderEclipseWell
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
RifReaderEclipseWell(){};
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void readWellCells( RifEclipseRestartDataAccess* restartDataAccess,
|
||||||
|
RigEclipseCaseData* eclipseCaseData,
|
||||||
|
std::vector<QDateTime> filteredTimeSteps,
|
||||||
|
std::vector<std::string> gridNames,
|
||||||
|
bool importCompleteMswData );
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
localGridCellIndexFromErtConnection( const RigGridBase* grid, const well_conn_type* ert_connection, const char* wellNameForErrorMsgs );
|
||||||
|
|
||||||
|
private:
|
||||||
|
static RigWellResultPoint createWellResultPoint( const RigEclipseCaseData* eCaseData,
|
||||||
|
const RigGridBase* grid,
|
||||||
|
const well_conn_type* ert_connection,
|
||||||
|
const char* wellName );
|
||||||
|
static RigWellResultPoint createWellResultPoint( const RigEclipseCaseData* eCaseData,
|
||||||
|
const RigGridBase* grid,
|
||||||
|
const well_conn_type* ert_connection,
|
||||||
|
const well_segment_type* segment,
|
||||||
|
const char* wellName );
|
||||||
|
|
||||||
|
static cvf::Vec3d interpolate3DPosition( const std::vector<SegmentPositionContribution>& positions );
|
||||||
|
static void propagatePosContribDownwards( std::map<int, std::vector<SegmentPositionContribution>>& segmentIdToPositionContrib,
|
||||||
|
const well_segment_collection_type* allErtSegments,
|
||||||
|
int ertSegmentId,
|
||||||
|
std::vector<SegmentPositionContribution> posContrib );
|
||||||
|
|
||||||
|
static std::string ertGridName( const RigEclipseCaseData* eCaseData, size_t gridNr );
|
||||||
|
};
|
@ -51,9 +51,9 @@ bool RifReaderInterface::isNNCsEnabled()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RifReaderInterface::isSkipWellData()
|
bool RifReaderInterface::loadWellDataEnabled()
|
||||||
{
|
{
|
||||||
return readerSettings()->skipWellData;
|
return !readerSettings()->skipWellData;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -56,7 +56,7 @@ public:
|
|||||||
bool isImportOfCompleteMswDataEnabled();
|
bool isImportOfCompleteMswDataEnabled();
|
||||||
bool isNNCsEnabled();
|
bool isNNCsEnabled();
|
||||||
bool includeInactiveCellsInFaultGeometry();
|
bool includeInactiveCellsInFaultGeometry();
|
||||||
bool isSkipWellData();
|
bool loadWellDataEnabled();
|
||||||
const QString faultIncludeFileAbsolutePathPrefix();
|
const QString faultIncludeFileAbsolutePathPrefix();
|
||||||
|
|
||||||
virtual bool open( const QString& fileName, RigEclipseCaseData* eclipseCase ) = 0;
|
virtual bool open( const QString& fileName, RigEclipseCaseData* eclipseCase ) = 0;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -21,13 +21,26 @@
|
|||||||
#include "RifReaderInterface.h"
|
#include "RifReaderInterface.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Opm::EclIO
|
namespace Opm::EclIO
|
||||||
{
|
{
|
||||||
class EInit;
|
class EInit;
|
||||||
class ERst;
|
class ERst;
|
||||||
|
class EGrid;
|
||||||
} // namespace Opm::EclIO
|
} // namespace Opm::EclIO
|
||||||
|
|
||||||
|
class RigMainGrid;
|
||||||
|
class RigGridBase;
|
||||||
|
class RigEclipseCaseData;
|
||||||
|
class RigEclipseTimeStepInfo;
|
||||||
|
|
||||||
|
namespace caf
|
||||||
|
{
|
||||||
|
class ProgressInfo;
|
||||||
|
}
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@ -38,13 +51,31 @@ public:
|
|||||||
RifReaderOpmCommon();
|
RifReaderOpmCommon();
|
||||||
~RifReaderOpmCommon() override;
|
~RifReaderOpmCommon() override;
|
||||||
|
|
||||||
bool open( const QString& fileName, RigEclipseCaseData* eclipseCase ) override;
|
bool open( const QString& fileName, RigEclipseCaseData* caseData ) override;
|
||||||
|
|
||||||
bool staticResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, std::vector<double>* values ) override;
|
bool staticResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, std::vector<double>* values ) override;
|
||||||
bool dynamicResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector<double>* values ) override;
|
bool dynamicResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector<double>* values ) override;
|
||||||
|
|
||||||
|
std::vector<QDateTime> timeStepsOnFile( QString gridFileName );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void buildMetaData( RigEclipseCaseData* eclipseCase );
|
void buildMetaData( RigEclipseCaseData* caseData, caf::ProgressInfo& progress );
|
||||||
|
bool importGrid( RigMainGrid* mainGrid, RigEclipseCaseData* caseData );
|
||||||
|
void transferGeometry( Opm::EclIO::EGrid& opmMainGrid,
|
||||||
|
Opm::EclIO::EGrid& opmGrid,
|
||||||
|
RigMainGrid* riMainGrid,
|
||||||
|
RigGridBase* riGrid,
|
||||||
|
RigEclipseCaseData* caseData,
|
||||||
|
size_t matrixActiveStartIndex,
|
||||||
|
size_t fractureActiveStartIndex );
|
||||||
|
|
||||||
|
void transferStaticNNCData( Opm::EclIO::EGrid& opmMainGrid, std::vector<Opm::EclIO::EGrid>& lgrGrids, RigMainGrid* mainGrid );
|
||||||
|
void transferDynamicNNCData( RigMainGrid* mainGrid );
|
||||||
|
|
||||||
|
void locateInitAndRestartFiles( QString gridFileName );
|
||||||
|
void setupInitAndRestartAccess();
|
||||||
|
|
||||||
|
std::vector<RigEclipseTimeStepInfo> createFilteredTimeStepInfos();
|
||||||
|
|
||||||
struct TimeDataFile
|
struct TimeDataFile
|
||||||
{
|
{
|
||||||
@ -55,16 +86,18 @@ private:
|
|||||||
double simulationTimeFromStart;
|
double simulationTimeFromStart;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<TimeDataFile> readTimeSteps( std::shared_ptr<Opm::EclIO::ERst> restartFile );
|
std::vector<TimeDataFile> readTimeSteps();
|
||||||
static void readWellCells( std::shared_ptr<Opm::EclIO::ERst> restartFile,
|
|
||||||
RigEclipseCaseData* eclipseCase,
|
|
||||||
const std::vector<QDateTime>& timeSteps );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_gridFileName;
|
std::string m_gridFileName;
|
||||||
|
std::string m_initFileName;
|
||||||
|
std::string m_restartFileName;
|
||||||
|
int m_gridUnit;
|
||||||
|
|
||||||
std::shared_ptr<Opm::EclIO::ERst> m_restartFile;
|
RigEclipseCaseData* m_eclipseCaseData;
|
||||||
std::shared_ptr<Opm::EclIO::EInit> m_initFile;
|
|
||||||
|
|
||||||
std::vector<QDateTime> m_timeSteps;
|
std::unique_ptr<Opm::EclIO::ERst> m_restartFile;
|
||||||
|
std::unique_ptr<Opm::EclIO::EInit> m_initFile;
|
||||||
|
|
||||||
|
std::vector<std::string> m_gridNames;
|
||||||
};
|
};
|
||||||
|
@ -819,14 +819,17 @@ QString RimFlowCharacteristicsPlot::curveDataAsText() const
|
|||||||
auto storageCapacityValues = a->second.m_storageCapFlowCapCurve.first;
|
auto storageCapacityValues = a->second.m_storageCapFlowCapCurve.first;
|
||||||
auto flowCapacityValues = a->second.m_storageCapFlowCapCurve.second;
|
auto flowCapacityValues = a->second.m_storageCapFlowCapCurve.second;
|
||||||
|
|
||||||
|
if ( storageCapacityValues.size() < 2 || flowCapacityValues.size() < 2 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bool extrapolate = false;
|
bool extrapolate = false;
|
||||||
std::vector<double> flowCapacitySamplingValues;
|
std::vector<double> flowCapacitySamplingValues;
|
||||||
for ( const auto storageCapacity : storageCapacitySamplingValues )
|
for ( const auto storageCapacity : storageCapacitySamplingValues )
|
||||||
{
|
{
|
||||||
{
|
double flowCapacity = interpolate( storageCapacityValues, flowCapacityValues, storageCapacity, extrapolate );
|
||||||
double flowCapacity = interpolate( storageCapacityValues, flowCapacityValues, storageCapacity, extrapolate );
|
flowCapacitySamplingValues.push_back( flowCapacity );
|
||||||
flowCapacitySamplingValues.push_back( flowCapacity );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dimensionLessTimeValues = a->second.m_dimensionlessTimeSweepEfficiencyCurve.first;
|
auto dimensionLessTimeValues = a->second.m_dimensionlessTimeSweepEfficiencyCurve.first;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "RicfCommandObject.h"
|
#include "RicfCommandObject.h"
|
||||||
|
|
||||||
#include "RifEclipseOutputFileTools.h"
|
#include "RifEclipseOutputFileTools.h"
|
||||||
|
#include "RifEclipseRestartDataAccess.h"
|
||||||
#include "RifInputPropertyLoader.h"
|
#include "RifInputPropertyLoader.h"
|
||||||
#include "RifReaderEclipseOutput.h"
|
#include "RifReaderEclipseOutput.h"
|
||||||
#include "RifReaderEclipseRft.h"
|
#include "RifReaderEclipseRft.h"
|
||||||
@ -109,6 +110,28 @@ bool RimEclipseResultCase::openEclipseGridFile()
|
|||||||
return importGridAndResultMetaData( false );
|
return importGridAndResultMetaData( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RimEclipseResultCase::showTimeStepFilterGUI()
|
||||||
|
{
|
||||||
|
caf::PdmUiPropertyViewDialog propertyDialog( nullptr, m_timeStepFilter, "Time Step Filter", "", QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
|
||||||
|
propertyDialog.resize( QSize( 400, 400 ) );
|
||||||
|
|
||||||
|
// Push arrow cursor onto the cursor stack so it takes over from the wait cursor.
|
||||||
|
QApplication::setOverrideCursor( QCursor( Qt::ArrowCursor ) );
|
||||||
|
// Show GUI to select time steps
|
||||||
|
int dialogReturnValue = propertyDialog.exec();
|
||||||
|
// Pop arrow cursor off the cursor stack so that the previous (wait) cursor takes over.
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
|
||||||
|
if ( dialogReturnValue != QDialog::Accepted ) return false;
|
||||||
|
|
||||||
|
m_timeStepFilter->updateFilteredTimeStepsFromUi();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -137,56 +160,48 @@ bool RimEclipseResultCase::importGridAndResultMetaData( bool showTimeStepFilter
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto defaultReader = RiaPreferences::current()->gridModelReader();
|
auto readerType = RiaPreferences::current()->gridModelReader();
|
||||||
|
|
||||||
if ( defaultReader == RiaDefines::GridModelReader::RESDATA )
|
// opmcommon reader only reads EGRID
|
||||||
|
if ( !gridFileName().toLower().endsWith( ".egrid" ) )
|
||||||
|
{
|
||||||
|
readerType = RiaDefines::GridModelReader::RESDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( readerType == RiaDefines::GridModelReader::RESDATA )
|
||||||
{
|
{
|
||||||
auto readerEclipseOutput = new RifReaderEclipseOutput();
|
auto readerEclipseOutput = new RifReaderEclipseOutput();
|
||||||
|
|
||||||
cvf::ref<RifEclipseRestartDataAccess> restartDataAccess = RifEclipseOutputFileTools::createDynamicResultAccess( gridFileName() );
|
cvf::ref<RifEclipseRestartDataAccess> restartDataAccess = RifEclipseOutputFileTools::createDynamicResultAccess( gridFileName() );
|
||||||
|
|
||||||
|
std::vector<QDateTime> timeSteps;
|
||||||
|
std::vector<double> daysSinceSimulationStart;
|
||||||
|
|
||||||
|
if ( restartDataAccess.notNull() )
|
||||||
{
|
{
|
||||||
std::vector<QDateTime> timeSteps;
|
restartDataAccess->timeSteps( &timeSteps, &daysSinceSimulationStart );
|
||||||
std::vector<double> daysSinceSimulationStart;
|
|
||||||
|
|
||||||
if ( restartDataAccess.notNull() )
|
|
||||||
{
|
|
||||||
restartDataAccess->timeSteps( &timeSteps, &daysSinceSimulationStart );
|
|
||||||
}
|
|
||||||
m_timeStepFilter->setTimeStepsFromFile( timeSteps );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( showTimeStepFilter )
|
|
||||||
{
|
|
||||||
caf::PdmUiPropertyViewDialog propertyDialog( nullptr,
|
|
||||||
m_timeStepFilter,
|
|
||||||
"Time Step Filter",
|
|
||||||
"",
|
|
||||||
QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
|
|
||||||
propertyDialog.resize( QSize( 400, 400 ) );
|
|
||||||
|
|
||||||
// Push arrow cursor onto the cursor stack so it takes over from the wait cursor.
|
|
||||||
QApplication::setOverrideCursor( QCursor( Qt::ArrowCursor ) );
|
|
||||||
// Show GUI to select time steps
|
|
||||||
int dialogReturnValue = propertyDialog.exec();
|
|
||||||
// Pop arrow cursor off the cursor stack so that the previous (wait) cursor takes over.
|
|
||||||
QApplication::restoreOverrideCursor();
|
|
||||||
|
|
||||||
if ( dialogReturnValue != QDialog::Accepted )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_timeStepFilter->updateFilteredTimeStepsFromUi();
|
|
||||||
}
|
}
|
||||||
|
m_timeStepFilter->setTimeStepsFromFile( timeSteps );
|
||||||
|
|
||||||
readerEclipseOutput->setFileDataAccess( restartDataAccess.p() );
|
readerEclipseOutput->setFileDataAccess( restartDataAccess.p() );
|
||||||
readerEclipseOutput->setTimeStepFilter( m_timeStepFilter->filteredTimeSteps() );
|
|
||||||
|
|
||||||
readerInterface = readerEclipseOutput;
|
readerInterface = readerEclipseOutput;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
readerInterface = new RifReaderOpmCommon;
|
auto readerOpmCommon = new RifReaderOpmCommon();
|
||||||
|
|
||||||
|
std::vector<QDateTime> timeSteps = readerOpmCommon->timeStepsOnFile( gridFileName() );
|
||||||
|
m_timeStepFilter->setTimeStepsFromFile( timeSteps );
|
||||||
|
|
||||||
|
readerInterface = readerOpmCommon;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( showTimeStepFilter )
|
||||||
|
{
|
||||||
|
if ( !showTimeStepFilterGUI() ) return false;
|
||||||
|
|
||||||
|
readerInterface->setTimeStepFilter( m_timeStepFilter->filteredTimeSteps() );
|
||||||
}
|
}
|
||||||
|
|
||||||
readerInterface->setFilenamesWithFaults( filesContainingFaults() );
|
readerInterface->setFilenamesWithFaults( filesContainingFaults() );
|
||||||
|
@ -84,6 +84,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void loadAndUpdateSourSimData();
|
void loadAndUpdateSourSimData();
|
||||||
void ensureRftDataIsImported();
|
void ensureRftDataIsImported();
|
||||||
|
bool showTimeStepFilterGUI();
|
||||||
|
|
||||||
cvf::ref<RifReaderInterface> createMockModel( QString modelName );
|
cvf::ref<RifReaderInterface> createMockModel( QString modelName );
|
||||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||||
|
@ -625,6 +625,11 @@ RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( m_opmFlowDiagStaticData.isNull() )
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<double> poreVolume;
|
std::vector<double> poreVolume;
|
||||||
for ( size_t cellIndex : selected_cell_indices )
|
for ( size_t cellIndex : selected_cell_indices )
|
||||||
{
|
{
|
||||||
|
@ -312,6 +312,21 @@ const RigGridBase* RigMainGrid::gridByIndex( size_t localGridIndex ) const
|
|||||||
return m_localGrids[localGridIndex - 1].p();
|
return m_localGrids[localGridIndex - 1].p();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
/// Returns the grid with the given name. Main Grid itself could be retreived by using name ""
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RigGridBase* RigMainGrid::gridByName( const std::string& name )
|
||||||
|
{
|
||||||
|
if ( name.empty() ) return this;
|
||||||
|
|
||||||
|
for ( auto& grid : m_localGrids )
|
||||||
|
{
|
||||||
|
if ( grid->gridName() == name ) return grid.p();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -63,6 +63,7 @@ public:
|
|||||||
RigGridBase* gridByIndex( size_t localGridIndex );
|
RigGridBase* gridByIndex( size_t localGridIndex );
|
||||||
const RigGridBase* gridByIndex( size_t localGridIndex ) const;
|
const RigGridBase* gridByIndex( size_t localGridIndex ) const;
|
||||||
RigGridBase* gridById( int localGridId );
|
RigGridBase* gridById( int localGridId );
|
||||||
|
RigGridBase* gridByName( const std::string& name );
|
||||||
|
|
||||||
size_t totalTemporaryGridCellCount() const;
|
size_t totalTemporaryGridCellCount() const;
|
||||||
|
|
||||||
|
@ -65,8 +65,8 @@ void RigSimWellData::computeMappingFromResultTimeIndicesToWellTimeIndices( const
|
|||||||
wellTimeStepIndex++;
|
wellTimeStepIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( wellTimeStepIndex < m_wellCellsTimeSteps.size() &&
|
if ( ( wellTimeStepIndex < m_wellCellsTimeSteps.size() ) &&
|
||||||
m_wellCellsTimeSteps[wellTimeStepIndex].timestamp() == simulationTimeSteps[resultTimeStepIndex] )
|
( m_wellCellsTimeSteps[wellTimeStepIndex].timestamp() == simulationTimeSteps[resultTimeStepIndex] ) )
|
||||||
{
|
{
|
||||||
m_resultTimeStepIndexToWellTimeStepIndex[resultTimeStepIndex] = wellTimeStepIndex;
|
m_resultTimeStepIndexToWellTimeStepIndex[resultTimeStepIndex] = wellTimeStepIndex;
|
||||||
}
|
}
|
||||||
|
187
ThirdParty/Ert/lib/ecl/well_info.cpp
vendored
187
ThirdParty/Ert/lib/ecl/well_info.cpp
vendored
@ -182,9 +182,9 @@
|
|||||||
|
|
||||||
|
|
||||||
struct well_info_struct {
|
struct well_info_struct {
|
||||||
std::map<std::string, well_ts_type*> wells; /* std::map of well_ts_type instances; indexed by well name. */
|
std::map<std::string, well_ts_type*> wells; /* std::map of well_ts_type instances; indexed by well name. */
|
||||||
std::vector<std::string> well_names; /* A list of all the well names. */
|
std::vector<std::string> well_names; /* A list of all the well names. */
|
||||||
const ecl_grid_type * grid;
|
std::vector<std::string> grid_names; /* A list of all grid names, main grid is at index 0, lgrs at 1 and above, if any */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -193,39 +193,39 @@ struct well_info_struct {
|
|||||||
it to resolve lgr names.
|
it to resolve lgr names.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
well_info_type * well_info_alloc( const ecl_grid_type * grid) {
|
well_info_type* well_info_alloc(const std::vector<std::string> grid_names) {
|
||||||
well_info_type * well_info = new well_info_type();
|
well_info_type* well_info = new well_info_type();
|
||||||
well_info->grid = grid;
|
well_info->grid_names = grid_names;
|
||||||
return well_info;
|
return well_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool well_info_has_well( well_info_type * well_info , const char * well_name ) {
|
bool well_info_has_well(well_info_type* well_info, const char* well_name) {
|
||||||
const auto it = well_info->wells.find(well_name);
|
const auto it = well_info->wells.find(well_name);
|
||||||
if (it == well_info->wells.end())
|
if (it == well_info->wells.end())
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
well_ts_type * well_info_get_ts( const well_info_type * well_info , const char *well_name) {
|
well_ts_type* well_info_get_ts(const well_info_type* well_info, const char* well_name) {
|
||||||
return well_info->wells.at( well_name );
|
return well_info->wells.at(well_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void well_info_add_new_ts( well_info_type * well_info , const char * well_name) {
|
static void well_info_add_new_ts(well_info_type* well_info, const char* well_name) {
|
||||||
well_ts_type * well_ts = well_ts_alloc( well_name ) ;
|
well_ts_type* well_ts = well_ts_alloc(well_name);
|
||||||
well_info->wells[well_name] = well_ts;
|
well_info->wells[well_name] = well_ts;
|
||||||
well_info->well_names.push_back( well_name );
|
well_info->well_names.push_back(well_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void well_info_add_state( well_info_type * well_info , well_state_type * well_state) {
|
static void well_info_add_state(well_info_type* well_info, well_state_type* well_state) {
|
||||||
const char * well_name = well_state_get_name( well_state );
|
const char* well_name = well_state_get_name(well_state);
|
||||||
if (!well_info_has_well( well_info , well_name))
|
if (!well_info_has_well(well_info, well_name))
|
||||||
well_info_add_new_ts( well_info , well_name );
|
well_info_add_new_ts(well_info, well_name);
|
||||||
|
|
||||||
{
|
{
|
||||||
well_ts_type * well_ts = well_info_get_ts( well_info , well_name );
|
well_ts_type* well_ts = well_info_get_ts(well_info, well_name);
|
||||||
well_ts_add_well( well_ts , well_state );
|
well_ts_add_well(well_ts, well_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -278,23 +278,23 @@ static void well_info_add_state( well_info_type * well_info , well_state_type *
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
void well_info_add_wells2( well_info_type * well_info , ecl_file_view_type * rst_view , int report_nr, bool load_segment_information) {
|
void well_info_add_wells2(well_info_type* well_info, ecl_file_view_type* rst_view, int report_nr, bool load_segment_information) {
|
||||||
bool close_stream = ecl_file_view_drop_flag( rst_view , ECL_FILE_CLOSE_STREAM );
|
bool close_stream = ecl_file_view_drop_flag(rst_view, ECL_FILE_CLOSE_STREAM);
|
||||||
ecl_rsthead_type * global_header = ecl_rsthead_alloc( rst_view , report_nr );
|
ecl_rsthead_type* global_header = ecl_rsthead_alloc(rst_view, report_nr);
|
||||||
int well_nr;
|
int well_nr;
|
||||||
for (well_nr = 0; well_nr < global_header->nwells; well_nr++) {
|
for (well_nr = 0; well_nr < global_header->nwells; well_nr++) {
|
||||||
well_state_type * well_state = well_state_alloc_from_file2( rst_view , well_info->grid , report_nr , well_nr , load_segment_information );
|
well_state_type* well_state = well_state_alloc_from_file2(rst_view, well_info->grid_names, report_nr, well_nr, load_segment_information);
|
||||||
if (well_state != NULL)
|
if (well_state != NULL)
|
||||||
well_info_add_state( well_info , well_state );
|
well_info_add_state(well_info, well_state);
|
||||||
}
|
}
|
||||||
ecl_rsthead_free( global_header );
|
ecl_rsthead_free(global_header);
|
||||||
if (close_stream)
|
if (close_stream)
|
||||||
ecl_file_view_add_flag(rst_view, ECL_FILE_CLOSE_STREAM);
|
ecl_file_view_add_flag(rst_view, ECL_FILE_CLOSE_STREAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void well_info_add_wells( well_info_type * well_info , ecl_file_type * rst_file , int report_nr, bool load_segment_information) {
|
void well_info_add_wells(well_info_type* well_info, ecl_file_type* rst_file, int report_nr, bool load_segment_information) {
|
||||||
well_info_add_wells2( well_info , ecl_file_get_active_view( rst_file ) , report_nr , load_segment_information );
|
well_info_add_wells2(well_info, ecl_file_get_active_view(rst_file), report_nr, load_segment_information);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -303,25 +303,25 @@ void well_info_add_wells( well_info_type * well_info , ecl_file_type * rst_file
|
|||||||
not have the SEQNUM keyword.
|
not have the SEQNUM keyword.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void well_info_add_UNRST_wells2( well_info_type * well_info , ecl_file_view_type * rst_view, bool load_segment_information) {
|
void well_info_add_UNRST_wells2(well_info_type* well_info, ecl_file_view_type* rst_view, bool load_segment_information) {
|
||||||
int num_blocks = ecl_file_view_get_num_named_kw( rst_view , SEQNUM_KW );
|
int num_blocks = ecl_file_view_get_num_named_kw(rst_view, SEQNUM_KW);
|
||||||
int block_nr;
|
int block_nr;
|
||||||
for (block_nr = 0; block_nr < num_blocks; block_nr++) {
|
for (block_nr = 0; block_nr < num_blocks; block_nr++) {
|
||||||
|
|
||||||
ecl_file_view_type * step_view = ecl_file_view_add_restart_view(rst_view, block_nr , -1 , -1 , -1 );
|
ecl_file_view_type* step_view = ecl_file_view_add_restart_view(rst_view, block_nr, -1, -1, -1);
|
||||||
const ecl_kw_type * seqnum_kw = ecl_file_view_iget_named_kw( step_view , SEQNUM_KW , 0);
|
const ecl_kw_type* seqnum_kw = ecl_file_view_iget_named_kw(step_view, SEQNUM_KW, 0);
|
||||||
int report_nr = ecl_kw_iget_int( seqnum_kw , 0 );
|
int report_nr = ecl_kw_iget_int(seqnum_kw, 0);
|
||||||
|
|
||||||
ecl_file_transaction_type * t = ecl_file_view_start_transaction(rst_view);
|
ecl_file_transaction_type* t = ecl_file_view_start_transaction(rst_view);
|
||||||
well_info_add_wells2( well_info , step_view , report_nr , load_segment_information );
|
well_info_add_wells2(well_info, step_view, report_nr, load_segment_information);
|
||||||
ecl_file_view_end_transaction(rst_view, t);
|
ecl_file_view_end_transaction(rst_view, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void well_info_add_UNRST_wells( well_info_type * well_info , ecl_file_type * rst_file, bool load_segment_information) {
|
void well_info_add_UNRST_wells(well_info_type* well_info, ecl_file_type* rst_file, bool load_segment_information) {
|
||||||
well_info_add_UNRST_wells2( well_info , ecl_file_get_global_view( rst_file ) , load_segment_information);
|
well_info_add_UNRST_wells2(well_info, ecl_file_get_global_view(rst_file), load_segment_information);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -331,71 +331,72 @@ void well_info_add_UNRST_wells( well_info_type * well_info , ecl_file_type * rst
|
|||||||
have crash and burn.
|
have crash and burn.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void well_info_load_rstfile( well_info_type * well_info , const char * filename, bool load_segment_information) {
|
void well_info_load_rstfile(well_info_type* well_info, const char* filename, bool load_segment_information) {
|
||||||
ecl_file_type * ecl_file = ecl_file_open( filename , 0);
|
ecl_file_type* ecl_file = ecl_file_open(filename, 0);
|
||||||
well_info_load_rst_eclfile(well_info, ecl_file, load_segment_information);
|
well_info_load_rst_eclfile(well_info, ecl_file, load_segment_information);
|
||||||
ecl_file_close( ecl_file );
|
ecl_file_close(ecl_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void well_info_load_rst_eclfile( well_info_type * well_info , ecl_file_type * ecl_file, bool load_segment_information) {
|
void well_info_load_rst_eclfile(well_info_type* well_info, ecl_file_type* ecl_file, bool load_segment_information) {
|
||||||
int report_nr;
|
int report_nr;
|
||||||
const char* filename = ecl_file_get_src_file(ecl_file);
|
const char* filename = ecl_file_get_src_file(ecl_file);
|
||||||
ecl_file_enum file_type = ecl_util_get_file_type( filename , NULL , &report_nr);
|
ecl_file_enum file_type = ecl_util_get_file_type(filename, NULL, &report_nr);
|
||||||
if ((file_type == ECL_RESTART_FILE) || (file_type == ECL_UNIFIED_RESTART_FILE))
|
if ((file_type == ECL_RESTART_FILE) || (file_type == ECL_UNIFIED_RESTART_FILE))
|
||||||
{
|
{
|
||||||
if (file_type == ECL_RESTART_FILE)
|
if (file_type == ECL_RESTART_FILE)
|
||||||
well_info_add_wells( well_info , ecl_file , report_nr , load_segment_information );
|
well_info_add_wells(well_info, ecl_file, report_nr, load_segment_information);
|
||||||
|
else
|
||||||
|
well_info_add_UNRST_wells(well_info, ecl_file, load_segment_information);
|
||||||
|
|
||||||
|
}
|
||||||
else
|
else
|
||||||
well_info_add_UNRST_wells( well_info , ecl_file , load_segment_information );
|
util_abort("%s: invalid file type: %s - must be a restart file\n", __func__, filename);
|
||||||
|
|
||||||
} else
|
|
||||||
util_abort("%s: invalid file type: %s - must be a restart file\n", __func__ , filename);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void well_info_free( well_info_type * well_info ) {
|
void well_info_free(well_info_type* well_info) {
|
||||||
for (const auto& pair : well_info->wells)
|
for (const auto& pair : well_info->wells)
|
||||||
well_ts_free(pair.second);
|
well_ts_free(pair.second);
|
||||||
|
|
||||||
delete well_info;
|
delete well_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
int well_info_get_well_size( const well_info_type * well_info , const char * well_name ) {
|
int well_info_get_well_size(const well_info_type* well_info, const char* well_name) {
|
||||||
well_ts_type * well_ts = well_info_get_ts( well_info , well_name );
|
well_ts_type* well_ts = well_info_get_ts(well_info, well_name);
|
||||||
return well_ts_get_size( well_ts );
|
return well_ts_get_size(well_ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
|
|
||||||
well_state_type * well_info_get_state_from_time( const well_info_type * well_info , const char * well_name , time_t sim_time) {
|
well_state_type* well_info_get_state_from_time(const well_info_type* well_info, const char* well_name, time_t sim_time) {
|
||||||
well_ts_type * well_ts = well_info_get_ts( well_info , well_name );
|
well_ts_type* well_ts = well_info_get_ts(well_info, well_name);
|
||||||
return well_ts_get_state_from_sim_time( well_ts , sim_time );
|
return well_ts_get_state_from_sim_time(well_ts, sim_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
well_state_type * well_info_get_state_from_report( const well_info_type * well_info , const char * well_name , int report_step ) {
|
well_state_type* well_info_get_state_from_report(const well_info_type* well_info, const char* well_name, int report_step) {
|
||||||
well_ts_type * well_ts = well_info_get_ts( well_info , well_name );
|
well_ts_type* well_ts = well_info_get_ts(well_info, well_name);
|
||||||
return well_ts_get_state_from_report( well_ts , report_step);
|
return well_ts_get_state_from_report(well_ts, report_step);
|
||||||
}
|
}
|
||||||
|
|
||||||
well_state_type * well_info_iget_state( const well_info_type * well_info , const char * well_name , int time_index) {
|
well_state_type* well_info_iget_state(const well_info_type* well_info, const char* well_name, int time_index) {
|
||||||
well_ts_type * well_ts = well_info_get_ts( well_info , well_name );
|
well_ts_type* well_ts = well_info_get_ts(well_info, well_name);
|
||||||
return well_ts_iget_state( well_ts , time_index);
|
return well_ts_iget_state(well_ts, time_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
well_state_type * well_info_iiget_state( const well_info_type * well_info , int well_index , int time_index) {
|
well_state_type* well_info_iiget_state(const well_info_type* well_info, int well_index, int time_index) {
|
||||||
const std::string& well_name = well_info->well_names[well_index];
|
const std::string& well_name = well_info->well_names[well_index];
|
||||||
return well_info_iget_state( well_info , well_name.c_str() , time_index );
|
return well_info_iget_state(well_info, well_name.c_str(), time_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
|
|
||||||
int well_info_get_num_wells( const well_info_type * well_info ) {
|
int well_info_get_num_wells(const well_info_type* well_info) {
|
||||||
return well_info->well_names.size();
|
return well_info->well_names.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * well_info_iget_well_name( const well_info_type * well_info, int well_index) {
|
const char* well_info_iget_well_name(const well_info_type* well_info, int well_index) {
|
||||||
const std::string& well_name = well_info->well_names[well_index];
|
const std::string& well_name = well_info->well_names[well_index];
|
||||||
return well_name.c_str();
|
return well_name.c_str();
|
||||||
}
|
}
|
||||||
|
804
ThirdParty/Ert/lib/ecl/well_state.cpp
vendored
804
ThirdParty/Ert/lib/ecl/well_state.cpp
vendored
@ -167,158 +167,158 @@ coupledte implementation these objects are modelled as such:
|
|||||||
#define WELL_STATE_TYPE_ID 613307832
|
#define WELL_STATE_TYPE_ID 613307832
|
||||||
|
|
||||||
struct well_state_struct {
|
struct well_state_struct {
|
||||||
UTIL_TYPE_ID_DECLARATION;
|
UTIL_TYPE_ID_DECLARATION;
|
||||||
std::string name;
|
std::string name;
|
||||||
time_t valid_from_time;
|
time_t valid_from_time;
|
||||||
int valid_from_report;
|
int valid_from_report;
|
||||||
int global_well_nr;
|
int global_well_nr;
|
||||||
bool open;
|
bool open;
|
||||||
well_type_enum type;
|
well_type_enum type;
|
||||||
bool is_MSW_well;
|
bool is_MSW_well;
|
||||||
double oil_rate;
|
double oil_rate;
|
||||||
double gas_rate;
|
double gas_rate;
|
||||||
double water_rate;
|
double water_rate;
|
||||||
double volume_rate;
|
double volume_rate;
|
||||||
ert_ecl_unit_enum unit_system;
|
ert_ecl_unit_enum unit_system;
|
||||||
|
|
||||||
std::map<std::string, well_conn_collection_type*> connections; // hash<grid_name,well_conn_collection>
|
|
||||||
well_segment_collection_type * segments;
|
|
||||||
well_branch_collection_type * branches;
|
|
||||||
|
|
||||||
/*****************************************************************/
|
std::map<std::string, well_conn_collection_type*> connections; // hash<grid_name,well_conn_collection>
|
||||||
|
well_segment_collection_type* segments;
|
||||||
std::vector<well_conn_type*> index_wellhead; // An well_conn_type instance representing the wellhead - indexed by grid_nr.
|
well_branch_collection_type* branches;
|
||||||
std::map<std::string, well_conn_type*> name_wellhead; // An well_conn_type instance representing the wellhead - indexed by lgr_name.
|
|
||||||
|
/*****************************************************************/
|
||||||
|
|
||||||
|
std::vector<well_conn_type*> index_wellhead; // An well_conn_type instance representing the wellhead - indexed by grid_nr.
|
||||||
|
std::map<std::string, well_conn_type*> name_wellhead; // An well_conn_type instance representing the wellhead - indexed by lgr_name.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UTIL_IS_INSTANCE_FUNCTION( well_state , WELL_STATE_TYPE_ID)
|
UTIL_IS_INSTANCE_FUNCTION(well_state, WELL_STATE_TYPE_ID)
|
||||||
|
|
||||||
|
|
||||||
well_state_type * well_state_alloc(const char * well_name , int global_well_nr , bool open, well_type_enum type , int report_nr, time_t valid_from) {
|
well_state_type* well_state_alloc(const char* well_name, int global_well_nr, bool open, well_type_enum type, int report_nr, time_t valid_from) {
|
||||||
well_state_type * well_state = new well_state_type();
|
well_state_type* well_state = new well_state_type();
|
||||||
UTIL_TYPE_ID_INIT( well_state , WELL_STATE_TYPE_ID );
|
UTIL_TYPE_ID_INIT(well_state, WELL_STATE_TYPE_ID);
|
||||||
|
|
||||||
well_state->name = well_name;
|
well_state->name = well_name;
|
||||||
well_state->valid_from_time = valid_from;
|
well_state->valid_from_time = valid_from;
|
||||||
well_state->valid_from_report = report_nr;
|
well_state->valid_from_report = report_nr;
|
||||||
well_state->open = open;
|
well_state->open = open;
|
||||||
well_state->type = type;
|
well_state->type = type;
|
||||||
well_state->global_well_nr = global_well_nr;
|
well_state->global_well_nr = global_well_nr;
|
||||||
well_state->segments = well_segment_collection_alloc();
|
well_state->segments = well_segment_collection_alloc();
|
||||||
well_state->branches = well_branch_collection_alloc();
|
well_state->branches = well_branch_collection_alloc();
|
||||||
well_state->is_MSW_well = false;
|
well_state->is_MSW_well = false;
|
||||||
well_state->oil_rate = 0;
|
well_state->oil_rate = 0;
|
||||||
well_state->gas_rate = 0;
|
well_state->gas_rate = 0;
|
||||||
well_state->water_rate = 0;
|
well_state->water_rate = 0;
|
||||||
well_state->volume_rate = 0;
|
well_state->volume_rate = 0;
|
||||||
well_state->unit_system = ECL_METRIC_UNITS;
|
well_state->unit_system = ECL_METRIC_UNITS;
|
||||||
|
|
||||||
/* See documentation of the 'IWEL_UNDOCUMENTED_ZERO' in well_const.h */
|
/* See documentation of the 'IWEL_UNDOCUMENTED_ZERO' in well_const.h */
|
||||||
if ((type == ECL_WELL_ZERO) && open)
|
if ((type == ECL_WELL_ZERO) && open)
|
||||||
util_abort("%s: Invalid type value for open wells.\n",__func__ );
|
util_abort("%s: Invalid type value for open wells.\n", __func__);
|
||||||
return well_state;
|
return well_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
double well_state_get_oil_rate( const well_state_type * well_state ) {
|
double well_state_get_oil_rate(const well_state_type* well_state) {
|
||||||
return well_state->oil_rate;
|
return well_state->oil_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double well_state_get_gas_rate( const well_state_type * well_state ) {
|
double well_state_get_gas_rate(const well_state_type* well_state) {
|
||||||
return well_state->gas_rate;
|
return well_state->gas_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double well_state_get_water_rate( const well_state_type * well_state) {
|
double well_state_get_water_rate(const well_state_type* well_state) {
|
||||||
return well_state->water_rate;
|
return well_state->water_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
double well_state_get_volume_rate( const well_state_type * well_state) {
|
double well_state_get_volume_rate(const well_state_type* well_state) {
|
||||||
return well_state->volume_rate;
|
return well_state->volume_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
double well_state_get_oil_rate_si( const well_state_type * well_state ) {
|
double well_state_get_oil_rate_si(const well_state_type* well_state) {
|
||||||
double conversion_factor = 1;
|
double conversion_factor = 1;
|
||||||
|
|
||||||
if (well_state->unit_system == ECL_METRIC_UNITS)
|
if (well_state->unit_system == ECL_METRIC_UNITS)
|
||||||
conversion_factor = 1.0 / ECL_UNITS_TIME_DAY;
|
conversion_factor = 1.0 / ECL_UNITS_TIME_DAY;
|
||||||
else if (well_state->unit_system == ECL_FIELD_UNITS)
|
else if (well_state->unit_system == ECL_FIELD_UNITS)
|
||||||
conversion_factor = ECL_UNITS_VOLUME_BARREL / ECL_UNITS_TIME_DAY;
|
conversion_factor = ECL_UNITS_VOLUME_BARREL / ECL_UNITS_TIME_DAY;
|
||||||
else if (well_state->unit_system == ECL_LAB_UNITS)
|
else if (well_state->unit_system == ECL_LAB_UNITS)
|
||||||
conversion_factor = ECL_UNITS_VOLUME_MILLI_LITER / ECL_UNITS_TIME_HOUR;
|
conversion_factor = ECL_UNITS_VOLUME_MILLI_LITER / ECL_UNITS_TIME_HOUR;
|
||||||
|
|
||||||
return well_state->oil_rate * conversion_factor;
|
return well_state->oil_rate * conversion_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double well_state_get_gas_rate_si( const well_state_type * well_state ) {
|
double well_state_get_gas_rate_si(const well_state_type* well_state) {
|
||||||
double conversion_factor = 1;
|
double conversion_factor = 1;
|
||||||
|
|
||||||
if (well_state->unit_system == ECL_METRIC_UNITS)
|
if (well_state->unit_system == ECL_METRIC_UNITS)
|
||||||
conversion_factor = 1.0 / ECL_UNITS_TIME_DAY;
|
conversion_factor = 1.0 / ECL_UNITS_TIME_DAY;
|
||||||
else if (well_state->unit_system == ECL_FIELD_UNITS)
|
else if (well_state->unit_system == ECL_FIELD_UNITS)
|
||||||
conversion_factor = ECL_UNITS_VOLUME_GAS_FIELD / ECL_UNITS_TIME_DAY;
|
conversion_factor = ECL_UNITS_VOLUME_GAS_FIELD / ECL_UNITS_TIME_DAY;
|
||||||
else if (well_state->unit_system == ECL_LAB_UNITS)
|
else if (well_state->unit_system == ECL_LAB_UNITS)
|
||||||
conversion_factor = ECL_UNITS_VOLUME_MILLI_LITER / ECL_UNITS_TIME_HOUR;
|
conversion_factor = ECL_UNITS_VOLUME_MILLI_LITER / ECL_UNITS_TIME_HOUR;
|
||||||
|
|
||||||
return well_state->gas_rate * conversion_factor;
|
return well_state->gas_rate * conversion_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double well_state_get_water_rate_si( const well_state_type * well_state) {
|
double well_state_get_water_rate_si(const well_state_type* well_state) {
|
||||||
double conversion_factor = 1;
|
double conversion_factor = 1;
|
||||||
|
|
||||||
if (well_state->unit_system == ECL_METRIC_UNITS)
|
if (well_state->unit_system == ECL_METRIC_UNITS)
|
||||||
conversion_factor = 1.0 / ECL_UNITS_TIME_DAY;
|
conversion_factor = 1.0 / ECL_UNITS_TIME_DAY;
|
||||||
else if (well_state->unit_system == ECL_FIELD_UNITS)
|
else if (well_state->unit_system == ECL_FIELD_UNITS)
|
||||||
conversion_factor = ECL_UNITS_VOLUME_BARREL / ECL_UNITS_TIME_DAY;
|
conversion_factor = ECL_UNITS_VOLUME_BARREL / ECL_UNITS_TIME_DAY;
|
||||||
else if (well_state->unit_system == ECL_LAB_UNITS)
|
else if (well_state->unit_system == ECL_LAB_UNITS)
|
||||||
conversion_factor = ECL_UNITS_VOLUME_MILLI_LITER / ECL_UNITS_TIME_HOUR;
|
conversion_factor = ECL_UNITS_VOLUME_MILLI_LITER / ECL_UNITS_TIME_HOUR;
|
||||||
|
|
||||||
return well_state->water_rate * conversion_factor;
|
return well_state->water_rate * conversion_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
double well_state_get_volume_rate_si( const well_state_type * well_state) {
|
double well_state_get_volume_rate_si(const well_state_type* well_state) {
|
||||||
return well_state->volume_rate;
|
return well_state->volume_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void well_state_add_wellhead( well_state_type * well_state , const ecl_rsthead_type * header , const ecl_kw_type * iwel_kw , int well_nr , const char * grid_name , int grid_nr) {
|
void well_state_add_wellhead(well_state_type* well_state, const ecl_rsthead_type* header, const ecl_kw_type* iwel_kw, int well_nr, const char* grid_name, int grid_nr) {
|
||||||
well_conn_type * wellhead = well_conn_alloc_wellhead( iwel_kw , header , well_nr );
|
well_conn_type* wellhead = well_conn_alloc_wellhead(iwel_kw, header, well_nr);
|
||||||
|
|
||||||
if (wellhead != NULL) {
|
if (wellhead != NULL) {
|
||||||
if (grid_nr >= static_cast<int>(well_state->index_wellhead.size()))
|
if (grid_nr >= static_cast<int>(well_state->index_wellhead.size()))
|
||||||
well_state->index_wellhead.resize(grid_nr+1, NULL);
|
well_state->index_wellhead.resize(grid_nr + 1, NULL);
|
||||||
well_state->index_wellhead[grid_nr] = wellhead;
|
well_state->index_wellhead[grid_nr] = wellhead;
|
||||||
well_state->name_wellhead[grid_name] = wellhead;
|
well_state->name_wellhead[grid_name] = wellhead;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool well_state_add_rates( well_state_type * well_state ,
|
static bool well_state_add_rates(well_state_type* well_state,
|
||||||
ecl_file_view_type * rst_view ,
|
ecl_file_view_type* rst_view,
|
||||||
int well_nr) {
|
int well_nr) {
|
||||||
|
|
||||||
bool has_xwel_kw = ecl_file_view_has_kw(rst_view, XWEL_KW);
|
bool has_xwel_kw = ecl_file_view_has_kw(rst_view, XWEL_KW);
|
||||||
if (has_xwel_kw) {
|
if (has_xwel_kw) {
|
||||||
const ecl_kw_type *xwel_kw = ecl_file_view_iget_named_kw(rst_view, XWEL_KW, 0);
|
const ecl_kw_type* xwel_kw = ecl_file_view_iget_named_kw(rst_view, XWEL_KW, 0);
|
||||||
ecl_rsthead_type *header = ecl_rsthead_alloc(rst_view, -1);
|
ecl_rsthead_type* header = ecl_rsthead_alloc(rst_view, -1);
|
||||||
int offset = header->nxwelz * well_nr;
|
int offset = header->nxwelz * well_nr;
|
||||||
|
|
||||||
well_state->unit_system = header->unit_system;
|
well_state->unit_system = header->unit_system;
|
||||||
well_state->oil_rate = ecl_kw_iget_double(xwel_kw, offset + XWEL_RES_ORAT_ITEM);
|
well_state->oil_rate = ecl_kw_iget_double(xwel_kw, offset + XWEL_RES_ORAT_ITEM);
|
||||||
well_state->gas_rate = ecl_kw_iget_double(xwel_kw, offset + XWEL_RES_GRAT_ITEM);
|
well_state->gas_rate = ecl_kw_iget_double(xwel_kw, offset + XWEL_RES_GRAT_ITEM);
|
||||||
well_state->water_rate = ecl_kw_iget_double(xwel_kw, offset + XWEL_RES_WRAT_ITEM);
|
well_state->water_rate = ecl_kw_iget_double(xwel_kw, offset + XWEL_RES_WRAT_ITEM);
|
||||||
well_state->volume_rate = ecl_kw_iget_double(xwel_kw, offset + XWEL_RESV_ITEM);
|
well_state->volume_rate = ecl_kw_iget_double(xwel_kw, offset + XWEL_RESV_ITEM);
|
||||||
|
|
||||||
ecl_rsthead_free(header);
|
ecl_rsthead_free(header);
|
||||||
}
|
}
|
||||||
return has_xwel_kw;
|
return has_xwel_kw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -332,69 +332,69 @@ static bool well_state_add_rates( well_state_type * well_state ,
|
|||||||
all.
|
all.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int well_state_get_lgr_well_nr( const well_state_type * well_state , const ecl_file_view_type * file_view) {
|
static int well_state_get_lgr_well_nr(const well_state_type* well_state, const ecl_file_view_type* file_view) {
|
||||||
int well_nr = -1;
|
int well_nr = -1;
|
||||||
|
|
||||||
if (ecl_file_view_has_kw( file_view , ZWEL_KW)) {
|
if (ecl_file_view_has_kw(file_view, ZWEL_KW)) {
|
||||||
ecl_rsthead_type * header = ecl_rsthead_alloc( file_view , -1);
|
ecl_rsthead_type* header = ecl_rsthead_alloc(file_view, -1);
|
||||||
const ecl_kw_type * zwel_kw = ecl_file_view_iget_named_kw( file_view , ZWEL_KW , 0 );
|
const ecl_kw_type* zwel_kw = ecl_file_view_iget_named_kw(file_view, ZWEL_KW, 0);
|
||||||
int num_wells = header->nwells;
|
int num_wells = header->nwells;
|
||||||
well_nr = 0;
|
well_nr = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
{
|
{
|
||||||
char * lgr_well_name = (char*)util_alloc_strip_copy( (const char*)ecl_kw_iget_ptr( zwel_kw , well_nr * header->nzwelz) );
|
char* lgr_well_name = (char*)util_alloc_strip_copy((const char*)ecl_kw_iget_ptr(zwel_kw, well_nr * header->nzwelz));
|
||||||
|
|
||||||
if ( well_state->name == lgr_well_name)
|
if (well_state->name == lgr_well_name)
|
||||||
found = true;
|
found = true;
|
||||||
else
|
else
|
||||||
well_nr++;
|
well_nr++;
|
||||||
|
|
||||||
free( lgr_well_name );
|
free(lgr_well_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
break;
|
break;
|
||||||
else if (well_nr == num_wells) {
|
else if (well_nr == num_wells) {
|
||||||
// The well is not in this LGR at all.
|
// The well is not in this LGR at all.
|
||||||
well_nr = -1;
|
well_nr = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
ecl_rsthead_free(header);
|
||||||
}
|
}
|
||||||
ecl_rsthead_free( header );
|
return well_nr;
|
||||||
}
|
|
||||||
return well_nr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
well_type_enum well_state_translate_ecl_type_int(int int_type) {
|
well_type_enum well_state_translate_ecl_type_int(int int_type) {
|
||||||
well_type_enum type = ECL_WELL_ZERO;
|
well_type_enum type = ECL_WELL_ZERO;
|
||||||
|
|
||||||
switch (int_type) {
|
switch (int_type) {
|
||||||
/* See documentation of the 'IWEL_UNDOCUMENTED_ZERO' in well_const.h */
|
/* See documentation of the 'IWEL_UNDOCUMENTED_ZERO' in well_const.h */
|
||||||
case(IWEL_UNDOCUMENTED_ZERO):
|
case(IWEL_UNDOCUMENTED_ZERO):
|
||||||
type = ECL_WELL_ZERO;
|
type = ECL_WELL_ZERO;
|
||||||
break;
|
break;
|
||||||
case(IWEL_PRODUCER):
|
case(IWEL_PRODUCER):
|
||||||
type = ECL_WELL_PRODUCER;
|
type = ECL_WELL_PRODUCER;
|
||||||
break;
|
break;
|
||||||
case(IWEL_OIL_INJECTOR):
|
case(IWEL_OIL_INJECTOR):
|
||||||
type = ECL_WELL_OIL_INJECTOR;
|
type = ECL_WELL_OIL_INJECTOR;
|
||||||
break;
|
break;
|
||||||
case(IWEL_GAS_INJECTOR):
|
case(IWEL_GAS_INJECTOR):
|
||||||
type = ECL_WELL_GAS_INJECTOR;
|
type = ECL_WELL_GAS_INJECTOR;
|
||||||
break;
|
break;
|
||||||
case(IWEL_WATER_INJECTOR):
|
case(IWEL_WATER_INJECTOR):
|
||||||
type = ECL_WELL_WATER_INJECTOR;
|
type = ECL_WELL_WATER_INJECTOR;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// See https://github.com/OPM/ResInsight/issues/10493
|
// See https://github.com/OPM/ResInsight/issues/10493
|
||||||
// util_abort("%s: Invalid type value %d\n",__func__ , int_type);
|
// util_abort("%s: Invalid type value %d\n",__func__ , int_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -404,215 +404,215 @@ well_type_enum well_state_translate_ecl_type_int(int int_type) {
|
|||||||
to one LGR block with the ecl_file_subselect_block() function.
|
to one LGR block with the ecl_file_subselect_block() function.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void well_state_add_connections__( well_state_type * well_state ,
|
static void well_state_add_connections__(well_state_type* well_state,
|
||||||
const ecl_file_view_type * rst_view ,
|
const ecl_file_view_type* rst_view,
|
||||||
const char * grid_name ,
|
const char* grid_name,
|
||||||
int grid_nr,
|
int grid_nr,
|
||||||
int well_nr ) {
|
int well_nr) {
|
||||||
|
|
||||||
ecl_rsthead_type * header = ecl_rsthead_alloc( rst_view , -1);
|
ecl_rsthead_type* header = ecl_rsthead_alloc(rst_view, -1);
|
||||||
const ecl_kw_type * iwel_kw = ecl_file_view_iget_named_kw( rst_view , IWEL_KW , 0);
|
const ecl_kw_type* iwel_kw = ecl_file_view_iget_named_kw(rst_view, IWEL_KW, 0);
|
||||||
|
|
||||||
|
|
||||||
well_state_add_wellhead( well_state , header , iwel_kw , well_nr , grid_name , grid_nr );
|
well_state_add_wellhead(well_state, header, iwel_kw, well_nr, grid_name, grid_nr);
|
||||||
|
|
||||||
if (ecl_file_view_has_kw(rst_view, ICON_KW)) {
|
if (ecl_file_view_has_kw(rst_view, ICON_KW)) {
|
||||||
const ecl_kw_type * icon_kw = ecl_file_view_iget_named_kw( rst_view , ICON_KW , 0);
|
const ecl_kw_type* icon_kw = ecl_file_view_iget_named_kw(rst_view, ICON_KW, 0);
|
||||||
if (!well_state_has_grid_connections( well_state , grid_name ))
|
if (!well_state_has_grid_connections(well_state, grid_name))
|
||||||
well_state->connections[grid_name] = well_conn_collection_alloc();
|
well_state->connections[grid_name] = well_conn_collection_alloc();
|
||||||
|
|
||||||
{
|
{
|
||||||
ecl_kw_type * scon_kw = NULL;
|
ecl_kw_type* scon_kw = NULL;
|
||||||
if (ecl_file_view_has_kw( rst_view , SCON_KW))
|
if (ecl_file_view_has_kw(rst_view, SCON_KW))
|
||||||
scon_kw = ecl_file_view_iget_named_kw( rst_view , SCON_KW , 0);
|
scon_kw = ecl_file_view_iget_named_kw(rst_view, SCON_KW, 0);
|
||||||
|
|
||||||
ecl_kw_type * xcon_kw = NULL;
|
ecl_kw_type* xcon_kw = NULL;
|
||||||
if (ecl_file_view_has_kw( rst_view , XCON_KW)) {
|
if (ecl_file_view_has_kw(rst_view, XCON_KW)) {
|
||||||
xcon_kw = ecl_file_view_iget_named_kw(rst_view, XCON_KW, 0);
|
xcon_kw = ecl_file_view_iget_named_kw(rst_view, XCON_KW, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
well_conn_collection_type * wellcc = well_state->connections[grid_name];
|
well_conn_collection_type* wellcc = well_state->connections[grid_name];
|
||||||
well_conn_collection_load_from_kw( wellcc , iwel_kw , icon_kw , scon_kw, xcon_kw , well_nr , header );
|
well_conn_collection_load_from_kw(wellcc, iwel_kw, icon_kw, scon_kw, xcon_kw, well_nr, header);
|
||||||
}
|
|
||||||
}
|
|
||||||
ecl_rsthead_free( header );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void well_state_add_global_connections( well_state_type * well_state ,
|
|
||||||
const ecl_file_view_type * rst_view ,
|
|
||||||
int well_nr ) {
|
|
||||||
well_state_add_connections__( well_state , rst_view , ECL_GRID_GLOBAL_GRID , 0 , well_nr );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void well_state_add_LGR_connections(well_state_type * well_state,
|
|
||||||
const ecl_grid_type * grid,
|
|
||||||
ecl_file_view_type * file_view) {
|
|
||||||
// Go through all the LGRs and add connections; both in the bulk
|
|
||||||
// grid and as wellhead.
|
|
||||||
|
|
||||||
int num_lgr = ecl_grid_get_num_lgr( grid );
|
|
||||||
for (int lgr_index = 0; lgr_index < num_lgr; lgr_index++) {
|
|
||||||
ecl_file_view_type * lgr_view = ecl_file_view_add_blockview(file_view , LGR_KW , lgr_index);
|
|
||||||
/*
|
|
||||||
Even though the grid has LGR information the restart file is not required
|
|
||||||
to have corresponding LGR information. This has for a long time been
|
|
||||||
unchecked, and there might be bugs lurking based on the incorrect
|
|
||||||
assumption that if the grid has LGR information then the corresponding LGR
|
|
||||||
information can also be found in the restart file.
|
|
||||||
*/
|
|
||||||
if (lgr_view) {
|
|
||||||
const char * grid_name = ecl_grid_iget_lgr_name( grid , lgr_index );
|
|
||||||
int well_nr = well_state_get_lgr_well_nr( well_state , lgr_view );
|
|
||||||
if (well_nr >= 0)
|
|
||||||
well_state_add_connections__( well_state , lgr_view , grid_name , lgr_index + 1, well_nr );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void well_state_add_connections( well_state_type * well_state ,
|
|
||||||
const ecl_grid_type * grid ,
|
|
||||||
ecl_file_type * rst_file , // Either an open .Xnnnn file or UNRST file restricted to one report step
|
|
||||||
int well_nr) {
|
|
||||||
|
|
||||||
well_state_add_connections2(well_state , grid , ecl_file_get_active_view( rst_file ) , well_nr );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void well_state_add_connections2( well_state_type * well_state ,
|
|
||||||
const ecl_grid_type * grid ,
|
|
||||||
ecl_file_view_type * rst_view ,
|
|
||||||
int well_nr) {
|
|
||||||
|
|
||||||
well_state_add_global_connections( well_state , rst_view , well_nr );
|
|
||||||
well_state_add_LGR_connections( well_state , grid , rst_view);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool well_state_add_MSW( well_state_type * well_state ,
|
|
||||||
ecl_file_type * rst_file ,
|
|
||||||
int well_nr,
|
|
||||||
bool load_segment_information) {
|
|
||||||
|
|
||||||
return well_state_add_MSW2( well_state , ecl_file_get_active_view(rst_file) , well_nr , load_segment_information );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool well_state_add_MSW2( well_state_type * well_state ,
|
|
||||||
ecl_file_view_type * rst_view ,
|
|
||||||
int well_nr,
|
|
||||||
bool load_segment_information) {
|
|
||||||
|
|
||||||
if (ecl_file_view_has_kw( rst_view , ISEG_KW)) {
|
|
||||||
ecl_rsthead_type * rst_head = ecl_rsthead_alloc( rst_view , -1);
|
|
||||||
const ecl_kw_type * iwel_kw = ecl_file_view_iget_named_kw( rst_view , IWEL_KW , 0);
|
|
||||||
const ecl_kw_type * iseg_kw = ecl_file_view_iget_named_kw( rst_view , ISEG_KW , 0);
|
|
||||||
well_rseg_loader_type * rseg_loader = NULL;
|
|
||||||
|
|
||||||
int segment_count;
|
|
||||||
|
|
||||||
if (ecl_file_view_has_kw( rst_view , RSEG_KW )) {
|
|
||||||
if (load_segment_information)
|
|
||||||
rseg_loader = well_rseg_loader_alloc(rst_view);
|
|
||||||
|
|
||||||
segment_count = well_segment_collection_load_from_kw( well_state->segments ,
|
|
||||||
well_nr ,
|
|
||||||
iwel_kw ,
|
|
||||||
iseg_kw ,
|
|
||||||
rseg_loader ,
|
|
||||||
rst_head,
|
|
||||||
load_segment_information ,
|
|
||||||
&well_state->is_MSW_well);
|
|
||||||
|
|
||||||
|
|
||||||
if (segment_count > 0) {
|
|
||||||
|
|
||||||
auto it = well_state->connections.begin();
|
|
||||||
while (it != well_state->connections.end()) {
|
|
||||||
well_segment_collection_add_connections( well_state->segments , it->first.c_str() , it->second );
|
|
||||||
it++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
well_segment_collection_link( well_state->segments );
|
|
||||||
well_segment_collection_add_branches( well_state->segments , well_state->branches );
|
|
||||||
}
|
|
||||||
ecl_rsthead_free( rst_head );
|
|
||||||
|
|
||||||
if (rseg_loader != NULL) {
|
|
||||||
well_rseg_loader_free(rseg_loader);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
ecl_rsthead_free(header);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool well_state_is_MSW( const well_state_type * well_state) {
|
static void well_state_add_global_connections(well_state_type* well_state,
|
||||||
return well_state->is_MSW_well;
|
const ecl_file_view_type* rst_view,
|
||||||
|
int well_nr) {
|
||||||
|
well_state_add_connections__(well_state, rst_view, ECL_GRID_GLOBAL_GRID, 0, well_nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool well_state_has_segment_data(const well_state_type * well_state){
|
static void well_state_add_LGR_connections(well_state_type* well_state,
|
||||||
if (well_segment_collection_get_size( well_state->segments ) > 0)
|
std::vector<std::string> grid_names,
|
||||||
return true;
|
ecl_file_view_type* file_view) {
|
||||||
|
// Go through all the LGRs and add connections; both in the bulk
|
||||||
|
// grid and as wellhead.
|
||||||
|
|
||||||
|
int num_lgr = (int)(grid_names.size() - 1);
|
||||||
|
for (int lgr_index = 0; lgr_index < num_lgr; lgr_index++) {
|
||||||
|
ecl_file_view_type* lgr_view = ecl_file_view_add_blockview(file_view, LGR_KW, lgr_index);
|
||||||
|
/*
|
||||||
|
Even though the grid has LGR information the restart file is not required
|
||||||
|
to have corresponding LGR information. This has for a long time been
|
||||||
|
unchecked, and there might be bugs lurking based on the incorrect
|
||||||
|
assumption that if the grid has LGR information then the corresponding LGR
|
||||||
|
information can also be found in the restart file.
|
||||||
|
*/
|
||||||
|
if (lgr_view) {
|
||||||
|
int well_nr = well_state_get_lgr_well_nr(well_state, lgr_view);
|
||||||
|
if (well_nr >= 0)
|
||||||
|
well_state_add_connections__(well_state, lgr_view, grid_names[lgr_index + 1].c_str(), lgr_index + 1, well_nr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void well_state_add_connections(well_state_type* well_state,
|
||||||
|
std::vector<std::string> grid_names,
|
||||||
|
ecl_file_type* rst_file, // Either an open .Xnnnn file or UNRST file restricted to one report step
|
||||||
|
int well_nr) {
|
||||||
|
|
||||||
|
well_state_add_connections2(well_state, grid_names, ecl_file_get_active_view(rst_file), well_nr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void well_state_add_connections2(well_state_type* well_state,
|
||||||
|
std::vector<std::string> grid_names,
|
||||||
|
ecl_file_view_type* rst_view,
|
||||||
|
int well_nr) {
|
||||||
|
|
||||||
|
well_state_add_global_connections(well_state, rst_view, well_nr);
|
||||||
|
well_state_add_LGR_connections(well_state, grid_names, rst_view);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool well_state_add_MSW(well_state_type* well_state,
|
||||||
|
ecl_file_type* rst_file,
|
||||||
|
int well_nr,
|
||||||
|
bool load_segment_information) {
|
||||||
|
|
||||||
|
return well_state_add_MSW2(well_state, ecl_file_get_active_view(rst_file), well_nr, load_segment_information);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool well_state_add_MSW2(well_state_type* well_state,
|
||||||
|
ecl_file_view_type* rst_view,
|
||||||
|
int well_nr,
|
||||||
|
bool load_segment_information) {
|
||||||
|
|
||||||
|
if (ecl_file_view_has_kw(rst_view, ISEG_KW)) {
|
||||||
|
ecl_rsthead_type* rst_head = ecl_rsthead_alloc(rst_view, -1);
|
||||||
|
const ecl_kw_type* iwel_kw = ecl_file_view_iget_named_kw(rst_view, IWEL_KW, 0);
|
||||||
|
const ecl_kw_type* iseg_kw = ecl_file_view_iget_named_kw(rst_view, ISEG_KW, 0);
|
||||||
|
well_rseg_loader_type* rseg_loader = NULL;
|
||||||
|
|
||||||
|
int segment_count;
|
||||||
|
|
||||||
|
if (ecl_file_view_has_kw(rst_view, RSEG_KW)) {
|
||||||
|
if (load_segment_information)
|
||||||
|
rseg_loader = well_rseg_loader_alloc(rst_view);
|
||||||
|
|
||||||
|
segment_count = well_segment_collection_load_from_kw(well_state->segments,
|
||||||
|
well_nr,
|
||||||
|
iwel_kw,
|
||||||
|
iseg_kw,
|
||||||
|
rseg_loader,
|
||||||
|
rst_head,
|
||||||
|
load_segment_information,
|
||||||
|
&well_state->is_MSW_well);
|
||||||
|
|
||||||
|
|
||||||
|
if (segment_count > 0) {
|
||||||
|
|
||||||
|
auto it = well_state->connections.begin();
|
||||||
|
while (it != well_state->connections.end()) {
|
||||||
|
well_segment_collection_add_connections(well_state->segments, it->first.c_str(), it->second);
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
well_segment_collection_link(well_state->segments);
|
||||||
|
well_segment_collection_add_branches(well_state->segments, well_state->branches);
|
||||||
|
}
|
||||||
|
ecl_rsthead_free(rst_head);
|
||||||
|
|
||||||
|
if (rseg_loader != NULL) {
|
||||||
|
well_rseg_loader_free(rseg_loader);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool well_state_is_MSW(const well_state_type* well_state) {
|
||||||
|
return well_state->is_MSW_well;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool well_state_has_segment_data(const well_state_type* well_state) {
|
||||||
|
if (well_segment_collection_get_size(well_state->segments) > 0)
|
||||||
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
well_state_type * well_state_alloc_from_file( ecl_file_type * ecl_file , const ecl_grid_type * grid , int report_nr , int global_well_nr ,bool load_segment_information) {
|
well_state_type* well_state_alloc_from_file(ecl_file_type* ecl_file, std::vector<std::string> grid_names, int report_nr, int global_well_nr, bool load_segment_information) {
|
||||||
return well_state_alloc_from_file2( ecl_file_get_active_view( ecl_file ) , grid , report_nr , global_well_nr , load_segment_information);
|
return well_state_alloc_from_file2(ecl_file_get_active_view(ecl_file), grid_names, report_nr, global_well_nr, load_segment_information);
|
||||||
}
|
}
|
||||||
|
|
||||||
well_state_type * well_state_alloc_from_file2( ecl_file_view_type * file_view , const ecl_grid_type * grid , int report_nr , int global_well_nr ,bool load_segment_information) {
|
well_state_type* well_state_alloc_from_file2(ecl_file_view_type* file_view, std::vector<std::string> grid_names, int report_nr, int global_well_nr, bool load_segment_information) {
|
||||||
if (ecl_file_view_has_kw( file_view , IWEL_KW)) {
|
if (ecl_file_view_has_kw(file_view, IWEL_KW)) {
|
||||||
well_state_type * well_state = NULL;
|
well_state_type* well_state = NULL;
|
||||||
ecl_rsthead_type * global_header = ecl_rsthead_alloc( file_view , -1);
|
ecl_rsthead_type* global_header = ecl_rsthead_alloc(file_view, -1);
|
||||||
const ecl_kw_type * global_iwel_kw = ecl_file_view_iget_named_kw( file_view , IWEL_KW , 0);
|
const ecl_kw_type* global_iwel_kw = ecl_file_view_iget_named_kw(file_view, IWEL_KW, 0);
|
||||||
const ecl_kw_type * global_zwel_kw = ecl_file_view_iget_named_kw( file_view , ZWEL_KW , 0);
|
const ecl_kw_type* global_zwel_kw = ecl_file_view_iget_named_kw(file_view, ZWEL_KW, 0);
|
||||||
|
|
||||||
const int iwel_offset = global_header->niwelz * global_well_nr;
|
const int iwel_offset = global_header->niwelz * global_well_nr;
|
||||||
{
|
{
|
||||||
char * name;
|
char* name;
|
||||||
bool open;
|
bool open;
|
||||||
well_type_enum type = ECL_WELL_ZERO;
|
well_type_enum type = ECL_WELL_ZERO;
|
||||||
{
|
{
|
||||||
int int_state = ecl_kw_iget_int( global_iwel_kw , iwel_offset + IWEL_STATUS_INDEX );
|
int int_state = ecl_kw_iget_int(global_iwel_kw, iwel_offset + IWEL_STATUS_INDEX);
|
||||||
if (int_state > 0)
|
if (int_state > 0)
|
||||||
open = true;
|
open = true;
|
||||||
else
|
else
|
||||||
open = false;
|
open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int int_type = ecl_kw_iget_int( global_iwel_kw , iwel_offset + IWEL_TYPE_INDEX);
|
int int_type = ecl_kw_iget_int(global_iwel_kw, iwel_offset + IWEL_TYPE_INDEX);
|
||||||
type = well_state_translate_ecl_type_int( int_type );
|
type = well_state_translate_ecl_type_int(int_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const int zwel_offset = global_header->nzwelz * global_well_nr;
|
const int zwel_offset = global_header->nzwelz * global_well_nr;
|
||||||
name = (char*)util_alloc_strip_copy((const char*)ecl_kw_iget_ptr( global_zwel_kw , zwel_offset )); // Hardwired max 8 characters in Well Name
|
name = (char*)util_alloc_strip_copy((const char*)ecl_kw_iget_ptr(global_zwel_kw, zwel_offset)); // Hardwired max 8 characters in Well Name
|
||||||
}
|
}
|
||||||
|
|
||||||
well_state = well_state_alloc(name , global_well_nr , open , type , report_nr , global_header->sim_time);
|
well_state = well_state_alloc(name, global_well_nr, open, type, report_nr, global_header->sim_time);
|
||||||
free( name );
|
free(name);
|
||||||
|
|
||||||
well_state_add_connections2( well_state , grid , file_view , global_well_nr);
|
well_state_add_connections2(well_state, grid_names, file_view, global_well_nr);
|
||||||
if (ecl_file_view_has_kw( file_view , ISEG_KW))
|
if (ecl_file_view_has_kw(file_view, ISEG_KW))
|
||||||
well_state_add_MSW2( well_state , file_view , global_well_nr , load_segment_information);
|
well_state_add_MSW2(well_state, file_view, global_well_nr, load_segment_information);
|
||||||
|
|
||||||
well_state_add_rates(well_state, file_view, global_well_nr);
|
well_state_add_rates(well_state, file_view, global_well_nr);
|
||||||
|
}
|
||||||
|
ecl_rsthead_free(global_header);
|
||||||
|
return well_state;
|
||||||
}
|
}
|
||||||
ecl_rsthead_free( global_header );
|
else
|
||||||
return well_state;
|
/* This seems a bit weird - have come over E300 restart files without the IWEL keyword. */
|
||||||
} else
|
return NULL;
|
||||||
/* This seems a bit weird - have come over E300 restart files without the IWEL keyword. */
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -621,115 +621,115 @@ well_state_type * well_state_alloc_from_file2( ecl_file_view_type * file_view ,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void well_state_free( well_state_type * well ) {
|
void well_state_free(well_state_type* well) {
|
||||||
|
|
||||||
for (size_t i = 0; i < well->index_wellhead.size(); i++) {
|
for (size_t i = 0; i < well->index_wellhead.size(); i++) {
|
||||||
if (well->index_wellhead[i])
|
if (well->index_wellhead[i])
|
||||||
well_conn_free(well->index_wellhead[i]);
|
well_conn_free(well->index_wellhead[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& pair : well->connections)
|
for (auto& pair : well->connections)
|
||||||
well_conn_collection_free(pair.second);
|
well_conn_collection_free(pair.second);
|
||||||
|
|
||||||
well_segment_collection_free( well->segments );
|
well_segment_collection_free(well->segments);
|
||||||
well_branch_collection_free( well->branches );
|
well_branch_collection_free(well->branches);
|
||||||
|
|
||||||
delete well;
|
delete well;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
|
|
||||||
int well_state_get_report_nr( const well_state_type * well_state ) {
|
int well_state_get_report_nr(const well_state_type* well_state) {
|
||||||
return well_state->valid_from_report;
|
return well_state->valid_from_report;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t well_state_get_sim_time( const well_state_type * well_state ) {
|
time_t well_state_get_sim_time(const well_state_type* well_state) {
|
||||||
return well_state->valid_from_time;
|
return well_state->valid_from_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Will return NULL if no wellhead in this grid.
|
Will return NULL if no wellhead in this grid.
|
||||||
*/
|
*/
|
||||||
const well_conn_type * well_state_iget_wellhead( const well_state_type * well_state , int grid_nr) {
|
const well_conn_type* well_state_iget_wellhead(const well_state_type* well_state, int grid_nr) {
|
||||||
if (grid_nr < static_cast<int>(well_state->index_wellhead.size()))
|
if (grid_nr < static_cast<int>(well_state->index_wellhead.size()))
|
||||||
return well_state->index_wellhead[grid_nr];
|
return well_state->index_wellhead[grid_nr];
|
||||||
else
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool well_state_has_named_well_conn(const well_state_type* well_state, const char* grid_name) {
|
||||||
|
const auto it = well_state->name_wellhead.find(grid_name);
|
||||||
|
if (it == well_state->name_wellhead.end())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const well_conn_type* well_state_get_wellhead(const well_state_type* well_state, const char* grid_name) {
|
||||||
|
const auto it = well_state->name_wellhead.find(grid_name);
|
||||||
|
if (it != well_state->name_wellhead.end())
|
||||||
|
return it->second;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const well_conn_type* well_state_get_global_wellhead(const well_state_type* well_state) {
|
||||||
bool well_state_has_named_well_conn( const well_state_type * well_state , const char * grid_name ) {
|
return well_state_get_wellhead(well_state, ECL_GRID_GLOBAL_GRID);
|
||||||
const auto it = well_state->name_wellhead.find( grid_name );
|
|
||||||
if (it == well_state->name_wellhead.end())
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const well_conn_type * well_state_get_wellhead( const well_state_type * well_state , const char * grid_name) {
|
well_type_enum well_state_get_type(const well_state_type* well_state) {
|
||||||
const auto it = well_state->name_wellhead.find( grid_name );
|
return well_state->type;
|
||||||
if (it != well_state->name_wellhead.end())
|
|
||||||
return it->second;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const well_conn_type * well_state_get_global_wellhead( const well_state_type * well_state ) {
|
bool well_state_is_open(const well_state_type* well_state) {
|
||||||
return well_state_get_wellhead( well_state, ECL_GRID_GLOBAL_GRID );
|
return well_state->open;
|
||||||
|
}
|
||||||
|
|
||||||
|
int well_state_get_well_nr(const well_state_type* well_state) {
|
||||||
|
return well_state->global_well_nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
well_type_enum well_state_get_type( const well_state_type * well_state){
|
const char* well_state_get_name(const well_state_type* well_state) {
|
||||||
return well_state->type;
|
return well_state->name.c_str();
|
||||||
}
|
|
||||||
|
|
||||||
bool well_state_is_open( const well_state_type * well_state ) {
|
|
||||||
return well_state->open;
|
|
||||||
}
|
|
||||||
|
|
||||||
int well_state_get_well_nr( const well_state_type * well_state ) {
|
|
||||||
return well_state->global_well_nr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char * well_state_get_name( const well_state_type * well_state ) {
|
|
||||||
return well_state->name.c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
|
|
||||||
const well_conn_collection_type * well_state_get_grid_connections( const well_state_type * well_state , const char * grid_name) {
|
const well_conn_collection_type* well_state_get_grid_connections(const well_state_type* well_state, const char* grid_name) {
|
||||||
if (well_state_has_grid_connections(well_state, grid_name) )
|
if (well_state_has_grid_connections(well_state, grid_name))
|
||||||
return well_state->connections.at(grid_name);
|
return well_state->connections.at(grid_name);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const well_conn_collection_type * well_state_get_global_connections( const well_state_type * well_state ) {
|
const well_conn_collection_type* well_state_get_global_connections(const well_state_type* well_state) {
|
||||||
return well_state_get_grid_connections( well_state , ECL_GRID_GLOBAL_GRID );
|
return well_state_get_grid_connections(well_state, ECL_GRID_GLOBAL_GRID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool well_state_has_grid_connections( const well_state_type * well_state , const char * grid_name) {
|
bool well_state_has_grid_connections(const well_state_type* well_state, const char* grid_name) {
|
||||||
|
|
||||||
const auto it = well_state->connections.find(grid_name);
|
const auto it = well_state->connections.find(grid_name);
|
||||||
if (it == well_state->connections.end())
|
if (it == well_state->connections.end())
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool well_state_has_global_connections( const well_state_type * well_state ) {
|
bool well_state_has_global_connections(const well_state_type* well_state) {
|
||||||
return well_state_has_grid_connections( well_state , ECL_GRID_GLOBAL_GRID );
|
return well_state_has_grid_connections(well_state, ECL_GRID_GLOBAL_GRID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
well_segment_collection_type * well_state_get_segments( const well_state_type * well_state ) {
|
well_segment_collection_type* well_state_get_segments(const well_state_type* well_state) {
|
||||||
return well_state->segments;
|
return well_state->segments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
well_branch_collection_type * well_state_get_branches( const well_state_type * well_state ) {
|
well_branch_collection_type* well_state_get_branches(const well_state_type* well_state) {
|
||||||
return well_state->branches;
|
return well_state->branches;
|
||||||
}
|
}
|
||||||
|
@ -30,26 +30,26 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct well_info_struct well_info_type;
|
typedef struct well_info_struct well_info_type;
|
||||||
|
|
||||||
well_info_type * well_info_alloc(const ecl_grid_type * grid);
|
well_info_type* well_info_alloc(std::vector<std::string> grid_names);
|
||||||
void well_info_add_UNRST_wells2( well_info_type * well_info , ecl_file_view_type * rst_view, bool load_segment_information);
|
void well_info_add_UNRST_wells2(well_info_type* well_info, ecl_file_view_type* rst_view, bool load_segment_information);
|
||||||
void well_info_add_UNRST_wells( well_info_type * well_info , ecl_file_type * rst_file, bool load_segment_information);
|
void well_info_add_UNRST_wells(well_info_type* well_info, ecl_file_type* rst_file, bool load_segment_information);
|
||||||
void well_info_add_wells( well_info_type * well_info , ecl_file_type * rst_file , int report_nr , bool load_segment_information);
|
void well_info_add_wells(well_info_type* well_info, ecl_file_type* rst_file, int report_nr, bool load_segment_information);
|
||||||
void well_info_add_wells2( well_info_type * well_info , ecl_file_view_type * rst_view , int report_nr, bool load_segment_information);
|
void well_info_add_wells2(well_info_type* well_info, ecl_file_view_type* rst_view, int report_nr, bool load_segment_information);
|
||||||
void well_info_load_rstfile( well_info_type * well_info , const char * filename, bool load_segment_information);
|
void well_info_load_rstfile(well_info_type* well_info, const char* filename, bool load_segment_information);
|
||||||
void well_info_load_rst_eclfile( well_info_type * well_info , ecl_file_type * rst_file , bool load_segment_information);
|
void well_info_load_rst_eclfile(well_info_type* well_info, ecl_file_type* rst_file, bool load_segment_information);
|
||||||
void well_info_free( well_info_type * well_info );
|
void well_info_free(well_info_type* well_info);
|
||||||
|
|
||||||
well_ts_type * well_info_get_ts( const well_info_type * well_info , const char *well_name);
|
well_ts_type* well_info_get_ts(const well_info_type* well_info, const char* well_name);
|
||||||
int well_info_get_num_wells( const well_info_type * well_info );
|
int well_info_get_num_wells(const well_info_type* well_info);
|
||||||
const char * well_info_iget_well_name( const well_info_type * well_info, int well_index);
|
const char* well_info_iget_well_name(const well_info_type* well_info, int well_index);
|
||||||
bool well_info_has_well( well_info_type * well_info , const char * well_name );
|
bool well_info_has_well(well_info_type* well_info, const char* well_name);
|
||||||
|
|
||||||
well_state_type * well_info_get_state_from_time( const well_info_type * well_info , const char * well_name , time_t sim_time);
|
well_state_type* well_info_get_state_from_time(const well_info_type* well_info, const char* well_name, time_t sim_time);
|
||||||
well_state_type * well_info_get_state_from_report( const well_info_type * well_info , const char * well_name , int report_step );
|
well_state_type* well_info_get_state_from_report(const well_info_type* well_info, const char* well_name, int report_step);
|
||||||
well_state_type * well_info_iget_state( const well_info_type * well_info , const char * well_name , int time_index);
|
well_state_type* well_info_iget_state(const well_info_type* well_info, const char* well_name, int time_index);
|
||||||
well_state_type * well_info_iiget_state( const well_info_type * well_info , int well_index , int time_index);
|
well_state_type* well_info_iiget_state(const well_info_type* well_info, int well_index, int time_index);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <ert/ecl/ecl_file.hpp>
|
#include <ert/ecl/ecl_file.hpp>
|
||||||
#include <ert/ecl/ecl_grid.hpp>
|
#include <ert/ecl/ecl_grid.hpp>
|
||||||
@ -38,72 +40,72 @@ extern "C" {
|
|||||||
|
|
||||||
#define GLOBAL_GRID_NAME "GLOBAL" // The name assigned to the global grid for name based lookup.
|
#define GLOBAL_GRID_NAME "GLOBAL" // The name assigned to the global grid for name based lookup.
|
||||||
|
|
||||||
typedef struct well_state_struct well_state_type;
|
typedef struct well_state_struct well_state_type;
|
||||||
|
|
||||||
well_state_type * well_state_alloc(const char * well_name , int global_well_nr , bool open, well_type_enum type , int report_nr, time_t valid_from);
|
well_state_type* well_state_alloc(const char* well_name, int global_well_nr, bool open, well_type_enum type, int report_nr, time_t valid_from);
|
||||||
well_state_type * well_state_alloc_from_file( ecl_file_type * ecl_file , const ecl_grid_type * grid , int report_step , int well_nr , bool load_segment_information);
|
well_state_type* well_state_alloc_from_file(ecl_file_type* ecl_file, std::vector<std::string> grid_names, int report_step, int well_nr, bool load_segment_information);
|
||||||
well_state_type * well_state_alloc_from_file2( ecl_file_view_type * file_view , const ecl_grid_type * grid , int report_nr , int global_well_nr ,bool load_segment_information);
|
well_state_type* well_state_alloc_from_file2(ecl_file_view_type* file_view, std::vector<std::string> grid_names, int report_nr, int global_well_nr, bool load_segment_information);
|
||||||
|
|
||||||
void well_state_add_connections2( well_state_type * well_state ,
|
void well_state_add_connections2(well_state_type* well_state,
|
||||||
const ecl_grid_type * grid ,
|
std::vector<std::string> grid_names,
|
||||||
ecl_file_view_type * rst_view ,
|
ecl_file_view_type* rst_view,
|
||||||
int well_nr);
|
int well_nr);
|
||||||
|
|
||||||
void well_state_add_connections( well_state_type * well_state ,
|
void well_state_add_connections(well_state_type* well_state,
|
||||||
const ecl_grid_type * grid ,
|
std::vector<std::string> grid_names,
|
||||||
ecl_file_type * rst_file ,
|
ecl_file_type* rst_file,
|
||||||
int well_nr);
|
int well_nr);
|
||||||
|
|
||||||
bool well_state_add_MSW( well_state_type * well_state ,
|
bool well_state_add_MSW(well_state_type* well_state,
|
||||||
ecl_file_type * rst_file ,
|
ecl_file_type* rst_file,
|
||||||
int well_nr,
|
int well_nr,
|
||||||
bool load_segment_information);
|
bool load_segment_information);
|
||||||
|
|
||||||
|
|
||||||
bool well_state_add_MSW2( well_state_type * well_state ,
|
bool well_state_add_MSW2(well_state_type* well_state,
|
||||||
ecl_file_view_type * rst_view,
|
ecl_file_view_type* rst_view,
|
||||||
int well_nr,
|
int well_nr,
|
||||||
bool load_segment_information);
|
bool load_segment_information);
|
||||||
|
|
||||||
|
|
||||||
bool well_state_is_MSW( const well_state_type * well_state);
|
bool well_state_is_MSW(const well_state_type* well_state);
|
||||||
|
|
||||||
bool well_state_has_segment_data(const well_state_type * well_state);
|
bool well_state_has_segment_data(const well_state_type* well_state);
|
||||||
|
|
||||||
well_segment_collection_type * well_state_get_segments( const well_state_type * well_state );
|
well_segment_collection_type* well_state_get_segments(const well_state_type* well_state);
|
||||||
well_branch_collection_type * well_state_get_branches( const well_state_type * well_state );
|
well_branch_collection_type* well_state_get_branches(const well_state_type* well_state);
|
||||||
|
|
||||||
|
|
||||||
void well_state_free( well_state_type * well );
|
void well_state_free(well_state_type* well);
|
||||||
const char * well_state_get_name( const well_state_type * well );
|
const char* well_state_get_name(const well_state_type* well);
|
||||||
int well_state_get_report_nr( const well_state_type * well_state );
|
int well_state_get_report_nr(const well_state_type* well_state);
|
||||||
time_t well_state_get_sim_time( const well_state_type * well_state );
|
time_t well_state_get_sim_time(const well_state_type* well_state);
|
||||||
well_type_enum well_state_get_type( const well_state_type * well_state);
|
well_type_enum well_state_get_type(const well_state_type* well_state);
|
||||||
bool well_state_is_open( const well_state_type * well_state );
|
bool well_state_is_open(const well_state_type* well_state);
|
||||||
int well_state_get_well_nr( const well_state_type * well_state );
|
int well_state_get_well_nr(const well_state_type* well_state);
|
||||||
|
|
||||||
const well_conn_type * well_state_get_global_wellhead( const well_state_type * well_state );
|
const well_conn_type* well_state_get_global_wellhead(const well_state_type* well_state);
|
||||||
const well_conn_type * well_state_iget_wellhead( const well_state_type * well_state , int grid_nr);
|
const well_conn_type* well_state_iget_wellhead(const well_state_type* well_state, int grid_nr);
|
||||||
const well_conn_type * well_state_get_wellhead( const well_state_type * well_state , const char * grid_name);
|
const well_conn_type* well_state_get_wellhead(const well_state_type* well_state, const char* grid_name);
|
||||||
|
|
||||||
well_type_enum well_state_translate_ecl_type_int(int int_type);
|
well_type_enum well_state_translate_ecl_type_int(int int_type);
|
||||||
|
|
||||||
const well_conn_collection_type * well_state_get_grid_connections( const well_state_type * well_state , const char * grid_name);
|
const well_conn_collection_type* well_state_get_grid_connections(const well_state_type* well_state, const char* grid_name);
|
||||||
const well_conn_collection_type * well_state_get_global_connections( const well_state_type * well_state );
|
const well_conn_collection_type* well_state_get_global_connections(const well_state_type* well_state);
|
||||||
bool well_state_has_grid_connections( const well_state_type * well_state , const char * grid_name);
|
bool well_state_has_grid_connections(const well_state_type* well_state, const char* grid_name);
|
||||||
bool well_state_has_global_connections( const well_state_type * well_state );
|
bool well_state_has_global_connections(const well_state_type* well_state);
|
||||||
|
|
||||||
double well_state_get_oil_rate( const well_state_type * well_state );
|
double well_state_get_oil_rate(const well_state_type* well_state);
|
||||||
double well_state_get_gas_rate( const well_state_type * well_state );
|
double well_state_get_gas_rate(const well_state_type* well_state);
|
||||||
double well_state_get_water_rate( const well_state_type * well_state);
|
double well_state_get_water_rate(const well_state_type* well_state);
|
||||||
double well_state_get_volume_rate( const well_state_type * well_state);
|
double well_state_get_volume_rate(const well_state_type* well_state);
|
||||||
double well_state_get_water_rate_si( const well_state_type * well_state);
|
double well_state_get_water_rate_si(const well_state_type* well_state);
|
||||||
double well_state_get_oil_rate_si( const well_state_type * well_state );
|
double well_state_get_oil_rate_si(const well_state_type* well_state);
|
||||||
double well_state_get_volume_rate_si( const well_state_type * well_state);
|
double well_state_get_volume_rate_si(const well_state_type* well_state);
|
||||||
double well_state_get_gas_rate_si( const well_state_type * well_state );
|
double well_state_get_gas_rate_si(const well_state_type* well_state);
|
||||||
|
|
||||||
|
|
||||||
UTIL_IS_INSTANCE_HEADER( well_state );
|
UTIL_IS_INSTANCE_HEADER(well_state);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
2
ThirdParty/custom-opm-common/opm-common
vendored
2
ThirdParty/custom-opm-common/opm-common
vendored
@ -1 +1 @@
|
|||||||
Subproject commit a76421efffb45ae42831a5a5a8cc7e2bddbf5b8e
|
Subproject commit ddbf77d5541eef7073d56991158aa63985309379
|
Loading…
Reference in New Issue
Block a user