2012-05-18 02:45:23 -05:00
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
# include "cvfBase.h"
# include "RigMainGrid.h"
# include "RigReservoir.h"
2012-06-26 09:10:41 -05:00
# include "RigReservoirCellResults.h"
2012-05-18 02:45:23 -05:00
2012-06-26 09:10:41 -05:00
# include "RifReaderEclipseOutput.h"
# include "RifEclipseOutputFileTools.h"
# include "RifEclipseUnifiedRestartFileAccess.h"
# include "RifEclipseRestartFilesetAccess.h"
2012-05-18 02:45:23 -05:00
# include <iostream>
# ifdef USE_ECL_LIB
# include "ecl_grid.h"
# include "well_state.h"
# endif //USE_ECL_LIB
2012-06-26 09:10:41 -05:00
# include "cafProgressInfo.h"
2012-05-18 02:45:23 -05:00
//--------------------------------------------------------------------------------------------------
/// ECLIPSE cell numbering layout:
/// Lower layer: Upper layer
///
/// 2---3 6---7
/// | | | |
/// 0---1 4---5
///
///
///
//--------------------------------------------------------------------------------------------------
// The indexing conventions for vertices in ECLIPSE
//
// 6-------------7
// /| /|
// / | / |
// / | / |
// 4-------------5 |
// | | | |
// | 2---------|---3
// | / | /
// | / | /
// |/ |/
// 0-------------1
// vertex indices
//
// The indexing conventions for vertices in ResInsight
//
// 7-------------6
// /| /|
// / | / |
// / | / |
// 4-------------5 |
// | | | |
// | 3---------|---2
// | / | /
// | / | /
// |/ |/
// 0-------------1
// vertex indices
//
static const size_t cellMappingECLRi [ 8 ] = { 0 , 1 , 3 , 2 , 4 , 5 , 7 , 6 } ;
//**************************************************************************************************
// Static functions
//**************************************************************************************************
# ifdef USE_ECL_LIB
2012-06-26 09:10:41 -05:00
bool transferGridCellData ( RigMainGrid * mainGrid , RigGridBase * localGrid , const ecl_grid_type * localEclGrid , size_t activeStartIndex )
2012-05-18 02:45:23 -05:00
{
int cellCount = ecl_grid_get_global_size ( localEclGrid ) ;
size_t cellStartIndex = mainGrid - > cells ( ) . size ( ) ;
size_t nodeStartIndex = mainGrid - > nodes ( ) . size ( ) ;
RigCell defaultCell ;
defaultCell . setHostGrid ( localGrid ) ;
mainGrid - > cells ( ) . resize ( cellStartIndex + cellCount , defaultCell ) ;
mainGrid - > nodes ( ) . resize ( nodeStartIndex + cellCount * 8 , cvf : : Vec3d ( 0 , 0 , 0 ) ) ;
2012-06-26 09:10:41 -05:00
caf : : ProgressInfo progInfo ( cellCount , " " ) ;
size_t computedCellCount = 0 ;
2012-05-18 02:45:23 -05:00
// Loop over cells and fill them with data
# pragma omp parallel for
for ( int gIdx = 0 ; gIdx < cellCount ; + + gIdx )
{
RigCell & cell = mainGrid - > cells ( ) [ cellStartIndex + gIdx ] ;
// The invalid (tainted) cell concept in ecl was not correct at all,
// so this is disabeled.
//bool invalid = ecl_grid_cell_invalid1(localEclGrid, gIdx);
//cell.setInvalid(invalid);
cell . setCellIndex ( gIdx ) ;
bool active = ecl_grid_cell_active1 ( localEclGrid , gIdx ) ;
cell . setActive ( active ) ;
cell . setGlobalActiveIndex ( active ? activeStartIndex + ecl_grid_get_active_index1 ( localEclGrid , gIdx ) : cvf : : UNDEFINED_SIZE_T ) ;
int parentCellIndex = ecl_grid_get_parent_cell1 ( localEclGrid , gIdx ) ;
if ( parentCellIndex = = - 1 )
{
cell . setParentCellIndex ( cvf : : UNDEFINED_SIZE_T ) ;
}
else
{
cell . setParentCellIndex ( parentCellIndex ) ;
}
// Corner coordinates
int cIdx ;
for ( cIdx = 0 ; cIdx < 8 ; + + cIdx )
{
double * point = mainGrid - > nodes ( ) [ nodeStartIndex + gIdx * 8 + cellMappingECLRi [ cIdx ] ] . ptr ( ) ;
ecl_grid_get_corner_xyz1 ( localEclGrid , gIdx , cIdx , & ( point [ 0 ] ) , & ( point [ 1 ] ) , & ( point [ 2 ] ) ) ;
point [ 2 ] = - point [ 2 ] ;
cell . cornerIndices ( ) [ cIdx ] = nodeStartIndex + gIdx * 8 + cIdx ;
}
// Sub grid in cell
const ecl_grid_type * subGrid = ecl_grid_get_cell_lgr1 ( localEclGrid , gIdx ) ;
if ( subGrid ! = NULL )
{
int subGridFileIndex = ecl_grid_get_grid_nr ( subGrid ) ;
CVF_ASSERT ( subGridFileIndex > 0 ) ;
cell . setSubGrid ( static_cast < RigLocalGrid * > ( mainGrid - > gridByIndex ( subGridFileIndex ) ) ) ;
}
2012-06-26 09:10:41 -05:00
# pragma omp atomic
computedCellCount + + ;
if ( computedCellCount % 5000 < 20 )
progInfo . setProgress ( computedCellCount ) ;
2012-05-18 02:45:23 -05:00
}
2012-06-26 09:10:41 -05:00
return true ;
2012-05-18 02:45:23 -05:00
}
# endif
//==================================================================================================
//
// Class RigReaderInterfaceECL
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Constructor
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
RifReaderEclipseOutput : : RifReaderEclipseOutput ( )
2012-05-18 02:45:23 -05:00
{
ground ( ) ;
}
//--------------------------------------------------------------------------------------------------
/// Destructor
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
RifReaderEclipseOutput : : ~ RifReaderEclipseOutput ( )
2012-05-18 02:45:23 -05:00
{
}
//--------------------------------------------------------------------------------------------------
/// Ground members
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
void RifReaderEclipseOutput : : ground ( )
2012-05-18 02:45:23 -05:00
{
m_fileName . clear ( ) ;
m_fileSet . clear ( ) ;
m_timeSteps . clear ( ) ;
}
//--------------------------------------------------------------------------------------------------
/// Close interface (for now, no files are kept open after calling methods, so just clear members)
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
void RifReaderEclipseOutput : : close ( )
2012-05-18 02:45:23 -05:00
{
m_staticResultsAccess = NULL ;
m_dynamicResultsAccess = NULL ;
ground ( ) ;
}
//--------------------------------------------------------------------------------------------------
/// Read geometry from file given by name into given reservoir object
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
bool RifReaderEclipseOutput : : transferGeometry ( const ecl_grid_type * mainEclGrid , RigReservoir * reservoir )
2012-05-18 02:45:23 -05:00
{
CVF_ASSERT ( reservoir ) ;
# ifdef USE_ECL_LIB
2012-06-26 09:10:41 -05:00
2012-05-18 02:45:23 -05:00
if ( ! mainEclGrid )
{
// Some error
return false ;
}
RigMainGrid * mainGrid = reservoir - > mainGrid ( ) ;
{
cvf : : Vec3st gridPointDim ( 0 , 0 , 0 ) ;
gridPointDim . x ( ) = ecl_grid_get_nx ( mainEclGrid ) + 1 ;
gridPointDim . y ( ) = ecl_grid_get_ny ( mainEclGrid ) + 1 ;
gridPointDim . z ( ) = ecl_grid_get_nz ( mainEclGrid ) + 1 ;
mainGrid - > setGridPointDimensions ( gridPointDim ) ;
}
// Get and set grid and lgr metadata
size_t totalCellCount = static_cast < size_t > ( ecl_grid_get_global_size ( mainEclGrid ) ) ;
int numLGRs = ecl_grid_get_num_lgr ( mainEclGrid ) ;
int lgrIdx ;
for ( lgrIdx = 0 ; lgrIdx < numLGRs ; + + lgrIdx )
{
ecl_grid_type * localEclGrid = ecl_grid_iget_lgr ( mainEclGrid , lgrIdx ) ;
std : : string lgrName = ecl_grid_get_name ( localEclGrid ) ;
cvf : : Vec3st gridPointDim ( 0 , 0 , 0 ) ;
gridPointDim . x ( ) = ecl_grid_get_nx ( localEclGrid ) + 1 ;
gridPointDim . y ( ) = ecl_grid_get_ny ( localEclGrid ) + 1 ;
gridPointDim . z ( ) = ecl_grid_get_nz ( localEclGrid ) + 1 ;
RigLocalGrid * localGrid = new RigLocalGrid ( mainGrid ) ;
mainGrid - > addLocalGrid ( localGrid ) ;
localGrid - > setIndexToStartOfCells ( totalCellCount ) ;
localGrid - > setGridName ( lgrName ) ;
localGrid - > setGridPointDimensions ( gridPointDim ) ;
totalCellCount + = ecl_grid_get_global_size ( localEclGrid ) ;
}
// Reserve room for the cells and nodes and fill them with data
mainGrid - > cells ( ) . reserve ( totalCellCount ) ;
mainGrid - > nodes ( ) . reserve ( 8 * totalCellCount ) ;
2012-06-26 09:10:41 -05:00
caf : : ProgressInfo progInfo ( 1 + numLGRs , " " ) ;
progInfo . setProgressDescription ( " Main Grid " ) ;
2012-05-18 02:45:23 -05:00
transferGridCellData ( mainGrid , mainGrid , mainEclGrid , 0 ) ;
2012-06-26 09:10:41 -05:00
progInfo . setProgress ( 1 ) ;
2012-05-18 02:45:23 -05:00
size_t globalActiveSize = ecl_grid_get_active_size ( mainEclGrid ) ;
for ( lgrIdx = 0 ; lgrIdx < numLGRs ; + + lgrIdx )
{
2012-06-26 09:10:41 -05:00
progInfo . setProgressDescription ( " LGR number " + QString : : number ( lgrIdx + 1 ) ) ;
2012-05-18 02:45:23 -05:00
ecl_grid_type * localEclGrid = ecl_grid_iget_lgr ( mainEclGrid , lgrIdx ) ;
transferGridCellData ( mainGrid , static_cast < RigLocalGrid * > ( mainGrid - > gridByIndex ( lgrIdx + 1 ) ) , localEclGrid , globalActiveSize ) ;
globalActiveSize + = ecl_grid_get_active_size ( localEclGrid ) ;
2012-06-26 09:10:41 -05:00
progInfo . setProgress ( 1 + lgrIdx ) ;
2012-05-18 02:45:23 -05:00
}
# endif
return true ;
}
//--------------------------------------------------------------------------------------------------
/// Open file and read geometry into given reservoir object
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
bool RifReaderEclipseOutput : : open ( const QString & fileName , RigReservoir * reservoir )
2012-05-18 02:45:23 -05:00
{
CVF_ASSERT ( reservoir ) ;
2012-06-26 09:10:41 -05:00
caf : : ProgressInfo progInfo ( 4 , " " ) ;
progInfo . setProgressDescription ( " Reading Grid " ) ;
2012-05-18 02:45:23 -05:00
// Make sure everything's closed
close ( ) ;
// Get set of files
QStringList fileSet ;
2012-06-26 09:10:41 -05:00
if ( ! RifEclipseOutputFileTools : : fileSet ( fileName , & fileSet ) ) return false ;
2012-05-18 02:45:23 -05:00
// Keep the set of files of interest
m_fileSet = fileSet ;
// Read geometry
2012-06-26 09:10:41 -05:00
# ifdef USE_ECL_LIB
ecl_grid_type * mainEclGrid = ecl_grid_alloc ( fileName . toAscii ( ) . data ( ) ) ;
progInfo . setProgress ( 1 ) ;
progInfo . setProgressDescription ( " Transferring grid geometry " ) ;
if ( ! transferGeometry ( mainEclGrid , reservoir ) ) return false ;
ecl_grid_free ( mainEclGrid ) ;
progInfo . setProgress ( 2 ) ;
progInfo . setProgressDescription ( " Reading Result index " ) ;
# endif
2012-05-18 02:45:23 -05:00
// Build results meta data
if ( ! buildMetaData ( reservoir ) ) return false ;
2012-06-26 09:10:41 -05:00
progInfo . setProgress ( 3 ) ;
progInfo . setProgressDescription ( " Reading Well information " ) ;
2012-05-18 02:45:23 -05:00
readWellCells ( reservoir ) ;
2012-06-26 09:10:41 -05:00
2012-05-18 02:45:23 -05:00
return true ;
}
//--------------------------------------------------------------------------------------------------
/// Build meta data - get states and results info
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
bool RifReaderEclipseOutput : : buildMetaData ( RigReservoir * reservoir )
2012-05-18 02:45:23 -05:00
{
# ifdef USE_ECL_LIB
CVF_ASSERT ( reservoir ) ;
CVF_ASSERT ( m_fileSet . size ( ) > 0 ) ;
2012-06-26 09:10:41 -05:00
caf : : ProgressInfo progInfo ( 2 , " " ) ;
2012-05-18 02:45:23 -05:00
// Get the number of active cells in the grid
size_t numActiveCells = reservoir - > mainGrid ( ) - > numActiveCells ( ) ;
2012-06-26 09:10:41 -05:00
size_t numGrids = reservoir - > mainGrid ( ) - > gridCount ( ) ;
2012-05-18 02:45:23 -05:00
// Create access object for dynamic results
2012-06-26 09:10:41 -05:00
m_dynamicResultsAccess = dynamicResultsAccess ( m_fileSet , numGrids , numActiveCells ) ;
RigReservoirCellResults * resCellResults = reservoir - > mainGrid ( ) - > results ( ) ;
2012-05-18 02:45:23 -05:00
if ( m_dynamicResultsAccess . notNull ( ) )
{
2012-06-26 09:10:41 -05:00
// Get time steps
2012-05-18 02:45:23 -05:00
m_timeSteps = m_dynamicResultsAccess - > timeSteps ( ) ;
// Get the names of the dynamic results
2012-06-26 09:10:41 -05:00
QStringList dynamicResultNames = m_dynamicResultsAccess - > resultNames ( ) ;
for ( size_t i = 0 ; i < static_cast < size_t > ( dynamicResultNames . size ( ) ) ; + + i )
{
size_t resIndex = resCellResults - > addEmptyScalarResult ( RimDefines : : DYNAMIC_NATIVE , dynamicResultNames [ i ] ) ;
resCellResults - > setTimeStepDates ( resIndex , m_timeSteps ) ;
}
2012-05-18 02:45:23 -05:00
}
2012-06-26 09:10:41 -05:00
progInfo . setProgress ( 1 ) ;
QString initFileName = RifEclipseOutputFileTools : : fileNameByType ( m_fileSet , ECL_INIT_FILE ) ;
2012-05-18 02:45:23 -05:00
if ( initFileName . size ( ) > 0 )
{
// Open init file
2012-06-26 09:10:41 -05:00
cvf : : ref < RifEclipseOutputFileTools > initFile = new RifEclipseOutputFileTools ;
2012-05-18 02:45:23 -05:00
if ( ! initFile - > open ( initFileName ) )
{
return false ;
}
// Get the names of the static results
QStringList staticResults ;
initFile - > keywordsOnFile ( & staticResults , numActiveCells ) ;
2012-06-26 09:10:41 -05:00
QStringList staticResultNames = staticResults ;
QList < QDateTime > staticDate ;
staticDate . push_back ( m_timeSteps . front ( ) ) ;
for ( size_t i = 0 ; i < static_cast < size_t > ( staticResultNames . size ( ) ) ; + + i )
{
size_t resIndex = resCellResults - > addEmptyScalarResult ( RimDefines : : STATIC_NATIVE , staticResultNames [ i ] ) ;
resCellResults - > setTimeStepDates ( resIndex , staticDate ) ;
}
2012-05-18 02:45:23 -05:00
m_staticResultsAccess = initFile ;
}
return true ;
# else
return false ;
# endif //USE_ECL_LIB
}
//--------------------------------------------------------------------------------------------------
/// Create results access object (.UNRST or .X0001 ... .XNNNN)
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
RifEclipseRestartDataAccess * RifReaderEclipseOutput : : dynamicResultsAccess ( const QStringList & fileSet , size_t numGrids , size_t numActiveCells )
2012-05-18 02:45:23 -05:00
{
2012-06-26 09:10:41 -05:00
RifEclipseRestartDataAccess * resultsAccess = NULL ;
2012-05-18 02:45:23 -05:00
# ifdef USE_ECL_LIB
// Look for unified restart file
2012-06-26 09:10:41 -05:00
QString unrstFileName = RifEclipseOutputFileTools : : fileNameByType ( fileSet , ECL_UNIFIED_RESTART_FILE ) ;
2012-05-18 02:45:23 -05:00
if ( unrstFileName . size ( ) > 0 )
{
2012-06-26 09:10:41 -05:00
resultsAccess = new RifEclipseUnifiedRestartFileAccess ( numGrids , numActiveCells ) ;
2012-05-18 02:45:23 -05:00
if ( ! resultsAccess - > open ( QStringList ( unrstFileName ) ) )
{
delete resultsAccess ;
return NULL ;
}
}
else
{
// Look for set of restart files (one file per time step)
2012-06-26 09:10:41 -05:00
QStringList restartFiles = RifEclipseOutputFileTools : : fileNamesByType ( fileSet , ECL_RESTART_FILE ) ;
2012-05-18 02:45:23 -05:00
if ( restartFiles . size ( ) > 0 )
{
2012-06-26 09:10:41 -05:00
resultsAccess = new RifEclipseRestartFilesetAccess ( numGrids , numActiveCells ) ;
2012-05-18 02:45:23 -05:00
if ( ! resultsAccess - > open ( restartFiles ) )
{
delete resultsAccess ;
return NULL ;
}
}
}
# endif //USE_ECL_LIB
// !! could add support for formatted result files
// !! consider priorities in case multiple types exist (.UNRST, .XNNNN, ...)
return resultsAccess ;
}
//--------------------------------------------------------------------------------------------------
/// Get all values of a given static result as doubles
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
bool RifReaderEclipseOutput : : staticResult ( const QString & result , std : : vector < double > * values )
2012-05-18 02:45:23 -05:00
{
CVF_ASSERT ( values ) ;
CVF_ASSERT ( m_staticResultsAccess . notNull ( ) ) ;
size_t numOccurrences = m_staticResultsAccess - > numOccurrences ( result ) ;
size_t i ;
for ( i = 0 ; i < numOccurrences ; i + + )
{
std : : vector < double > partValues ;
if ( ! m_staticResultsAccess - > keywordData ( result , i , & partValues ) ) return false ;
values - > insert ( values - > end ( ) , partValues . begin ( ) , partValues . end ( ) ) ;
}
return true ;
}
//--------------------------------------------------------------------------------------------------
/// Get dynamic result at given step index. Will concatenate values for the main grid and all sub grids.
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
bool RifReaderEclipseOutput : : dynamicResult ( const QString & result , size_t stepIndex , std : : vector < double > * values )
2012-05-18 02:45:23 -05:00
{
CVF_ASSERT ( m_dynamicResultsAccess . notNull ( ) ) ;
return m_dynamicResultsAccess - > results ( result , stepIndex , values ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
const QList < QDateTime > & RifReaderEclipseOutput : : timeSteps ( ) const
2012-05-18 02:45:23 -05:00
{
return m_timeSteps ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
void RifReaderEclipseOutput : : readWellCells ( RigReservoir * reservoir )
2012-05-18 02:45:23 -05:00
{
CVF_ASSERT ( reservoir ) ;
if ( m_dynamicResultsAccess . isNull ( ) ) return ;
# ifdef USE_ECL_LIB
well_info_type * ert_well_info = well_info_alloc ( NULL ) ;
if ( ! ert_well_info ) return ;
m_dynamicResultsAccess - > readWellData ( ert_well_info ) ;
RigMainGrid * mainGrid = reservoir - > mainGrid ( ) ;
std : : vector < RigGridBase * > grids ;
reservoir - > allGrids ( & grids ) ;
cvf : : Collection < RigWellResults > wells ;
int wellIdx ;
for ( wellIdx = 0 ; wellIdx < well_info_get_num_wells ( ert_well_info ) ; wellIdx + + )
{
const char * wellName = well_info_iget_well_name ( ert_well_info , wellIdx ) ;
CVF_ASSERT ( wellName ) ;
cvf : : ref < RigWellResults > wellResults = new RigWellResults ;
wellResults - > m_wellName = wellName ;
well_ts_type * ert_well_time_series = well_info_get_ts ( ert_well_info , wellName ) ;
int timeStepCount = well_ts_get_size ( ert_well_time_series ) ;
wellResults - > m_wellCellsTimeSteps . resize ( timeStepCount ) ;
int timeIdx ;
for ( timeIdx = 0 ; timeIdx < timeStepCount ; timeIdx + + )
{
well_state_type * ert_well_state = well_ts_iget_state ( ert_well_time_series , timeIdx ) ;
RigWellResultFrame & wellResFrame = wellResults - > m_wellCellsTimeSteps [ timeIdx ] ;
// Build timestamp for well
2012-06-26 09:10:41 -05:00
// Also see RifEclipseOutputFileAccess::timeStepsText for accessing time_t structures
2012-05-18 02:45:23 -05:00
{
time_t stepTime = well_state_get_sim_time ( ert_well_state ) ;
wellResFrame . m_timestamp = QDateTime : : fromTime_t ( stepTime ) ;
}
// Production type
well_type_enum ert_well_type = well_state_get_type ( ert_well_state ) ;
if ( ert_well_type = = PRODUCER )
{
wellResFrame . m_productionType = RigWellResultFrame : : PRODUCER ;
}
else if ( ert_well_type = = WATER_INJECTOR )
{
wellResFrame . m_productionType = RigWellResultFrame : : WATER_INJECTOR ;
}
else if ( ert_well_type = = GAS_INJECTOR )
{
wellResFrame . m_productionType = RigWellResultFrame : : GAS_INJECTOR ;
}
else if ( ert_well_type = = OIL_INJECTOR )
{
wellResFrame . m_productionType = RigWellResultFrame : : OIL_INJECTOR ;
}
else
{
wellResFrame . m_productionType = RigWellResultFrame : : UNDEFINED_PRODUCTION_TYPE ;
}
wellResFrame . m_isOpen = well_state_is_open ( ert_well_state ) ;
// Loop over all the grids in the model. If we have connections in one, we will discard
// the maingrid connections as they are "duplicates"
bool hasWellConnectionsInLGR = false ;
for ( size_t gridNr = 1 ; gridNr < grids . size ( ) ; + + gridNr )
{
int branchCount = well_state_iget_lgr_num_branches ( ert_well_state , gridNr ) ;
if ( branchCount > 0 )
{
hasWellConnectionsInLGR = true ;
break ;
}
}
size_t gridNr = hasWellConnectionsInLGR ? 1 : 0 ;
for ( ; gridNr < grids . size ( ) ; + + gridNr )
{
// Wellhead. If several grids have a wellhead definition for this well, we use tha last one. (Possibly the innermost LGR)
const well_conn_type * ert_wellhead = well_state_iget_wellhead ( ert_well_state , gridNr ) ;
if ( ert_wellhead )
{
wellResFrame . m_wellHead . m_gridIndex = gridNr ;
int gridK = CVF_MAX ( 0 , ert_wellhead - > k ) ; // Why this ?
wellResFrame . m_wellHead . m_gridCellIndex = grids [ gridNr ] - > cellIndexFromIJK ( ert_wellhead - > i , ert_wellhead - > j , gridK ) ;
}
int branchCount = well_state_iget_lgr_num_branches ( ert_well_state , gridNr ) ;
if ( branchCount > 0 )
{
if ( static_cast < int > ( wellResFrame . m_wellResultBranches . size ( ) ) < branchCount ) wellResFrame . m_wellResultBranches . resize ( branchCount ) ;
for ( int branchIdx = 0 ; branchIdx < branchCount ; + + branchIdx )
{
// Connections
int connectionCount = well_state_iget_num_lgr_connections ( ert_well_state , gridNr , branchIdx ) ;
if ( connectionCount > 0 )
{
RigWellResultBranch & wellSegment = wellResFrame . m_wellResultBranches [ branchIdx ] ; // Is this completely right? Is the branch index actually the same between lgrs ?
wellSegment . m_branchNumber = branchIdx ;
size_t existingConnCount = wellSegment . m_wellCells . size ( ) ;
wellSegment . m_wellCells . resize ( existingConnCount + connectionCount ) ;
int connIdx ;
for ( connIdx = 0 ; connIdx < connectionCount ; connIdx + + )
{
const well_conn_type * ert_connection = well_state_iget_lgr_connections ( ert_well_state , gridNr , branchIdx ) [ connIdx ] ;
CVF_ASSERT ( ert_connection ) ;
RigWellResultCell & data = wellSegment . m_wellCells [ existingConnCount + connIdx ] ;
data . m_gridIndex = gridNr ;
data . m_gridCellIndex = grids [ gridNr ] - > cellIndexFromIJK ( ert_connection - > i , ert_connection - > j , ert_connection - > k ) ;
2012-06-26 09:10:41 -05:00
data . m_isOpen = ert_connection - > open ;
data . m_branchId = ert_connection - > branch ;
data . m_segmentId = ert_connection - > segment ;
2012-05-18 02:45:23 -05:00
}
}
}
}
}
}
wellResults - > computeMappingFromResultTimeIndicesToWellTimeIndices ( m_timeSteps ) ;
wells . push_back ( wellResults . p ( ) ) ;
}
well_info_free ( ert_well_info ) ;
reservoir - > setWellResults ( wells ) ;
# endif
}