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:
jonjenssen 2024-06-18 13:03:48 +02:00 committed by GitHub
parent ccda815bde
commit 4365b0dfb9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 2898 additions and 2504 deletions

View File

@ -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 )
return date.startOfDay();
return date.startOfDay( timeSpec );
#else
return QDateTime( date, QTime( 0, 0 ) );
return QDateTime( date, QTime( 0, 0 ), timeSpec );
#endif
}

View File

@ -58,7 +58,7 @@ public:
static QDateTime addPeriod( 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();

View File

@ -10,6 +10,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RifPerforationIntervalReader.h
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseInput.h
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseOutput.h
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseWell.h
${CMAKE_CURRENT_LIST_DIR}/RifSummaryReaderInterface.h
${CMAKE_CURRENT_LIST_DIR}/RifEclipseUserDataParserTools.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}/RifSeismicZGYReader.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}/RifRevealSummaryCsvReader.h
${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSectionSummaryReader.h
${CMAKE_CURRENT_LIST_DIR}/RifStimPlanCsvSummaryReader.h
${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommon.h
${CMAKE_CURRENT_LIST_DIR}/RifEclipseReportKeywords.h
${CMAKE_CURRENT_LIST_DIR}/RifInpExportTools.h
${CMAKE_CURRENT_LIST_DIR}/RifFaultReactivationModelExporter.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}/RifRoffFileTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RifEclipseOutputFileTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RifEclipseRestartDataAccess.cpp
${CMAKE_CURRENT_LIST_DIR}/RifEclipseRestartFilesetAccess.cpp
${CMAKE_CURRENT_LIST_DIR}/RifEclipseUnifiedRestartFileAccess.cpp
${CMAKE_CURRENT_LIST_DIR}/RifEclipseSummaryTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RifPerforationIntervalReader.cpp
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseInput.cpp
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseOutput.cpp
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseWell.cpp
${CMAKE_CURRENT_LIST_DIR}/RifSummaryReaderInterface.cpp
${CMAKE_CURRENT_LIST_DIR}/RifEclipseUserDataParserTools.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}/RifSeismicZGYReader.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}/RifRevealCsvSummaryReader.cpp
${CMAKE_CURRENT_LIST_DIR}/RifEclipseReportKeywords.cpp
${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSectionSummaryReader.cpp
${CMAKE_CURRENT_LIST_DIR}/RifStimPlanCsvSummaryReader.cpp
${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommon.cpp

View File

@ -23,6 +23,7 @@
#include "RiaQDateTimeTools.h"
#include "RiaStringEncodingTools.h"
#include "RifEclipseReportKeywords.h"
#include "RifEclipseRestartFilesetAccess.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 );
return reportstepMetaData.keywordValueCounts();
@ -76,10 +77,11 @@ std::vector<RifKeywordValueCount> RifEclipseOutputFileTools::keywordValueCounts(
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifEclipseOutputFileTools::createResultEntries( const std::vector<RifKeywordValueCount>& fileKeywordInfo,
const std::vector<RigEclipseTimeStepInfo>& timeStepInfo,
RiaDefines::ResultCatType resultCategory,
RigEclipseCaseData* eclipseCaseData )
void RifEclipseOutputFileTools::createResultEntries( const std::vector<RifEclipseKeywordValueCount>& fileKeywordInfo,
const std::vector<RigEclipseTimeStepInfo>& timeStepInfo,
RiaDefines::ResultCatType resultCategory,
RigEclipseCaseData* eclipseCaseData,
size_t totalTimeSteps )
{
if ( !eclipseCaseData ) return;
@ -91,12 +93,17 @@ void RifEclipseOutputFileTools::createResultEntries( const std::vector<RifKeywor
eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ),
eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_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 )
{
RigEclipseResultAddress resAddr( resultCategory,
RifKeywordValueCount::mapType( keywordData.dataType() ),
RifEclipseKeywordValueCount::mapType( keywordData.dataType() ),
QString::fromStdString( keywordData.keyword() ) );
matrixModelResults->createResultEntry( resAddr, false );
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::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 )
{
RigEclipseResultAddress resAddr( resultCategory,
RifKeywordValueCount::mapType( keywordData.dataType() ),
RifEclipseKeywordValueCount::mapType( keywordData.dataType() ),
QString::fromStdString( keywordData.keyword() ) );
fractureModelResults->createResultEntry( resAddr, false );
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 );
@ -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 )
{
@ -753,18 +765,18 @@ RifRestartReportKeywords RifEclipseOutputFileTools::createReportStepsMetaData( c
continue;
}
RifKeywordValueCount::KeywordDataType dataType = RifKeywordValueCount::KeywordDataType::UNKNOWN;
auto dataType = RifEclipseKeywordValueCount::KeywordDataType::UNKNOWN;
if ( dataTypeEnumOnFile == ECL_DOUBLE_TYPE )
{
dataType = RifKeywordValueCount::KeywordDataType::DOUBLE;
dataType = RifEclipseKeywordValueCount::KeywordDataType::DOUBLE;
}
else if ( dataTypeEnumOnFile == ECL_FLOAT_TYPE )
{
dataType = RifKeywordValueCount::KeywordDataType::FLOAT;
dataType = RifEclipseKeywordValueCount::KeywordDataType::FLOAT;
}
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 );
@ -786,12 +798,12 @@ RifRestartReportKeywords RifEclipseOutputFileTools::createReportStepsMetaData( c
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RifKeywordValueCount>
RifEclipseOutputFileTools::validKeywordsForPorosityModel( const std::vector<RifKeywordValueCount>& keywordItemCounts,
const RigActiveCellInfo* matrixActiveCellInfo,
const RigActiveCellInfo* fractureActiveCellInfo,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepCount )
std::vector<RifEclipseKeywordValueCount>
RifEclipseOutputFileTools::validKeywordsForPorosityModel( const std::vector<RifEclipseKeywordValueCount>& keywordItemCounts,
const RigActiveCellInfo* matrixActiveCellInfo,
const RigActiveCellInfo* fractureActiveCellInfo,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepCount )
{
if ( !matrixActiveCellInfo ) return {};
@ -800,7 +812,7 @@ std::vector<RifKeywordValueCount>
return {};
}
std::vector<RifKeywordValueCount> keywordsWithCorrectNumberOfDataItems;
std::vector<RifEclipseKeywordValueCount> keywordsWithCorrectNumberOfDataItems;
for ( const auto& keywordValueCount : keywordItemCounts )
{
@ -809,39 +821,39 @@ std::vector<RifKeywordValueCount>
bool validKeyword = false;
size_t timeStepsAllCellsRest = valueCount % matrixActiveCellInfo->reservoirCellCount();
if ( timeStepsAllCellsRest == 0 && valueCount <= timeStepCount * matrixActiveCellInfo->reservoirCellCount() )
auto matrixActiveCellCount = matrixActiveCellInfo->reservoirActiveCellCount();
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
validKeyword = true;
}
else
{
size_t timeStepsMatrixRest = valueCount % matrixActiveCellInfo->reservoirActiveCellCount();
size_t timeStepsMatrixRest = valueCount % matrixActiveCellCount;
size_t timeStepsFractureRest = 0;
if ( fractureActiveCellInfo->reservoirActiveCellCount() > 0 )
if ( fractureActiveCellCount > 0 )
{
timeStepsFractureRest = valueCount % fractureActiveCellInfo->reservoirActiveCellCount();
timeStepsFractureRest = valueCount % fractureActiveCellCount;
}
size_t sumFractureMatrixActiveCellCount = matrixActiveCellInfo->reservoirActiveCellCount() +
fractureActiveCellInfo->reservoirActiveCellCount();
size_t timeStepsMatrixAndFractureRest = valueCount % sumFractureMatrixActiveCellCount;
size_t sumFractureMatrixActiveCellCount = matrixActiveCellCount + fractureActiveCellCount;
size_t timeStepsMatrixAndFractureRest = valueCount % sumFractureMatrixActiveCellCount;
if ( porosityModel == RiaDefines::PorosityModelType::MATRIX_MODEL && timeStepsMatrixRest == 0 )
{
if ( valueCount <=
timeStepCount * std::max( matrixActiveCellInfo->reservoirActiveCellCount(), sumFractureMatrixActiveCellCount ) )
if ( valueCount <= timeStepCount * std::max( matrixActiveCellCount, sumFractureMatrixActiveCellCount ) )
{
validKeyword = true;
}
}
else if ( porosityModel == RiaDefines::PorosityModelType::FRACTURE_MODEL &&
fractureActiveCellInfo->reservoirActiveCellCount() > 0 && timeStepsFractureRest == 0 )
else if ( porosityModel == RiaDefines::PorosityModelType::FRACTURE_MODEL && fractureActiveCellCount > 0 &&
timeStepsFractureRest == 0 )
{
if ( valueCount <=
timeStepCount * std::max( fractureActiveCellInfo->reservoirActiveCellCount(), sumFractureMatrixActiveCellCount ) )
if ( valueCount <= timeStepCount * std::max( fractureActiveCellCount, sumFractureMatrixActiveCellCount ) )
{
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
if ( !validKeyword )
{
if ( timeStepCount == 1 )
{
size_t mainGridMatrixActiveCellCount = matrixActiveCellInfo->gridActiveCellCounts( 0 );
size_t mainGridFractureActiveCellCount = fractureActiveCellInfo->gridActiveCellCounts( 0 );
size_t mainGridMatrixActiveCellCount = matrixActiveCellInfo->reservoirActiveCellCount();
size_t mainGridFractureActiveCellCount = fractureActiveCellInfo->reservoirActiveCellCount();
if ( valueCount == mainGridMatrixActiveCellCount || valueCount == mainGridFractureActiveCellCount ||
valueCount == mainGridMatrixActiveCellCount + mainGridFractureActiveCellCount )
@ -879,3 +901,57 @@ std::vector<RifKeywordValueCount>
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 );
}
}
}

View File

@ -20,8 +20,13 @@
#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 "cvfObject.h"
@ -37,6 +42,8 @@ using ecl_file_type = struct ecl_file_struct;
class RifEclipseRestartDataAccess;
class RigEclipseTimeStepInfo;
class RigActiveCellInfo;
class RigEclipseCaseData;
class QByteArray;
//==================================================================================================
@ -50,12 +57,13 @@ public:
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,
const std::vector<RigEclipseTimeStepInfo>& timeStepInfo,
RiaDefines::ResultCatType resultCategory,
RigEclipseCaseData* eclipseCaseData );
static void createResultEntries( const std::vector<RifEclipseKeywordValueCount>& fileKeywordInfo,
const std::vector<RigEclipseTimeStepInfo>& timeStepInfo,
RiaDefines::ResultCatType resultCategory,
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<int>* values );
@ -94,11 +102,19 @@ public:
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:
static RifRestartReportKeywords createReportStepsMetaData( const std::vector<ecl_file_type*>& ecl_files );
static std::vector<RifKeywordValueCount> validKeywordsForPorosityModel( const std::vector<RifKeywordValueCount>& keywordItemCounts,
const RigActiveCellInfo* activeCellInfo,
const RigActiveCellInfo* fractureActiveCellInfo,
RiaDefines::PorosityModelType matrixOrFracture,
size_t timeStepCount );
static void getDayMonthYear( const ecl_kw_type* intehead_kw, int* day, int* month, int* year );
static RifEclipseReportKeywords createReportStepsMetaData( const std::vector<ecl_file_type*>& ecl_files );
};

View File

@ -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
// it under the terms of the GNU General Public License as published by
@ -16,32 +16,20 @@
//
/////////////////////////////////////////////////////////////////////////////////
#include "RifEclipseRestartDataAccess.h"
//--------------------------------------------------------------------------------------------------
/// Constructor
//--------------------------------------------------------------------------------------------------
RifEclipseRestartDataAccess::RifEclipseRestartDataAccess()
{
}
//--------------------------------------------------------------------------------------------------
/// Destructor
//--------------------------------------------------------------------------------------------------
RifEclipseRestartDataAccess::~RifEclipseRestartDataAccess()
{
}
#include "RifEclipseReportKeywords.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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 );
if ( it == m_keywordValueCounts.end() )
{
m_keywordValueCounts[keyword] = RifKeywordValueCount( keyword, valueCount, dataType );
m_keywordValueCounts[keyword] = RifEclipseKeywordValueCount( keyword, valueCount, dataType );
}
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 )
{
@ -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 )
{
tmp.push_back( info );

View 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;
};

View File

@ -29,78 +29,9 @@
#include "ert/ecl_well/well_info.hpp"
#include "RifEclipseReportKeywords.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
@ -109,8 +40,8 @@ private:
class RifEclipseRestartDataAccess : public cvf::Object
{
public:
RifEclipseRestartDataAccess();
~RifEclipseRestartDataAccess() override;
RifEclipseRestartDataAccess(){};
~RifEclipseRestartDataAccess() override{};
virtual bool open() = 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 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 dynamicNNCResults( const ecl_grid_type* grid,

View File

@ -158,7 +158,7 @@ void RifEclipseRestartFilesetAccess::timeSteps( std::vector<QDateTime>* timeStep
//--------------------------------------------------------------------------------------------------
/// Get list of result names
//--------------------------------------------------------------------------------------------------
std::vector<RifKeywordValueCount> RifEclipseRestartFilesetAccess::keywordValueCounts()
std::vector<RifEclipseKeywordValueCount> RifEclipseRestartFilesetAccess::keywordValueCounts()
{
CVF_ASSERT( timeStepCount() > 0 );

View File

@ -46,7 +46,7 @@ public:
void timeSteps( std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart ) 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 dynamicNNCResults( const ecl_grid_type* grid,

View File

@ -214,7 +214,7 @@ void RifEclipseUnifiedRestartFileAccess::timeSteps( std::vector<QDateTime>* time
//--------------------------------------------------------------------------------------------------
/// Get list of result names
//--------------------------------------------------------------------------------------------------
std::vector<RifKeywordValueCount> RifEclipseUnifiedRestartFileAccess::keywordValueCounts()
std::vector<RifEclipseKeywordValueCount> RifEclipseUnifiedRestartFileAccess::keywordValueCounts()
{
if ( openFile() )
{

View File

@ -47,7 +47,7 @@ public:
void timeSteps( std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart ) 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 dynamicNNCResults( const ecl_grid_type* grid,

View File

@ -16,7 +16,7 @@
//
/////////////////////////////////////////////////////////////////////////////////
#include "RifOpmGridTools.h"
#include "RifOpmRadialGridTools.h"
#include "RiaLogging.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 );
@ -73,7 +73,7 @@ void RifOpmGridTools::importCoordinatesForRadialGrid( const std::string& gridFil
if ( opmMainGrid.is_radial() )
{
transferCoordinates( opmMainGrid, opmMainGrid, riMainGrid, riMainGrid );
transferCoordinatesRadial( opmMainGrid, opmMainGrid, riMainGrid, riMainGrid );
}
auto lgrNames = opmMainGrid.list_of_lgrs();
@ -88,7 +88,7 @@ void RifOpmGridTools::importCoordinatesForRadialGrid( const std::string& gridFil
auto riLgrGrid = riMainGrid->gridByIndex( i );
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
@ -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
//
//--------------------------------------------------------------------------------------------------
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();
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
if ( !hostCellGlobalIndices.empty() && ( gridDimension[0] - 1 == ijkCell[0] ) )
{
std::array<double, 8> cellRadius{};
std::array<double, 8> cellTheta{};
std::array<double, 8> cellZ{};
opmGrid.getRadialCellCorners( ijkCell, cellRadius, cellTheta, cellZ );
auto hostCellIndex = hostCellGlobalIndices[opmCellIndex];
double maxRadius = *std::max_element( cellRadius.begin(), cellRadius.end() );
// 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();
}
}
lockToHostPillars( riNode, opmMainGrid, opmGrid, ijkCell, hostCellIndex, opmCellIndex, opmNodeIndex, xCenterCoordOpm, yCenterCoordOpm );
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//
//--------------------------------------------------------------------------------------------------
void RifOpmGridTools::transferCoordinatesCartesian( Opm::EclIO::EGrid& opmMainGrid,
Opm::EclIO::EGrid& opmGrid,
RigMainGrid* riMainGrid,
RigGridBase* riGrid,
RigEclipseCaseData* caseData )
void RifOpmRadialGridTools::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 )
{
// 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();
opmGrid.load_grid_data();
auto riActiveCells = caseData->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL );
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++ )
// 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] )
{
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> opmY{};
std::array<double, 8> 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
auto riNodeStartIndex = riReservoirIndex * 8;
double closestPillarDistance = std::numeric_limits<double>::max();
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];
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 )
for ( const auto& c : candidates[pillarIndex] )
{
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>>
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 {};
@ -420,7 +291,6 @@ std::map<int, std::pair<double, double>>
if ( cellCount != riGrid->cellCount() ) return {};
// 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
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>>
RifOpmGridTools::computeSnapToCoordinates( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, int mainGridCellIndex, int lgrCellIndex )
std::vector<std::vector<cvf::Vec3d>> RifOpmRadialGridTools::computeSnapToCoordinates( Opm::EclIO::EGrid& opmMainGrid,
Opm::EclIO::EGrid& opmGrid,
int mainGridCellIndex,
int lgrCellIndex )
{
auto hostCellIndices = opmGrid.hostCellsGlobalIndex();
auto lgrIjk = opmGrid.ijk_from_global_index( lgrCellIndex );

View File

@ -39,28 +39,28 @@ class RigEclipseCaseData;
//==================================================================================================
///
//==================================================================================================
class RifOpmGridTools
class RifOpmRadialGridTools
{
public:
// 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 size_t cellCount( const std::string& gridFilePath );
static bool importGrid( const std::string& gridFilePath, RigMainGrid* mainGrid, RigEclipseCaseData* caseData );
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 void
transferCoordinatesRadial( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, RigMainGrid* riMainGrid, RigGridBase* riGrid );
static std::map<int, std::pair<double, double>>
computeXyCenterForTopOfCells( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, RigGridBase* riGrid );
static std::vector<std::vector<cvf::Vec3d>>
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

View File

@ -36,7 +36,7 @@ class RigEclipseTimeStepInfo;
class RigGridBase;
class RigMainGrid;
class QDateTime;
class RifKeywordValueCount;
class RifEclipseKeywordValueCount;
struct RigWellResultPoint;
@ -91,43 +91,33 @@ public:
private:
bool readActiveCellInfo();
void buildMetaData( ecl_grid_type* grid );
void readWellCells( const ecl_grid_type* mainEclGrid, bool importCompleteMswData );
std::string ertGridName( size_t gridNr );
RigWellResultPoint createWellResultPoint( const RigGridBase* grid, const well_conn_type* ert_connection, const char* wellName );
RigWellResultPoint createWellResultPoint( const RigGridBase* grid,
const well_conn_type* ert_connection,
const well_segment_type* segment,
const char* wellName );
void buildMetaData( ecl_grid_type* grid );
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 transferDynamicNNCData( const ecl_grid_type* mainEclGrid, RigMainGrid* mainGrid );
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();
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:
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
RigEclipseCaseData* m_eclipseCase;
RigEclipseCaseData* m_eclipseCaseData;
ecl_file_type* m_ecl_init_file; // File access to static results
mutable cvf::ref<RifEclipseRestartDataAccess> m_dynamicResultsAccess; // File access to dynamic results

File diff suppressed because it is too large Load Diff

View 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 );
};

View File

@ -51,9 +51,9 @@ bool RifReaderInterface::isNNCsEnabled()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifReaderInterface::isSkipWellData()
bool RifReaderInterface::loadWellDataEnabled()
{
return readerSettings()->skipWellData;
return !readerSettings()->skipWellData;
}
//--------------------------------------------------------------------------------------------------

View File

@ -56,7 +56,7 @@ public:
bool isImportOfCompleteMswDataEnabled();
bool isNNCsEnabled();
bool includeInactiveCellsInFaultGeometry();
bool isSkipWellData();
bool loadWellDataEnabled();
const QString faultIncludeFileAbsolutePathPrefix();
virtual bool open( const QString& fileName, RigEclipseCaseData* eclipseCase ) = 0;

File diff suppressed because it is too large Load Diff

View File

@ -21,13 +21,26 @@
#include "RifReaderInterface.h"
#include <memory>
#include <string>
#include <vector>
namespace Opm::EclIO
{
class EInit;
class ERst;
class EGrid;
} // namespace Opm::EclIO
class RigMainGrid;
class RigGridBase;
class RigEclipseCaseData;
class RigEclipseTimeStepInfo;
namespace caf
{
class ProgressInfo;
}
//==================================================================================================
//
//
@ -38,13 +51,31 @@ public:
RifReaderOpmCommon();
~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 dynamicResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector<double>* values ) override;
std::vector<QDateTime> timeStepsOnFile( QString gridFileName );
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
{
@ -55,16 +86,18 @@ private:
double simulationTimeFromStart;
};
static std::vector<TimeDataFile> readTimeSteps( std::shared_ptr<Opm::EclIO::ERst> restartFile );
static void readWellCells( std::shared_ptr<Opm::EclIO::ERst> restartFile,
RigEclipseCaseData* eclipseCase,
const std::vector<QDateTime>& timeSteps );
std::vector<TimeDataFile> readTimeSteps();
private:
std::string m_gridFileName;
std::string m_initFileName;
std::string m_restartFileName;
int m_gridUnit;
std::shared_ptr<Opm::EclIO::ERst> m_restartFile;
std::shared_ptr<Opm::EclIO::EInit> m_initFile;
RigEclipseCaseData* m_eclipseCaseData;
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;
};

View File

@ -819,14 +819,17 @@ QString RimFlowCharacteristicsPlot::curveDataAsText() const
auto storageCapacityValues = a->second.m_storageCapFlowCapCurve.first;
auto flowCapacityValues = a->second.m_storageCapFlowCapCurve.second;
if ( storageCapacityValues.size() < 2 || flowCapacityValues.size() < 2 )
{
continue;
}
bool extrapolate = false;
std::vector<double> flowCapacitySamplingValues;
for ( const auto storageCapacity : storageCapacitySamplingValues )
{
{
double flowCapacity = interpolate( storageCapacityValues, flowCapacityValues, storageCapacity, extrapolate );
flowCapacitySamplingValues.push_back( flowCapacity );
}
double flowCapacity = interpolate( storageCapacityValues, flowCapacityValues, storageCapacity, extrapolate );
flowCapacitySamplingValues.push_back( flowCapacity );
}
auto dimensionLessTimeValues = a->second.m_dimensionlessTimeSweepEfficiencyCurve.first;

View File

@ -30,6 +30,7 @@
#include "RicfCommandObject.h"
#include "RifEclipseOutputFileTools.h"
#include "RifEclipseRestartDataAccess.h"
#include "RifInputPropertyLoader.h"
#include "RifReaderEclipseOutput.h"
#include "RifReaderEclipseRft.h"
@ -109,6 +110,28 @@ bool RimEclipseResultCase::openEclipseGridFile()
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;
}
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();
cvf::ref<RifEclipseRestartDataAccess> restartDataAccess = RifEclipseOutputFileTools::createDynamicResultAccess( gridFileName() );
std::vector<QDateTime> timeSteps;
std::vector<double> daysSinceSimulationStart;
if ( restartDataAccess.notNull() )
{
std::vector<QDateTime> timeSteps;
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();
restartDataAccess->timeSteps( &timeSteps, &daysSinceSimulationStart );
}
m_timeStepFilter->setTimeStepsFromFile( timeSteps );
readerEclipseOutput->setFileDataAccess( restartDataAccess.p() );
readerEclipseOutput->setTimeStepFilter( m_timeStepFilter->filteredTimeSteps() );
readerInterface = readerEclipseOutput;
}
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() );

View File

@ -84,6 +84,7 @@ protected:
private:
void loadAndUpdateSourSimData();
void ensureRftDataIsImported();
bool showTimeStepFilterGUI();
cvf::ref<RifReaderInterface> createMockModel( QString modelName );
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;

View File

@ -625,6 +625,11 @@ RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame
return result;
}
if ( m_opmFlowDiagStaticData.isNull() )
{
return result;
}
std::vector<double> poreVolume;
for ( size_t cellIndex : selected_cell_indices )
{

View File

@ -312,6 +312,21 @@ const RigGridBase* RigMainGrid::gridByIndex( size_t localGridIndex ) const
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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -63,6 +63,7 @@ public:
RigGridBase* gridByIndex( size_t localGridIndex );
const RigGridBase* gridByIndex( size_t localGridIndex ) const;
RigGridBase* gridById( int localGridId );
RigGridBase* gridByName( const std::string& name );
size_t totalTemporaryGridCellCount() const;

View File

@ -65,8 +65,8 @@ void RigSimWellData::computeMappingFromResultTimeIndicesToWellTimeIndices( const
wellTimeStepIndex++;
}
if ( wellTimeStepIndex < m_wellCellsTimeSteps.size() &&
m_wellCellsTimeSteps[wellTimeStepIndex].timestamp() == simulationTimeSteps[resultTimeStepIndex] )
if ( ( wellTimeStepIndex < m_wellCellsTimeSteps.size() ) &&
( m_wellCellsTimeSteps[wellTimeStepIndex].timestamp() == simulationTimeSteps[resultTimeStepIndex] ) )
{
m_resultTimeStepIndexToWellTimeStepIndex[resultTimeStepIndex] = wellTimeStepIndex;
}

View File

@ -182,9 +182,9 @@
struct well_info_struct {
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. */
const ecl_grid_type * grid;
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> 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.
*/
well_info_type * well_info_alloc( const ecl_grid_type * grid) {
well_info_type * well_info = new well_info_type();
well_info->grid = grid;
return well_info;
well_info_type* well_info_alloc(const std::vector<std::string> grid_names) {
well_info_type* well_info = new well_info_type();
well_info->grid_names = grid_names;
return well_info;
}
bool well_info_has_well( well_info_type * well_info , const char * well_name ) {
const auto it = well_info->wells.find(well_name);
if (it == well_info->wells.end())
return false;
return true;
bool well_info_has_well(well_info_type* well_info, const char* well_name) {
const auto it = well_info->wells.find(well_name);
if (it == well_info->wells.end())
return false;
return true;
}
well_ts_type * well_info_get_ts( const well_info_type * well_info , const char *well_name) {
return well_info->wells.at( 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);
}
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_info->wells[well_name] = well_ts;
well_info->well_names.push_back( 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_info->wells[well_name] = well_ts;
well_info->well_names.push_back(well_name);
}
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 );
if (!well_info_has_well( well_info , well_name))
well_info_add_new_ts( well_info , well_name );
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);
if (!well_info_has_well(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_add_well( well_ts , well_state );
}
{
well_ts_type* well_ts = well_info_get_ts(well_info, well_name);
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) {
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 );
int 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 );
if (well_state != NULL)
well_info_add_state( well_info , well_state );
}
ecl_rsthead_free( global_header );
if (close_stream)
ecl_file_view_add_flag(rst_view, ECL_FILE_CLOSE_STREAM);
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);
ecl_rsthead_type* global_header = ecl_rsthead_alloc(rst_view, report_nr);
int 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_names, report_nr, well_nr, load_segment_information);
if (well_state != NULL)
well_info_add_state(well_info, well_state);
}
ecl_rsthead_free(global_header);
if (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) {
well_info_add_wells2( well_info , ecl_file_get_active_view( rst_file ) , report_nr , 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);
}
/**
@ -303,25 +303,25 @@ void well_info_add_wells( well_info_type * well_info , ecl_file_type * rst_file
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) {
int num_blocks = ecl_file_view_get_num_named_kw( rst_view , SEQNUM_KW );
int block_nr;
for (block_nr = 0; block_nr < num_blocks; block_nr++) {
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 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 );
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 );
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);
int report_nr = ecl_kw_iget_int(seqnum_kw, 0);
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 );
ecl_file_view_end_transaction(rst_view, t);
}
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);
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) {
well_info_add_UNRST_wells2( well_info , ecl_file_get_global_view( rst_file ) , 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);
}
@ -331,71 +331,72 @@ void well_info_add_UNRST_wells( well_info_type * well_info , ecl_file_type * rst
have crash and burn.
*/
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);
well_info_load_rst_eclfile(well_info, ecl_file, load_segment_information);
ecl_file_close( ecl_file );
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);
well_info_load_rst_eclfile(well_info, ecl_file, load_segment_information);
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) {
int report_nr;
const char* filename = ecl_file_get_src_file(ecl_file);
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)
well_info_add_wells( well_info , ecl_file , report_nr , 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;
const char* filename = ecl_file_get_src_file(ecl_file);
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)
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
well_info_add_UNRST_wells( well_info , ecl_file , load_segment_information );
} else
util_abort("%s: invalid file type: %s - must be a restart file\n", __func__ , filename);
util_abort("%s: invalid file type: %s - must be a restart file\n", __func__, filename);
}
void well_info_free( well_info_type * well_info ) {
for (const auto& pair : well_info->wells)
well_ts_free(pair.second);
void well_info_free(well_info_type* well_info) {
for (const auto& pair : well_info->wells)
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 ) {
well_ts_type * well_ts = well_info_get_ts( well_info , well_name );
return well_ts_get_size( well_ts );
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);
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_ts_type * well_ts = well_info_get_ts( well_info , well_name );
return well_ts_get_state_from_sim_time( well_ts , 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);
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_ts_type * well_ts = well_info_get_ts( well_info , well_name );
return well_ts_get_state_from_report( well_ts , 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);
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_ts_type * well_ts = well_info_get_ts( well_info , well_name );
return well_ts_iget_state( well_ts , 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);
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) {
const std::string& well_name = well_info->well_names[well_index];
return well_info_iget_state( well_info , well_name.c_str() , 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];
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 ) {
return well_info->well_names.size();
int well_info_get_num_wells(const well_info_type* well_info) {
return well_info->well_names.size();
}
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];
return well_name.c_str();
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];
return well_name.c_str();
}

