2012-05-18 09:45:23 +02: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"
2013-02-13 13:33:35 +01:00
#include "RigEclipseCase.h"
2012-06-26 16:10:41 +02:00
#include "RigReservoirCellResults.h"
2012-05-18 09:45:23 +02:00
2012-06-26 16:10:41 +02:00
#include "RifReaderEclipseOutput.h"
#include "RifEclipseOutputFileTools.h"
#include "RifEclipseUnifiedRestartFileAccess.h"
#include "RifEclipseRestartFilesetAccess.h"
2013-02-01 14:39:32 +01:00
#include "RifReaderInterface.h"
2012-05-18 09:45:23 +02:00
#include <iostream>
#include "ecl_grid.h"
#include "well_state.h"
2013-02-27 11:27:02 +01:00
#include "ecl_kw_magic.h"
2012-06-26 16:10:41 +02:00
#include "cafProgressInfo.h"
2012-05-18 09:45:23 +02: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
//
2013-01-30 15:02:28 +01:00
// 7-------------6 |k
// /| /| | /j
// / | / | |/
// / | / | *---i
2012-05-18 09:45:23 +02:00
// 4-------------5 |
// | | | |
// | 3---------|---2
// | / | /
// | / | /
// |/ |/
// 0-------------1
// vertex indices
//
static const size_t cellMappingECLRi [ 8 ] = { 0 , 1 , 3 , 2 , 4 , 5 , 7 , 6 };
//**************************************************************************************************
// Static functions
//**************************************************************************************************
2013-03-13 11:50:31 +01:00
bool transferGridCellData ( RigMainGrid * mainGrid , RigActiveCellInfo * activeCellInfo , RigActiveCellInfo * fractureActiveCellInfo , RigGridBase * localGrid , const ecl_grid_type * localEclGrid , size_t matrixActiveStartIndex , size_t fractureActiveStartIndex )
2012-05-18 09:45:23 +02:00
{
2013-03-13 11:50:31 +01:00
CVF_ASSERT ( activeCellInfo && fractureActiveCellInfo );
2013-02-12 11:15:36 +01:00
2012-05-18 09:45:23 +02: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-09-11 09:22:36 +02:00
int progTicks = 100 ;
double cellsPrProgressTick = cellCount / ( float ) progTicks ;
caf :: ProgressInfo progInfo ( progTicks , "" );
2012-06-26 16:10:41 +02:00
size_t computedCellCount = 0 ;
2012-05-18 09:45:23 +02:00
// Loop over cells and fill them with data
2012-09-11 09:22:36 +02:00
#pragma omp parallel for
2013-02-12 11:15:36 +01:00
for ( int localCellIdx = 0 ; localCellIdx < cellCount ; ++ localCellIdx )
2012-05-18 09:45:23 +02:00
{
2013-02-12 11:15:36 +01:00
RigCell & cell = mainGrid -> cells ()[ cellStartIndex + localCellIdx ];
2012-05-18 09:45:23 +02:00
2013-02-12 11:15:36 +01:00
bool invalid = ecl_grid_cell_invalid1 ( localEclGrid , localCellIdx );
2013-01-30 15:02:28 +01:00
cell . setInvalid ( invalid );
2013-02-12 11:15:36 +01:00
cell . setCellIndex ( localCellIdx );
2013-01-30 15:02:28 +01:00
2013-02-01 15:33:21 +01:00
// Active cell index
2013-02-12 11:15:36 +01:00
int matrixActiveIndex = ecl_grid_get_active_index1 ( localEclGrid , localCellIdx );
2013-01-30 15:02:28 +01:00
if ( matrixActiveIndex != - 1 )
{
2013-02-12 14:46:45 +01:00
activeCellInfo -> setActiveIndexInMatrixModel ( cellStartIndex + localCellIdx , matrixActiveStartIndex + matrixActiveIndex );
2013-01-30 15:02:28 +01:00
}
2013-01-30 09:30:48 +01:00
2013-02-12 11:15:36 +01:00
int fractureActiveIndex = ecl_grid_get_active_fracture_index1 ( localEclGrid , localCellIdx );
2013-01-30 15:02:28 +01:00
if ( fractureActiveIndex != - 1 )
2013-01-30 09:30:48 +01:00
{
2013-03-13 11:50:31 +01:00
fractureActiveCellInfo -> setActiveIndexInMatrixModel ( cellStartIndex + localCellIdx , fractureActiveStartIndex + fractureActiveIndex );
2013-01-30 15:02:28 +01:00
}
2012-05-18 09:45:23 +02:00
2013-02-01 15:33:21 +01:00
// Parent cell index
2013-02-12 11:15:36 +01:00
int parentCellIndex = ecl_grid_get_parent_cell1 ( localEclGrid , localCellIdx );
2012-05-18 09:45:23 +02:00
if ( parentCellIndex == - 1 )
{
cell . setParentCellIndex ( cvf :: UNDEFINED_SIZE_T );
}
else
{
cell . setParentCellIndex ( parentCellIndex );
}
2013-02-01 15:33:21 +01:00
// Coarse cell info
2013-02-12 11:15:36 +01:00
ecl_coarse_cell_type * coarseCellData = ecl_grid_get_cell_coarse_group1 ( localEclGrid , localCellIdx );
2013-02-01 15:33:21 +01:00
cell . setInCoarseCell ( coarseCellData != NULL );
2012-05-18 09:45:23 +02:00
// Corner coordinates
int cIdx ;
for ( cIdx = 0 ; cIdx < 8 ; ++ cIdx )
{
2013-02-12 11:15:36 +01:00
double * point = mainGrid -> nodes ()[ nodeStartIndex + localCellIdx * 8 + cellMappingECLRi [ cIdx ]]. ptr ();
ecl_grid_get_corner_xyz1 ( localEclGrid , localCellIdx , cIdx , & ( point [ 0 ]), & ( point [ 1 ]), & ( point [ 2 ]));
2012-05-18 09:45:23 +02:00
point [ 2 ] = - point [ 2 ];
2013-02-12 11:15:36 +01:00
cell . cornerIndices ()[ cIdx ] = nodeStartIndex + localCellIdx * 8 + cIdx ;
2012-05-18 09:45:23 +02:00
}
// Sub grid in cell
2013-02-12 11:15:36 +01:00
const ecl_grid_type * subGrid = ecl_grid_get_cell_lgr1 ( localEclGrid , localCellIdx );
2012-05-18 09:45:23 +02:00
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 16:10:41 +02:00
2013-02-01 15:33:21 +01:00
// Mark inactive long pyramid looking cells as invalid
2013-02-11 15:12:53 +01:00
// Forslag
//if (!invalid && (cell.isInCoarseCell() || (!cell.isActiveInMatrixModel() && !cell.isActiveInFractureModel()) ) )
if ( ! invalid )
2013-01-30 15:02:28 +01:00
{
cell . setInvalid ( cell . isLongPyramidCell ());
}
2012-06-26 16:10:41 +02:00
#pragma omp atomic
computedCellCount ++ ;
2012-09-11 09:22:36 +02:00
progInfo . setProgress (( int )( computedCellCount / cellsPrProgressTick ));
2012-05-18 09:45:23 +02:00
}
2012-06-26 16:10:41 +02:00
return true ;
2012-05-18 09:45:23 +02:00
}
//==================================================================================================
//
// Class RigReaderInterfaceECL
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Constructor
//--------------------------------------------------------------------------------------------------
2012-06-26 16:10:41 +02:00
RifReaderEclipseOutput :: RifReaderEclipseOutput ()
2012-05-18 09:45:23 +02:00
{
2013-02-27 14:30:32 +01:00
m_fileName . clear ();
m_fileSet . clear ();
m_timeSteps . clear ();
m_eclipseCase = NULL ;
2013-02-27 14:13:37 +01:00
m_ecl_init_file = NULL ;
m_dynamicResultsAccess = NULL ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
/// Destructor
//--------------------------------------------------------------------------------------------------
2012-06-26 16:10:41 +02:00
RifReaderEclipseOutput ::~ RifReaderEclipseOutput ()
2012-05-18 09:45:23 +02:00
{
2013-03-08 08:24:40 +01:00
close ();
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
/// Close interface (for now, no files are kept open after calling methods, so just clear members)
//--------------------------------------------------------------------------------------------------
2012-06-26 16:10:41 +02:00
void RifReaderEclipseOutput :: close ()
2012-05-18 09:45:23 +02:00
{
2013-02-27 14:13:37 +01:00
if ( m_ecl_init_file )
2013-02-27 11:27:02 +01:00
{
2013-02-27 14:13:37 +01:00
ecl_file_close ( m_ecl_init_file );
2013-02-27 11:27:02 +01:00
}
2013-02-27 14:13:37 +01:00
m_ecl_init_file = NULL ;
2013-02-27 11:27:02 +01:00
2013-02-27 14:13:37 +01:00
if ( m_dynamicResultsAccess . notNull ())
{
m_dynamicResultsAccess -> close ();
}
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
/// Read geometry from file given by name into given reservoir object
//--------------------------------------------------------------------------------------------------
2013-02-13 13:24:39 +01:00
bool RifReaderEclipseOutput :: transferGeometry ( const ecl_grid_type * mainEclGrid , RigEclipseCase * eclipseCase )
2012-05-18 09:45:23 +02:00
{
2013-02-13 13:24:39 +01:00
CVF_ASSERT ( eclipseCase );
2012-05-18 09:45:23 +02:00
if ( ! mainEclGrid )
{
// Some error
return false ;
}
2013-03-13 11:50:31 +01:00
RigActiveCellInfo * activeCellInfo = eclipseCase -> activeCellInfo ( RifReaderInterface :: MATRIX_RESULTS );
RigActiveCellInfo * fractureActiveCellInfo = eclipseCase -> activeCellInfo ( RifReaderInterface :: FRACTURE_RESULTS );
CVF_ASSERT ( activeCellInfo && fractureActiveCellInfo );
2013-02-12 11:15:36 +01:00
2013-02-13 13:24:39 +01:00
RigMainGrid * mainGrid = eclipseCase -> mainGrid ();
2012-05-18 09:45:23 +02:00
{
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 );
}
2013-02-12 11:15:36 +01:00
activeCellInfo -> setGlobalCellCount ( totalCellCount );
2013-03-13 11:50:31 +01:00
fractureActiveCellInfo -> setGlobalCellCount ( totalCellCount );
2012-05-18 09:45:23 +02:00
// Reserve room for the cells and nodes and fill them with data
mainGrid -> cells (). reserve ( totalCellCount );
mainGrid -> nodes (). reserve ( 8 * totalCellCount );
2012-09-11 09:22:36 +02:00
caf :: ProgressInfo progInfo ( 3 + numLGRs , "" );
2012-06-26 16:10:41 +02:00
progInfo . setProgressDescription ( "Main Grid" );
2012-09-11 09:22:36 +02:00
progInfo . setNextProgressIncrement ( 3 );
2012-06-26 16:10:41 +02:00
2013-03-13 11:50:31 +01:00
transferGridCellData ( mainGrid , activeCellInfo , fractureActiveCellInfo , mainGrid , mainEclGrid , 0 , 0 );
2012-05-18 09:45:23 +02:00
2012-09-11 09:22:36 +02:00
progInfo . setProgress ( 3 );
2012-06-26 16:10:41 +02:00
2013-01-30 09:30:48 +01:00
size_t globalMatrixActiveSize = ecl_grid_get_nactive ( mainEclGrid );
size_t globalFractureActiveSize = ecl_grid_get_nactive_fracture ( mainEclGrid );
2012-05-18 09:45:23 +02:00
2013-02-12 11:15:36 +01:00
activeCellInfo -> setGridCount ( 1 + numLGRs );
2013-03-13 11:50:31 +01:00
fractureActiveCellInfo -> setGridCount ( 1 + numLGRs );
2013-02-12 11:15:36 +01:00
2013-03-13 11:50:31 +01:00
activeCellInfo -> setGridActiveCellCounts ( 0 , globalMatrixActiveSize );
fractureActiveCellInfo -> setGridActiveCellCounts ( 0 , globalFractureActiveSize );
2013-02-01 15:33:21 +01:00
2012-05-18 09:45:23 +02:00
for ( lgrIdx = 0 ; lgrIdx < numLGRs ; ++ lgrIdx )
{
2012-06-26 16:10:41 +02:00
progInfo . setProgressDescription ( "LGR number " + QString :: number ( lgrIdx + 1 ));
2012-05-18 09:45:23 +02:00
ecl_grid_type * localEclGrid = ecl_grid_iget_lgr ( mainEclGrid , lgrIdx );
2013-02-01 15:33:21 +01:00
RigLocalGrid * localGrid = static_cast < RigLocalGrid *> ( mainGrid -> gridByIndex ( lgrIdx + 1 ));
2013-03-13 11:50:31 +01:00
transferGridCellData ( mainGrid , activeCellInfo , fractureActiveCellInfo , localGrid , localEclGrid , globalMatrixActiveSize , globalFractureActiveSize );
2013-02-12 11:15:36 +01:00
int matrixActiveCellCount = ecl_grid_get_nactive ( localEclGrid );
globalMatrixActiveSize += matrixActiveCellCount ;
2013-02-01 15:33:21 +01:00
2013-02-12 11:15:36 +01:00
int fractureActiveCellCount = ecl_grid_get_nactive_fracture ( localEclGrid );
globalFractureActiveSize += fractureActiveCellCount ;
2013-02-01 15:33:21 +01:00
2013-03-13 11:50:31 +01:00
activeCellInfo -> setGridActiveCellCounts ( lgrIdx + 1 , matrixActiveCellCount );
fractureActiveCellInfo -> setGridActiveCellCounts ( lgrIdx + 1 , fractureActiveCellCount );
2012-09-11 09:22:36 +02:00
progInfo . setProgress ( 3 + lgrIdx );
2012-05-18 09:45:23 +02:00
}
2013-02-12 11:15:36 +01:00
activeCellInfo -> computeDerivedData ();
2013-03-13 11:50:31 +01:00
fractureActiveCellInfo -> computeDerivedData ();
2013-02-12 11:15:36 +01:00
2012-05-18 09:45:23 +02:00
return true ;
}
//--------------------------------------------------------------------------------------------------
/// Open file and read geometry into given reservoir object
//--------------------------------------------------------------------------------------------------
2013-02-13 13:24:39 +01:00
bool RifReaderEclipseOutput :: open ( const QString & fileName , RigEclipseCase * eclipseCase )
2012-05-18 09:45:23 +02:00
{
2013-02-13 13:24:39 +01:00
CVF_ASSERT ( eclipseCase );
2013-02-06 13:44:27 +01:00
caf :: ProgressInfo progInfo ( 100 , "" );
2012-06-26 16:10:41 +02:00
progInfo . setProgressDescription ( "Reading Grid" );
2012-05-18 09:45:23 +02:00
// Make sure everything's closed
close ();
// Get set of files
QStringList fileSet ;
2012-06-26 16:10:41 +02:00
if ( ! RifEclipseOutputFileTools :: fileSet ( fileName , & fileSet )) return false ;
2013-02-06 13:44:27 +01:00
progInfo . incrementProgress ();
2012-06-26 16:10:41 +02:00
2013-02-06 13:44:27 +01:00
progInfo . setNextProgressIncrement ( 20 );
2012-05-18 09:45:23 +02:00
// Keep the set of files of interest
m_fileSet = fileSet ;
// Read geometry
2012-06-26 16:10:41 +02:00
ecl_grid_type * mainEclGrid = ecl_grid_alloc ( fileName . toAscii (). data () );
2013-02-06 13:44:27 +01:00
progInfo . incrementProgress ();
progInfo . setNextProgressIncrement ( 10 );
2012-06-26 16:10:41 +02:00
progInfo . setProgressDescription ( "Transferring grid geometry" );
2013-02-13 13:24:39 +01:00
if ( ! transferGeometry ( mainEclGrid , eclipseCase )) return false ;
2013-02-06 13:44:27 +01:00
progInfo . incrementProgress ();
2013-01-30 14:13:50 +01:00
progInfo . setProgressDescription ( "Releasing reader memory" );
2012-06-26 16:10:41 +02:00
ecl_grid_free ( mainEclGrid );
2013-02-06 13:44:27 +01:00
progInfo . incrementProgress ();
2012-06-26 16:10:41 +02:00
progInfo . setProgressDescription ( "Reading Result index" );
2013-02-06 13:44:27 +01:00
progInfo . setNextProgressIncrement ( 60 );
2012-06-26 16:10:41 +02:00
2013-02-27 14:13:37 +01:00
m_eclipseCase = eclipseCase ;
2013-02-05 10:51:32 +01:00
2013-02-13 13:24:39 +01:00
eclipseCase -> results ( RifReaderInterface :: MATRIX_RESULTS ) -> setReaderInterface ( this );
eclipseCase -> results ( RifReaderInterface :: FRACTURE_RESULTS ) -> setReaderInterface ( this );
2013-02-05 10:51:32 +01:00
2012-05-18 09:45:23 +02:00
// Build results meta data
2013-02-27 14:13:37 +01:00
if ( ! buildMetaData ()) return false ;
2013-02-06 13:44:27 +01:00
progInfo . incrementProgress ();
2012-05-18 09:45:23 +02:00
2013-02-06 13:44:27 +01:00
progInfo . setNextProgressIncrement ( 8 );
2012-06-26 16:10:41 +02:00
progInfo . setProgressDescription ( "Reading Well information" );
2013-02-27 14:13:37 +01:00
readWellCells ();
2013-02-05 10:51:32 +01:00
2012-05-18 09:45:23 +02:00
return true ;
}
2013-02-27 11:27:02 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-03-05 13:10:26 +01:00
bool RifReaderEclipseOutput :: openAndReadActiveCellData ( const QString & fileName , RigEclipseCase * mainEclipseCase , RigEclipseCase * eclipseCase )
2013-02-27 11:27:02 +01:00
{
CVF_ASSERT ( eclipseCase );
2013-02-27 11:54:32 +01:00
// It is required to have a main grid before reading active cell data
if ( ! eclipseCase -> mainGrid ())
{
return false ;
}
2013-02-27 11:27:02 +01:00
close ();
// Get set of files
QStringList fileSet ;
if ( ! RifEclipseOutputFileTools :: fileSet ( fileName , & fileSet )) return false ;
// Keep the set of files of interest
m_fileSet = fileSet ;
2013-02-27 14:13:37 +01:00
m_eclipseCase = eclipseCase ;
2013-02-27 11:27:02 +01:00
eclipseCase -> results ( RifReaderInterface :: MATRIX_RESULTS ) -> setReaderInterface ( this );
eclipseCase -> results ( RifReaderInterface :: FRACTURE_RESULTS ) -> setReaderInterface ( this );
2013-02-27 14:13:37 +01:00
if ( ! readActiveCellInfo ())
2013-02-27 11:54:32 +01:00
{
return false ;
}
2013-02-27 11:27:02 +01:00
2013-02-27 15:27:33 +01:00
// Reading of metadata and well cells is not performed here
//if (!buildMetaData()) return false;
// readWellCells();
2013-02-27 11:27:02 +01:00
2013-03-05 13:10:26 +01:00
m_dynamicResultsAccess = createDynamicResultsAccess ( m_fileSet );
QList < QDateTime > mainCaseTimeSteps = mainEclipseCase -> results ( RifReaderInterface :: MATRIX_RESULTS ) -> readerInterface () -> timeSteps ();
m_dynamicResultsAccess -> setTimeSteps ( mainCaseTimeSteps );
2013-02-27 11:27:02 +01:00
return true ;
}
//--------------------------------------------------------------------------------------------------
///
2013-03-07 13:13:34 +01:00
/// See also RigStatistics::computeActiveCellUnion()
2013-02-27 11:27:02 +01:00
//--------------------------------------------------------------------------------------------------
2013-02-27 14:13:37 +01:00
bool RifReaderEclipseOutput :: readActiveCellInfo ()
2013-02-27 11:27:02 +01:00
{
2013-03-08 08:24:40 +01:00
CVF_ASSERT ( m_eclipseCase );
2013-02-27 14:13:37 +01:00
CVF_ASSERT ( m_eclipseCase -> mainGrid ());
2013-02-27 11:27:02 +01:00
QString egridFileName = RifEclipseOutputFileTools :: fileNameByType ( m_fileSet , ECL_EGRID_FILE );
if ( egridFileName . size () > 0 )
{
ecl_file_type * ecl_file = ecl_file_open ( egridFileName . toAscii (). data ());
if ( ! ecl_file ) return false ;
int actnumKeywordCount = ecl_file_get_num_named_kw ( ecl_file , ACTNUM_KW );
if ( actnumKeywordCount > 0 )
{
std :: vector < std :: vector < int > > actnumValuesPerGrid ;
actnumValuesPerGrid . resize ( actnumKeywordCount );
size_t globalCellCount = 0 ;
2013-03-02 10:18:27 +01:00
for ( size_t gridIdx = 0 ; gridIdx < static_cast < size_t > ( actnumKeywordCount ); gridIdx ++ )
2013-02-27 11:27:02 +01:00
{
RifEclipseOutputFileTools :: keywordData ( ecl_file , ACTNUM_KW , gridIdx , & actnumValuesPerGrid [ gridIdx ]);
globalCellCount += actnumValuesPerGrid [ gridIdx ]. size ();
}
2013-02-27 11:54:32 +01:00
// Check if number of cells is matching
2013-02-27 14:13:37 +01:00
if ( m_eclipseCase -> mainGrid () -> cells (). size () != globalCellCount )
2013-02-27 11:54:32 +01:00
{
return false ;
}
2013-03-13 11:50:31 +01:00
RigActiveCellInfo * activeCellInfo = m_eclipseCase -> activeCellInfo ( RifReaderInterface :: MATRIX_RESULTS );
RigActiveCellInfo * fractureActiveCellInfo = m_eclipseCase -> activeCellInfo ( RifReaderInterface :: FRACTURE_RESULTS );
2013-02-27 11:27:02 +01:00
activeCellInfo -> setGlobalCellCount ( globalCellCount );
2013-03-13 11:50:31 +01:00
fractureActiveCellInfo -> setGlobalCellCount ( globalCellCount );
2013-02-27 11:27:02 +01:00
activeCellInfo -> setGridCount ( actnumKeywordCount );
2013-03-13 11:50:31 +01:00
fractureActiveCellInfo -> setGridCount ( actnumKeywordCount );
2013-02-27 11:27:02 +01:00
size_t cellIdx = 0 ;
2013-03-07 13:13:34 +01:00
size_t globalActiveMatrixIndex = 0 ;
size_t globalActiveFractureIndex = 0 ;
2013-03-02 10:18:27 +01:00
for ( size_t gridIdx = 0 ; gridIdx < static_cast < size_t > ( actnumKeywordCount ); gridIdx ++ )
2013-02-27 11:27:02 +01:00
{
size_t activeMatrixIndex = 0 ;
size_t activeFractureIndex = 0 ;
std :: vector < int >& actnumValues = actnumValuesPerGrid [ gridIdx ];
for ( size_t i = 0 ; i < actnumValues . size (); i ++ )
{
if ( actnumValues [ i ] == 1 || actnumValues [ i ] == 3 )
{
2013-03-07 13:13:34 +01:00
activeCellInfo -> setActiveIndexInMatrixModel ( cellIdx , globalActiveMatrixIndex ++ );
activeMatrixIndex ++ ;
2013-02-27 11:27:02 +01:00
}
if ( actnumValues [ i ] == 2 || actnumValues [ i ] == 3 )
{
2013-03-13 11:50:31 +01:00
fractureActiveCellInfo -> setActiveIndexInMatrixModel ( cellIdx , globalActiveFractureIndex ++ );
2013-03-07 13:13:34 +01:00
activeFractureIndex ++ ;
2013-02-27 11:27:02 +01:00
}
cellIdx ++ ;
}
2013-03-13 11:50:31 +01:00
activeCellInfo -> setGridActiveCellCounts ( gridIdx , activeMatrixIndex );
fractureActiveCellInfo -> setGridActiveCellCounts ( gridIdx , activeFractureIndex );
2013-02-27 11:27:02 +01:00
}
activeCellInfo -> computeDerivedData ();
2013-03-13 11:50:31 +01:00
fractureActiveCellInfo -> computeDerivedData ();
2013-02-27 11:27:02 +01:00
}
ecl_file_close ( ecl_file );
return true ;
}
return false ;
}
2012-05-18 09:45:23 +02:00
//--------------------------------------------------------------------------------------------------
/// Build meta data - get states and results info
//--------------------------------------------------------------------------------------------------
2013-02-27 14:13:37 +01:00
bool RifReaderEclipseOutput :: buildMetaData ()
2012-05-18 09:45:23 +02:00
{
2013-03-08 08:24:40 +01:00
CVF_ASSERT ( m_eclipseCase );
2012-05-18 09:45:23 +02:00
CVF_ASSERT ( m_fileSet . size () > 0 );
2013-02-06 13:44:27 +01:00
caf :: ProgressInfo progInfo ( m_fileSet . size () + 3 , "" );
progInfo . setNextProgressIncrement ( m_fileSet . size ());
2012-06-26 16:10:41 +02:00
2012-05-18 09:45:23 +02:00
// Create access object for dynamic results
2013-03-05 13:10:26 +01:00
m_dynamicResultsAccess = createDynamicResultsAccess ( m_fileSet );
2013-01-30 14:13:50 +01:00
if ( m_dynamicResultsAccess . isNull ())
{
return false ;
}
2012-06-26 16:10:41 +02:00
2013-03-05 13:49:34 +01:00
m_dynamicResultsAccess -> open ();
2013-03-05 13:10:26 +01:00
2013-02-27 11:27:02 +01:00
2013-02-06 13:44:27 +01:00
progInfo . incrementProgress ();
2013-02-27 14:13:37 +01:00
RigReservoirCellResults * matrixModelResults = m_eclipseCase -> results ( RifReaderInterface :: MATRIX_RESULTS );
RigReservoirCellResults * fractureModelResults = m_eclipseCase -> results ( RifReaderInterface :: FRACTURE_RESULTS );
2012-06-26 16:10:41 +02:00
2012-05-18 09:45:23 +02:00
if ( m_dynamicResultsAccess . notNull ())
{
2012-06-26 16:10:41 +02:00
// Get time steps
2012-05-18 09:45:23 +02:00
m_timeSteps = m_dynamicResultsAccess -> timeSteps ();
2013-02-05 10:51:32 +01:00
QStringList resultNames ;
std :: vector < size_t > resultNamesDataItemCounts ;
m_dynamicResultsAccess -> resultNames ( & resultNames , & resultNamesDataItemCounts );
2013-02-01 14:39:32 +01:00
{
2013-03-13 11:50:31 +01:00
QStringList matrixResultNames = validKeywordsForPorosityModel ( resultNames , resultNamesDataItemCounts ,
m_eclipseCase -> activeCellInfo ( RifReaderInterface :: MATRIX_RESULTS ),
m_eclipseCase -> activeCellInfo ( RifReaderInterface :: FRACTURE_RESULTS ),
RifReaderInterface :: MATRIX_RESULTS , m_dynamicResultsAccess -> timeStepCount ());
2013-02-01 14:39:32 +01:00
2013-02-05 10:51:32 +01:00
for ( int i = 0 ; i < matrixResultNames . size (); ++ i )
2013-02-01 14:39:32 +01:00
{
2013-02-05 10:51:32 +01:00
size_t resIndex = matrixModelResults -> addEmptyScalarResult ( RimDefines :: DYNAMIC_NATIVE , matrixResultNames [ i ]);
2013-02-01 14:39:32 +01:00
matrixModelResults -> setTimeStepDates ( resIndex , m_timeSteps );
}
}
2012-06-26 16:10:41 +02:00
{
2013-03-13 11:50:31 +01:00
QStringList fractureResultNames = validKeywordsForPorosityModel ( resultNames , resultNamesDataItemCounts ,
m_eclipseCase -> activeCellInfo ( RifReaderInterface :: MATRIX_RESULTS ),
m_eclipseCase -> activeCellInfo ( RifReaderInterface :: FRACTURE_RESULTS ),
RifReaderInterface :: FRACTURE_RESULTS , m_dynamicResultsAccess -> timeStepCount ());
2013-02-01 14:39:32 +01:00
2013-02-05 10:51:32 +01:00
for ( int i = 0 ; i < fractureResultNames . size (); ++ i )
2013-02-01 14:39:32 +01:00
{
2013-02-05 10:51:32 +01:00
size_t resIndex = fractureModelResults -> addEmptyScalarResult ( RimDefines :: DYNAMIC_NATIVE , fractureResultNames [ i ]);
2013-02-01 14:39:32 +01:00
fractureModelResults -> setTimeStepDates ( resIndex , m_timeSteps );
}
2012-06-26 16:10:41 +02:00
}
2013-02-01 14:39:32 +01:00
2012-05-18 09:45:23 +02:00
}
2013-02-06 13:44:27 +01:00
progInfo . incrementProgress ();
2012-06-26 16:10:41 +02:00
2013-03-05 13:10:26 +01:00
openInitFile ();
2013-02-27 14:13:37 +01:00
progInfo . incrementProgress ();
2013-02-05 10:51:32 +01:00
2013-03-05 13:10:26 +01:00
if ( m_ecl_init_file )
2013-02-27 14:13:37 +01:00
{
2013-03-05 13:10:26 +01:00
QStringList resultNames ;
std :: vector < size_t > resultNamesDataItemCounts ;
RifEclipseOutputFileTools :: findKeywordsAndDataItemCounts ( m_ecl_init_file , & resultNames , & resultNamesDataItemCounts );
2012-08-31 19:12:47 +02:00
2012-06-26 16:10:41 +02:00
{
2013-03-13 11:50:31 +01:00
QStringList matrixResultNames = validKeywordsForPorosityModel ( resultNames , resultNamesDataItemCounts ,
m_eclipseCase -> activeCellInfo ( RifReaderInterface :: MATRIX_RESULTS ),
m_eclipseCase -> activeCellInfo ( RifReaderInterface :: FRACTURE_RESULTS ),
RifReaderInterface :: MATRIX_RESULTS , 1 );
2013-02-01 14:39:32 +01:00
2013-03-05 13:10:26 +01:00
QList < QDateTime > staticDate ;
if ( m_timeSteps . size () > 0 )
{
staticDate . push_back ( m_timeSteps . front ());
}
2013-02-01 14:39:32 +01:00
2013-03-05 13:10:26 +01:00
for ( int i = 0 ; i < matrixResultNames . size (); ++ i )
{
size_t resIndex = matrixModelResults -> addEmptyScalarResult ( RimDefines :: STATIC_NATIVE , matrixResultNames [ i ]);
matrixModelResults -> setTimeStepDates ( resIndex , staticDate );
}
2012-06-26 16:10:41 +02:00
}
2012-05-18 09:45:23 +02:00
2013-02-27 14:13:37 +01:00
{
2013-03-13 11:50:31 +01:00
QStringList fractureResultNames = validKeywordsForPorosityModel ( resultNames , resultNamesDataItemCounts ,
m_eclipseCase -> activeCellInfo ( RifReaderInterface :: MATRIX_RESULTS ),
m_eclipseCase -> activeCellInfo ( RifReaderInterface :: FRACTURE_RESULTS ),
RifReaderInterface :: FRACTURE_RESULTS , 1 );
2013-03-05 13:10:26 +01:00
QList < QDateTime > staticDate ;
if ( m_timeSteps . size () > 0 )
{
staticDate . push_back ( m_timeSteps . front ());
}
for ( int i = 0 ; i < fractureResultNames . size (); ++ i )
{
size_t resIndex = fractureModelResults -> addEmptyScalarResult ( RimDefines :: STATIC_NATIVE , fractureResultNames [ i ]);
fractureModelResults -> setTimeStepDates ( resIndex , staticDate );
}
2013-02-27 14:13:37 +01:00
}
2012-05-18 09:45:23 +02:00
}
return true ;
}
//--------------------------------------------------------------------------------------------------
/// Create results access object (.UNRST or .X0001 ... .XNNNN)
//--------------------------------------------------------------------------------------------------
2013-03-05 13:10:26 +01:00
RifEclipseRestartDataAccess * RifReaderEclipseOutput :: createDynamicResultsAccess ( const QStringList & fileSet )
2012-05-18 09:45:23 +02:00
{
2012-06-26 16:10:41 +02:00
RifEclipseRestartDataAccess * resultsAccess = NULL ;
2012-05-18 09:45:23 +02:00
// Look for unified restart file
2012-06-26 16:10:41 +02:00
QString unrstFileName = RifEclipseOutputFileTools :: fileNameByType ( fileSet , ECL_UNIFIED_RESTART_FILE );
2012-05-18 09:45:23 +02:00
if ( unrstFileName . size () > 0 )
{
2013-01-30 14:13:50 +01:00
resultsAccess = new RifEclipseUnifiedRestartFileAccess ();
2013-03-05 13:10:26 +01:00
resultsAccess -> setFileSet ( QStringList ( unrstFileName ));
2012-05-18 09:45:23 +02:00
}
else
{
// Look for set of restart files (one file per time step)
2012-06-26 16:10:41 +02:00
QStringList restartFiles = RifEclipseOutputFileTools :: fileNamesByType ( fileSet , ECL_RESTART_FILE );
2012-05-18 09:45:23 +02:00
if ( restartFiles . size () > 0 )
{
2013-01-30 14:13:50 +01:00
resultsAccess = new RifEclipseRestartFilesetAccess ();
2013-03-05 13:10:26 +01:00
resultsAccess -> setFileSet ( restartFiles );
2012-05-18 09:45:23 +02:00
}
}
return resultsAccess ;
}
//--------------------------------------------------------------------------------------------------
/// Get all values of a given static result as doubles
//--------------------------------------------------------------------------------------------------
2013-01-30 14:13:50 +01:00
bool RifReaderEclipseOutput :: staticResult ( const QString & result , PorosityModelResultType matrixOrFracture , std :: vector < double >* values )
2012-05-18 09:45:23 +02:00
{
CVF_ASSERT ( values );
2013-02-27 14:13:37 +01:00
if ( ! openInitFile ())
{
return false ;
}
CVF_ASSERT ( m_ecl_init_file );
2013-02-05 10:51:32 +01:00
std :: vector < double > fileValues ;
2012-05-18 09:45:23 +02:00
2013-02-27 14:13:37 +01:00
size_t numOccurrences = ecl_file_get_num_named_kw ( m_ecl_init_file , result . toAscii (). data ());
2012-05-18 09:45:23 +02:00
size_t i ;
for ( i = 0 ; i < numOccurrences ; i ++ )
{
std :: vector < double > partValues ;
2013-02-27 14:13:37 +01:00
RifEclipseOutputFileTools :: keywordData ( m_ecl_init_file , result , i , & partValues );
2013-02-05 10:51:32 +01:00
fileValues . insert ( fileValues . end (), partValues . begin (), partValues . end ());
2012-05-18 09:45:23 +02:00
}
2013-02-05 10:51:32 +01:00
extractResultValuesBasedOnPorosityModel ( matrixOrFracture , values , fileValues );
2012-05-18 09:45:23 +02:00
return true ;
}
//--------------------------------------------------------------------------------------------------
/// Get dynamic result at given step index. Will concatenate values for the main grid and all sub grids.
//--------------------------------------------------------------------------------------------------
2013-01-30 14:13:50 +01:00
bool RifReaderEclipseOutput :: dynamicResult ( const QString & result , PorosityModelResultType matrixOrFracture , size_t stepIndex , std :: vector < double >* values )
2012-05-18 09:45:23 +02:00
{
2013-03-05 13:10:26 +01:00
if ( m_dynamicResultsAccess . isNull ())
{
m_dynamicResultsAccess = createDynamicResultsAccess ( m_fileSet );
}
if ( m_dynamicResultsAccess . isNull ())
{
CVF_ASSERT ( false );
return false ;
}
2013-02-05 10:51:32 +01:00
std :: vector < double > fileValues ;
2013-02-27 14:13:37 +01:00
if ( ! m_dynamicResultsAccess -> results ( result , stepIndex , m_eclipseCase -> mainGrid () -> gridCount (), & fileValues ))
2013-02-05 10:51:32 +01:00
{
return false ;
}
extractResultValuesBasedOnPorosityModel ( matrixOrFracture , values , fileValues );
return true ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-02-27 14:13:37 +01:00
void RifReaderEclipseOutput :: readWellCells ()
2012-05-18 09:45:23 +02:00
{
2013-03-08 08:24:40 +01:00
CVF_ASSERT ( m_eclipseCase );
2012-05-18 09:45:23 +02:00
if ( m_dynamicResultsAccess . isNull ()) return ;
well_info_type * ert_well_info = well_info_alloc ( NULL );
if ( ! ert_well_info ) return ;
m_dynamicResultsAccess -> readWellData ( ert_well_info );
2013-02-27 14:13:37 +01:00
RigMainGrid * mainGrid = m_eclipseCase -> mainGrid ();
2012-05-18 09:45:23 +02:00
std :: vector < RigGridBase *> grids ;
2013-02-27 14:13:37 +01:00
m_eclipseCase -> allGrids ( & grids );
2012-05-18 09:45:23 +02:00
cvf :: Collection < RigWellResults > wells ;
2013-02-06 13:44:27 +01:00
caf :: ProgressInfo progress ( well_info_get_num_wells ( ert_well_info ), "" );
2012-05-18 09:45:23 +02:00
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 16:10:41 +02:00
// Also see RifEclipseOutputFileAccess::timeStepsText for accessing time_t structures
2012-05-18 09:45:23 +02: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 )
{
2013-01-23 10:56:09 +01:00
int branchCount = well_state_iget_lgr_num_branches ( ert_well_state , static_cast < int > ( gridNr ));
2012-05-18 09:45:23 +02:00
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)
2013-01-23 10:56:09 +01:00
const well_conn_type * ert_wellhead = well_state_iget_wellhead ( ert_well_state , static_cast < int > ( gridNr ));
2012-05-18 09:45:23 +02:00
if ( ert_wellhead )
{
2013-01-25 15:20:41 +01:00
int cellI = well_conn_get_i ( ert_wellhead );
int cellJ = well_conn_get_j ( ert_wellhead );
int cellK = CVF_MAX ( 0 , well_conn_get_k ( ert_wellhead )); // Why this ?
2013-02-08 14:51:42 +01:00
// If a well is defined in fracture region, the K-value is from (cellCountK - 1) -> cellCountK*2 - 1
// Adjust K so index is always in valid grid region
2013-03-02 10:18:27 +01:00
if ( cellK >= static_cast < int > ( grids [ gridNr ] -> cellCountK ()))
2013-02-08 14:51:42 +01:00
{
cellK -= static_cast < int > ( grids [ gridNr ] -> cellCountK ());
2013-01-25 15:20:41 +01:00
}
2013-02-08 14:51:42 +01:00
2013-01-25 15:20:41 +01:00
wellResFrame . m_wellHead . m_gridCellIndex = grids [ gridNr ] -> cellIndexFromIJK ( cellI , cellJ , cellK );
2012-05-18 09:45:23 +02:00
wellResFrame . m_wellHead . m_gridIndex = gridNr ;
}
2012-09-13 10:56:39 +02:00
2013-01-23 10:56:09 +01:00
int branchCount = well_state_iget_lgr_num_branches ( ert_well_state , static_cast < int > ( gridNr ));
2012-05-18 09:45:23 +02:00
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
2013-01-23 10:56:09 +01:00
int connectionCount = well_state_iget_num_lgr_connections ( ert_well_state , static_cast < int > ( gridNr ), branchIdx );
2012-05-18 09:45:23 +02:00
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 ++ )
{
2013-01-23 10:56:09 +01:00
const well_conn_type * ert_connection = well_state_iget_lgr_connections ( ert_well_state , static_cast < int > ( gridNr ), branchIdx )[ connIdx ];
2012-05-18 09:45:23 +02:00
CVF_ASSERT ( ert_connection );
RigWellResultCell & data = wellSegment . m_wellCells [ existingConnCount + connIdx ];
data . m_gridIndex = gridNr ;
2012-09-13 10:56:39 +02:00
{
2013-01-25 15:20:41 +01:00
int cellI = well_conn_get_i ( ert_connection );
int cellJ = well_conn_get_j ( ert_connection );
int cellK = well_conn_get_k ( ert_connection );
2012-09-13 10:56:39 +02:00
bool open = well_conn_open ( ert_connection );
int branch = well_conn_get_branch ( ert_connection );
int segment = well_conn_get_segment ( ert_connection );
2013-02-08 14:51:42 +01:00
// If a well is defined in fracture region, the K-value is from (cellCountK - 1) -> cellCountK*2 - 1
// Adjust K so index is always in valid grid region
2013-03-02 10:18:27 +01:00
if ( cellK >= static_cast < int > ( grids [ gridNr ] -> cellCountK ()))
2013-01-25 15:20:41 +01:00
{
2013-02-08 14:51:42 +01:00
cellK -= static_cast < int > ( grids [ gridNr ] -> cellCountK ());
2013-01-25 15:20:41 +01:00
}
data . m_gridCellIndex = grids [ gridNr ] -> cellIndexFromIJK ( cellI , cellJ , cellK );
2012-09-13 10:56:39 +02:00
data . m_isOpen = open ;
data . m_branchId = branch ;
data . m_segmentId = segment ;
}
2012-05-18 09:45:23 +02:00
}
}
}
}
}
}
wellResults -> computeMappingFromResultTimeIndicesToWellTimeIndices ( m_timeSteps );
wells . push_back ( wellResults . p ());
2013-02-06 13:44:27 +01:00
progress . incrementProgress ();
2012-05-18 09:45:23 +02:00
}
well_info_free ( ert_well_info );
2013-02-27 14:13:37 +01:00
m_eclipseCase -> setWellResults ( wells );
2012-05-18 09:45:23 +02:00
}
2013-01-25 15:20:41 +01:00
2013-02-05 10:51:32 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-03-13 11:50:31 +01:00
QStringList RifReaderEclipseOutput :: validKeywordsForPorosityModel ( const QStringList & keywords , const std :: vector < size_t >& keywordDataItemCounts ,
const RigActiveCellInfo * activeCellInfo , const RigActiveCellInfo * fractureActiveCellInfo ,
PorosityModelResultType matrixOrFracture , size_t timeStepCount ) const
2013-02-05 10:51:32 +01:00
{
2013-02-12 11:15:36 +01:00
CVF_ASSERT ( activeCellInfo );
2013-03-02 10:18:27 +01:00
if ( keywords . size () != static_cast < int > ( keywordDataItemCounts . size ()))
2013-02-05 10:51:32 +01:00
{
return QStringList ();
}
if ( matrixOrFracture == RifReaderInterface :: FRACTURE_RESULTS )
{
2013-03-13 11:50:31 +01:00
if ( fractureActiveCellInfo -> globalMatrixModelActiveCellCount () == 0 )
2013-02-05 10:51:32 +01:00
{
return QStringList ();
}
}
QStringList keywordsWithCorrectNumberOfDataItems ;
for ( int i = 0 ; i < keywords . size (); i ++ )
{
QString keyword = keywords [ i ];
size_t keywordDataCount = keywordDataItemCounts [ i ];
2013-02-27 11:27:02 +01:00
if ( activeCellInfo -> globalMatrixModelActiveCellCount () > 0 )
{
size_t timeStepsMatrix = keywordDataItemCounts [ i ] / activeCellInfo -> globalMatrixModelActiveCellCount ();
size_t timeStepsMatrixRest = keywordDataItemCounts [ i ] % activeCellInfo -> globalMatrixModelActiveCellCount ();
2013-02-05 10:51:32 +01:00
2013-03-13 11:50:31 +01:00
size_t timeStepsMatrixAndFracture = keywordDataItemCounts [ i ] / ( activeCellInfo -> globalMatrixModelActiveCellCount () + fractureActiveCellInfo -> globalMatrixModelActiveCellCount ());
size_t timeStepsMatrixAndFractureRest = keywordDataItemCounts [ i ] % ( activeCellInfo -> globalMatrixModelActiveCellCount () + fractureActiveCellInfo -> globalMatrixModelActiveCellCount ());
2013-02-05 10:51:32 +01:00
2013-02-27 11:27:02 +01:00
if ( matrixOrFracture == RifReaderInterface :: MATRIX_RESULTS )
2013-02-05 10:51:32 +01:00
{
2013-02-27 11:27:02 +01:00
if ( timeStepsMatrixRest == 0 || timeStepsMatrixAndFractureRest == 0 )
{
if ( timeStepCount == timeStepsMatrix || timeStepCount == timeStepsMatrixAndFracture )
{
keywordsWithCorrectNumberOfDataItems . push_back ( keywords [ i ]);
}
}
}
else
{
if ( timeStepsMatrixAndFractureRest == 0 && timeStepCount == timeStepsMatrixAndFracture )
2013-02-05 10:51:32 +01:00
{
keywordsWithCorrectNumberOfDataItems . push_back ( keywords [ i ]);
}
}
}
else
{
2013-02-27 11:27:02 +01:00
keywordsWithCorrectNumberOfDataItems . push_back ( keywords [ i ]);
2013-02-05 10:51:32 +01:00
}
}
return keywordsWithCorrectNumberOfDataItems ;
}
2013-02-27 11:27:02 +01:00
2013-02-05 10:51:32 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseOutput :: extractResultValuesBasedOnPorosityModel ( PorosityModelResultType matrixOrFracture , std :: vector < double >* destinationResultValues , const std :: vector < double >& sourceResultValues )
{
2013-03-13 11:50:31 +01:00
RigActiveCellInfo * fracActCellInfo = m_eclipseCase -> activeCellInfo ( RifReaderInterface :: FRACTURE_RESULTS );
2013-02-05 10:51:32 +01:00
2013-03-13 11:50:31 +01:00
if ( matrixOrFracture == RifReaderInterface :: MATRIX_RESULTS && fracActCellInfo -> globalMatrixModelActiveCellCount () == 0 )
{
destinationResultValues -> insert ( destinationResultValues -> end (), sourceResultValues . begin (), sourceResultValues . end ());
2013-02-05 10:51:32 +01:00
}
else
{
2013-03-13 11:50:31 +01:00
RigActiveCellInfo * actCellInfo = m_eclipseCase -> activeCellInfo ( RifReaderInterface :: MATRIX_RESULTS );
2013-02-05 10:51:32 +01:00
size_t dataItemCount = 0 ;
size_t sourceStartPosition = 0 ;
2013-02-27 14:13:37 +01:00
for ( size_t i = 0 ; i < m_eclipseCase -> mainGrid () -> gridCount (); i ++ )
2013-02-05 10:51:32 +01:00
{
2013-02-12 11:15:36 +01:00
size_t matrixActiveCellCount = 0 ;
size_t fractureActiveCellCount = 0 ;
2013-03-13 11:50:31 +01:00
actCellInfo -> gridActiveCellCounts ( i , matrixActiveCellCount );
fracActCellInfo -> gridActiveCellCounts ( i , fractureActiveCellCount );
2013-02-05 10:51:32 +01:00
2013-03-13 11:50:31 +01:00
if ( matrixOrFracture == RifReaderInterface :: MATRIX_RESULTS )
{
destinationResultValues -> insert ( destinationResultValues -> end (),
sourceResultValues . begin () + sourceStartPosition ,
sourceResultValues . begin () + sourceStartPosition + matrixActiveCellCount );
}
else
{
destinationResultValues -> insert ( destinationResultValues -> end (),
sourceResultValues . begin () + sourceStartPosition + matrixActiveCellCount ,
sourceResultValues . begin () + sourceStartPosition + matrixActiveCellCount + fractureActiveCellCount );
}
2013-02-05 10:51:32 +01:00
sourceStartPosition += ( matrixActiveCellCount + fractureActiveCellCount );
}
}
}
2013-02-27 14:13:37 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifReaderEclipseOutput :: openInitFile ()
{
if ( m_ecl_init_file )
{
return true ;
}
QString initFileName = RifEclipseOutputFileTools :: fileNameByType ( m_fileSet , ECL_INIT_FILE );
if ( initFileName . size () > 0 )
{
2013-02-28 11:27:37 +01:00
m_ecl_init_file = ecl_file_open ( initFileName . toAscii (). data ());
if ( m_ecl_init_file )
2013-02-27 14:13:37 +01:00
{
return true ;
}
}
return false ;
}
2013-03-05 13:10:26 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList < QDateTime > RifReaderEclipseOutput :: timeSteps ()
{
return m_timeSteps ;
}