View File

@ -167,158 +167,158 @@ coupledte implementation these objects are modelled as such:
#define WELL_STATE_TYPE_ID 613307832
struct well_state_struct {
UTIL_TYPE_ID_DECLARATION;
std::string name;
time_t valid_from_time;
int valid_from_report;
int global_well_nr;
bool open;
well_type_enum type;
bool is_MSW_well;
double oil_rate;
double gas_rate;
double water_rate;
double volume_rate;
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;
UTIL_TYPE_ID_DECLARATION;
std::string name;
time_t valid_from_time;
int valid_from_report;
int global_well_nr;
bool open;
well_type_enum type;
bool is_MSW_well;
double oil_rate;
double gas_rate;
double water_rate;
double volume_rate;
ert_ecl_unit_enum unit_system;
/*****************************************************************/
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.
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::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 = new well_state_type();
UTIL_TYPE_ID_INIT( 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 = new well_state_type();
UTIL_TYPE_ID_INIT(well_state, WELL_STATE_TYPE_ID);
well_state->name = well_name;
well_state->valid_from_time = valid_from;
well_state->valid_from_report = report_nr;
well_state->open = open;
well_state->type = type;
well_state->global_well_nr = global_well_nr;
well_state->segments = well_segment_collection_alloc();
well_state->branches = well_branch_collection_alloc();
well_state->is_MSW_well = false;
well_state->oil_rate = 0;
well_state->gas_rate = 0;
well_state->water_rate = 0;
well_state->volume_rate = 0;
well_state->unit_system = ECL_METRIC_UNITS;
well_state->name = well_name;
well_state->valid_from_time = valid_from;
well_state->valid_from_report = report_nr;
well_state->open = open;
well_state->type = type;
well_state->global_well_nr = global_well_nr;
well_state->segments = well_segment_collection_alloc();
well_state->branches = well_branch_collection_alloc();
well_state->is_MSW_well = false;
well_state->oil_rate = 0;
well_state->gas_rate = 0;
well_state->water_rate = 0;
well_state->volume_rate = 0;
well_state->unit_system = ECL_METRIC_UNITS;
/* See documentation of the 'IWEL_UNDOCUMENTED_ZERO' in well_const.h */
if ((type == ECL_WELL_ZERO) && open)
util_abort("%s: Invalid type value for open wells.\n",__func__ );
return well_state;
/* See documentation of the 'IWEL_UNDOCUMENTED_ZERO' in well_const.h */
if ((type == ECL_WELL_ZERO) && open)
util_abort("%s: Invalid type value for open wells.\n", __func__);
return well_state;
}
double well_state_get_oil_rate( const well_state_type * well_state ) {
return well_state->oil_rate;
double well_state_get_oil_rate(const well_state_type* well_state) {
return well_state->oil_rate;
}
double well_state_get_gas_rate( const well_state_type * well_state ) {
return well_state->gas_rate;
double well_state_get_gas_rate(const well_state_type* well_state) {
return well_state->gas_rate;
}
double well_state_get_water_rate( const well_state_type * well_state) {
return well_state->water_rate;
double well_state_get_water_rate(const well_state_type* well_state) {
return well_state->water_rate;
}
double well_state_get_volume_rate( const well_state_type * well_state) {
return well_state->volume_rate;
double well_state_get_volume_rate(const well_state_type* well_state) {
return well_state->volume_rate;
}
double well_state_get_oil_rate_si( const well_state_type * well_state ) {
double conversion_factor = 1;
double well_state_get_oil_rate_si(const well_state_type* well_state) {
double conversion_factor = 1;
if (well_state->unit_system == ECL_METRIC_UNITS)
conversion_factor = 1.0 / ECL_UNITS_TIME_DAY;
else if (well_state->unit_system == ECL_FIELD_UNITS)
conversion_factor = ECL_UNITS_VOLUME_BARREL / ECL_UNITS_TIME_DAY;
else if (well_state->unit_system == ECL_LAB_UNITS)
conversion_factor = ECL_UNITS_VOLUME_MILLI_LITER / ECL_UNITS_TIME_HOUR;
if (well_state->unit_system == ECL_METRIC_UNITS)
conversion_factor = 1.0 / ECL_UNITS_TIME_DAY;
else if (well_state->unit_system == ECL_FIELD_UNITS)
conversion_factor = ECL_UNITS_VOLUME_BARREL / ECL_UNITS_TIME_DAY;
else if (well_state->unit_system == ECL_LAB_UNITS)
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 conversion_factor = 1;
double well_state_get_gas_rate_si(const well_state_type* well_state) {
double conversion_factor = 1;
if (well_state->unit_system == ECL_METRIC_UNITS)
conversion_factor = 1.0 / ECL_UNITS_TIME_DAY;
else if (well_state->unit_system == ECL_FIELD_UNITS)
conversion_factor = ECL_UNITS_VOLUME_GAS_FIELD / ECL_UNITS_TIME_DAY;
else if (well_state->unit_system == ECL_LAB_UNITS)
conversion_factor = ECL_UNITS_VOLUME_MILLI_LITER / ECL_UNITS_TIME_HOUR;
if (well_state->unit_system == ECL_METRIC_UNITS)
conversion_factor = 1.0 / ECL_UNITS_TIME_DAY;
else if (well_state->unit_system == ECL_FIELD_UNITS)
conversion_factor = ECL_UNITS_VOLUME_GAS_FIELD / ECL_UNITS_TIME_DAY;
else if (well_state->unit_system == ECL_LAB_UNITS)
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 conversion_factor = 1;
double well_state_get_water_rate_si(const well_state_type* well_state) {
double conversion_factor = 1;
if (well_state->unit_system == ECL_METRIC_UNITS)
conversion_factor = 1.0 / ECL_UNITS_TIME_DAY;
else if (well_state->unit_system == ECL_FIELD_UNITS)
conversion_factor = ECL_UNITS_VOLUME_BARREL / ECL_UNITS_TIME_DAY;
else if (well_state->unit_system == ECL_LAB_UNITS)
conversion_factor = ECL_UNITS_VOLUME_MILLI_LITER / ECL_UNITS_TIME_HOUR;
if (well_state->unit_system == ECL_METRIC_UNITS)
conversion_factor = 1.0 / ECL_UNITS_TIME_DAY;
else if (well_state->unit_system == ECL_FIELD_UNITS)
conversion_factor = ECL_UNITS_VOLUME_BARREL / ECL_UNITS_TIME_DAY;
else if (well_state->unit_system == ECL_LAB_UNITS)
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) {
return well_state->volume_rate;
double well_state_get_volume_rate_si(const well_state_type* well_state) {
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) {
well_conn_type * wellhead = well_conn_alloc_wellhead( iwel_kw , header , well_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);
if (wellhead != NULL) {
if (grid_nr >= static_cast<int>(well_state->index_wellhead.size()))
well_state->index_wellhead.resize(grid_nr+1, NULL);
well_state->index_wellhead[grid_nr] = wellhead;
well_state->name_wellhead[grid_name] = wellhead;
}
if (wellhead != NULL) {
if (grid_nr >= static_cast<int>(well_state->index_wellhead.size()))
well_state->index_wellhead.resize(grid_nr + 1, NULL);
well_state->index_wellhead[grid_nr] = wellhead;
well_state->name_wellhead[grid_name] = wellhead;
}
}
static bool well_state_add_rates( well_state_type * well_state ,
ecl_file_view_type * rst_view ,
int well_nr) {
static bool well_state_add_rates(well_state_type* well_state,
ecl_file_view_type* rst_view,
int well_nr) {
bool has_xwel_kw = ecl_file_view_has_kw(rst_view, XWEL_KW);
if (has_xwel_kw) {
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);
int offset = header->nxwelz * well_nr;
bool has_xwel_kw = ecl_file_view_has_kw(rst_view, XWEL_KW);
if (has_xwel_kw) {
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);
int offset = header->nxwelz * well_nr;
well_state->unit_system = header->unit_system;
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->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->unit_system = header->unit_system;
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->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);
ecl_rsthead_free(header);
}
return has_xwel_kw;
ecl_rsthead_free(header);
}
return has_xwel_kw;
}
@ -332,69 +332,69 @@ static bool well_state_add_rates( well_state_type * well_state ,
all.
*/
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;
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;
if (ecl_file_view_has_kw( file_view , ZWEL_KW)) {
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 );
int num_wells = header->nwells;
well_nr = 0;
while (true) {
bool found = false;
{
char * lgr_well_name = (char*)util_alloc_strip_copy( (const char*)ecl_kw_iget_ptr( zwel_kw , well_nr * header->nzwelz) );
if (ecl_file_view_has_kw(file_view, ZWEL_KW)) {
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);
int num_wells = header->nwells;
well_nr = 0;
while (true) {
bool found = false;
{
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)
found = true;
else
well_nr++;
if (well_state->name == lgr_well_name)
found = true;
else
well_nr++;
free( lgr_well_name );
}
free(lgr_well_name);
}
if (found)
break;
else if (well_nr == num_wells) {
// The well is not in this LGR at all.
well_nr = -1;
break;
}
if (found)
break;
else if (well_nr == num_wells) {
// The well is not in this LGR at all.
well_nr = -1;
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 type = ECL_WELL_ZERO;
well_type_enum type = ECL_WELL_ZERO;
switch (int_type) {
/* See documentation of the 'IWEL_UNDOCUMENTED_ZERO' in well_const.h */
case(IWEL_UNDOCUMENTED_ZERO):
type = ECL_WELL_ZERO;
break;
case(IWEL_PRODUCER):
type = ECL_WELL_PRODUCER;
break;
case(IWEL_OIL_INJECTOR):
type = ECL_WELL_OIL_INJECTOR;
break;
case(IWEL_GAS_INJECTOR):
type = ECL_WELL_GAS_INJECTOR;
break;
case(IWEL_WATER_INJECTOR):
type = ECL_WELL_WATER_INJECTOR;
break;
default:
// See https://github.com/OPM/ResInsight/issues/10493
// util_abort("%s: Invalid type value %d\n",__func__ , int_type);
break;
}
return type;
switch (int_type) {
/* See documentation of the 'IWEL_UNDOCUMENTED_ZERO' in well_const.h */
case(IWEL_UNDOCUMENTED_ZERO):
type = ECL_WELL_ZERO;
break;
case(IWEL_PRODUCER):
type = ECL_WELL_PRODUCER;
break;
case(IWEL_OIL_INJECTOR):
type = ECL_WELL_OIL_INJECTOR;
break;
case(IWEL_GAS_INJECTOR):
type = ECL_WELL_GAS_INJECTOR;
break;
case(IWEL_WATER_INJECTOR):
type = ECL_WELL_WATER_INJECTOR;
break;
default:
// See https://github.com/OPM/ResInsight/issues/10493
// util_abort("%s: Invalid type value %d\n",__func__ , int_type);
break;
}
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.
*/
static void well_state_add_connections__( well_state_type * well_state ,
const ecl_file_view_type * rst_view ,
const char * grid_name ,
int grid_nr,
int well_nr ) {
static void well_state_add_connections__(well_state_type* well_state,
const ecl_file_view_type* rst_view,
const char* grid_name,
int grid_nr,
int well_nr) {
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);
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);
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)) {
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 ))
well_state->connections[grid_name] = well_conn_collection_alloc();
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);
if (!well_state_has_grid_connections(well_state, grid_name))
well_state->connections[grid_name] = well_conn_collection_alloc();
{
ecl_kw_type * scon_kw = NULL;
if (ecl_file_view_has_kw( rst_view , SCON_KW))
scon_kw = ecl_file_view_iget_named_kw( rst_view , SCON_KW , 0);
{
ecl_kw_type* scon_kw = NULL;
if (ecl_file_view_has_kw(rst_view, SCON_KW))
scon_kw = ecl_file_view_iget_named_kw(rst_view, SCON_KW, 0);
ecl_kw_type * xcon_kw = NULL;
if (ecl_file_view_has_kw( rst_view , XCON_KW)) {
xcon_kw = ecl_file_view_iget_named_kw(rst_view, XCON_KW, 0);
}
ecl_kw_type* xcon_kw = NULL;
if (ecl_file_view_has_kw(rst_view, XCON_KW)) {
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_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_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_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;
ecl_rsthead_free(header);
}
bool well_state_is_MSW( const well_state_type * well_state) {
return well_state->is_MSW_well;
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);
}
bool well_state_has_segment_data(const well_state_type * well_state){
if (well_segment_collection_get_size( well_state->segments ) > 0)
return true;
static void well_state_add_LGR_connections(well_state_type* well_state,
std::vector<std::string> grid_names,
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
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) {
return well_state_alloc_from_file2( ecl_file_get_active_view( ecl_file ) , grid , report_nr , global_well_nr , 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_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) {
if (ecl_file_view_has_kw( file_view , IWEL_KW)) {
well_state_type * well_state = NULL;
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_zwel_kw = ecl_file_view_iget_named_kw( file_view , ZWEL_KW , 0);
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)) {
well_state_type* well_state = NULL;
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_zwel_kw = ecl_file_view_iget_named_kw(file_view, ZWEL_KW, 0);
const int iwel_offset = global_header->niwelz * global_well_nr;
{
char * name;
bool open;
well_type_enum type = ECL_WELL_ZERO;
{
int int_state = ecl_kw_iget_int( global_iwel_kw , iwel_offset + IWEL_STATUS_INDEX );
if (int_state > 0)
open = true;
else
open = false;
}
const int iwel_offset = global_header->niwelz * global_well_nr;
{
char* name;
bool open;
well_type_enum type = ECL_WELL_ZERO;
{
int int_state = ecl_kw_iget_int(global_iwel_kw, iwel_offset + IWEL_STATUS_INDEX);
if (int_state > 0)
open = true;
else
open = false;
}
{
int int_type = ecl_kw_iget_int( global_iwel_kw , iwel_offset + IWEL_TYPE_INDEX);
type = well_state_translate_ecl_type_int( int_type );
}
{
int int_type = ecl_kw_iget_int(global_iwel_kw, iwel_offset + IWEL_TYPE_INDEX);
type = well_state_translate_ecl_type_int(int_type);
}
{
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
}
{
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
}
well_state = well_state_alloc(name , global_well_nr , open , type , report_nr , global_header->sim_time);
free( name );
well_state = well_state_alloc(name, global_well_nr, open, type, report_nr, global_header->sim_time);
free(name);
well_state_add_connections2( well_state , grid , file_view , global_well_nr);
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_connections2(well_state, grid_names, file_view, global_well_nr);
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_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 );
return well_state;
} else
/* This seems a bit weird - have come over E300 restart files without the IWEL keyword. */
return NULL;
else
/* 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++) {
if (well->index_wellhead[i])
well_conn_free(well->index_wellhead[i]);
}
for (size_t i = 0; i < well->index_wellhead.size(); i++) {
if (well->index_wellhead[i])
well_conn_free(well->index_wellhead[i]);
}
for (auto& pair : well->connections)
well_conn_collection_free(pair.second);
for (auto& pair : well->connections)
well_conn_collection_free(pair.second);
well_segment_collection_free( well->segments );
well_branch_collection_free( well->branches );
well_segment_collection_free(well->segments);
well_branch_collection_free(well->branches);
delete well;
delete well;
}
/*****************************************************************/
int well_state_get_report_nr( const well_state_type * well_state ) {
return well_state->valid_from_report;
int well_state_get_report_nr(const well_state_type* well_state) {
return well_state->valid_from_report;
}
time_t well_state_get_sim_time( const well_state_type * well_state ) {
return well_state->valid_from_time;
time_t well_state_get_sim_time(const well_state_type* well_state) {
return well_state->valid_from_time;
}
/**
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) {
if (grid_nr < static_cast<int>(well_state->index_wellhead.size()))
return well_state->index_wellhead[grid_nr];
else
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()))
return well_state->index_wellhead[grid_nr];
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;
}
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_global_wellhead(const well_state_type* well_state) {
return well_state_get_wellhead(well_state, ECL_GRID_GLOBAL_GRID);
}
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;
well_type_enum well_state_get_type(const well_state_type* well_state) {
return well_state->type;
}
const well_conn_type * well_state_get_global_wellhead( const well_state_type * well_state ) {
return well_state_get_wellhead( well_state, ECL_GRID_GLOBAL_GRID );
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;
}
well_type_enum well_state_get_type( const well_state_type * well_state){
return well_state->type;
}
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 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) {
if (well_state_has_grid_connections(well_state, grid_name) )
return well_state->connections.at(grid_name);
else
return NULL;
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))
return well_state->connections.at(grid_name);
else
return NULL;
}
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 );
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);
}
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);
if (it == well_state->connections.end())
return false;
return true;
const auto it = well_state->connections.find(grid_name);
if (it == well_state->connections.end())
return false;
return true;
}
bool well_state_has_global_connections( const well_state_type * well_state ) {
return well_state_has_grid_connections( well_state , ECL_GRID_GLOBAL_GRID );
bool well_state_has_global_connections(const well_state_type* well_state) {
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 ) {
return well_state->segments;
well_segment_collection_type* well_state_get_segments(const well_state_type* well_state) {
return well_state->segments;
}
well_branch_collection_type * well_state_get_branches( const well_state_type * well_state ) {
return well_state->branches;
well_branch_collection_type* well_state_get_branches(const well_state_type* well_state) {
return well_state->branches;
}

View File

@ -30,26 +30,26 @@
extern "C" {
#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);
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_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_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_free( well_info_type * well_info );
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_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_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_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);
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 );
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 );
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);
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);
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_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_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_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);
#ifdef __cplusplus
}

View File

@ -22,6 +22,8 @@
#include <time.h>
#include <vector>
#include <string>
#include <ert/ecl/ecl_file.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.
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_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_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(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, 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, 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 ,
const ecl_grid_type * grid ,
ecl_file_view_type * rst_view ,
int 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);
void well_state_add_connections( well_state_type * well_state ,
const ecl_grid_type * grid ,
ecl_file_type * rst_file ,
int well_nr);
void well_state_add_connections(well_state_type* well_state,
std::vector<std::string> grid_names,
ecl_file_type* rst_file,
int well_nr);
bool well_state_add_MSW( well_state_type * well_state ,
ecl_file_type * rst_file ,
int well_nr,
bool load_segment_information);
bool well_state_add_MSW(well_state_type* well_state,
ecl_file_type* rst_file,
int well_nr,
bool 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);
bool well_state_add_MSW2(well_state_type* well_state,
ecl_file_view_type* rst_view,
int well_nr,
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_branch_collection_type * well_state_get_branches( 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);
void well_state_free( 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 );
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);
bool well_state_is_open( const well_state_type * well_state );
int well_state_get_well_nr( const well_state_type * well_state );
void well_state_free(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);
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);
bool well_state_is_open(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_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_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_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_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_global_connections( const well_state_type * well_state );
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);
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);
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_water_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_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_gas_rate_si( 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_water_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_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_gas_rate_si(const well_state_type* well_state);
UTIL_IS_INSTANCE_HEADER( well_state );
UTIL_IS_INSTANCE_HEADER(well_state);
#ifdef __cplusplus
}

@ -1 +1 @@
Subproject commit a76421efffb45ae42831a5a5a8cc7e2bddbf5b8e
Subproject commit ddbf77d5541eef7073d56991158aa63985309379