2012-05-18 02:45:23 -05:00
/////////////////////////////////////////////////////////////////////////////////
//
2014-09-23 08:04:57 -05:00
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 Ceetron AS
2012-05-18 02:45:23 -05:00
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
2014-08-27 07:05:29 -05:00
# include "RifReaderEclipseOutput.h"
2012-05-18 02:45:23 -05:00
2017-01-17 08:11:02 -06:00
# include "RifEclipseInputFileTools.h"
2012-06-26 09:10:41 -05:00
# include "RifEclipseOutputFileTools.h"
# include "RifEclipseRestartFilesetAccess.h"
2014-08-27 07:05:29 -05:00
# include "RifEclipseUnifiedRestartFileAccess.h"
2012-05-18 02:45:23 -05:00
2017-01-17 08:11:02 -06:00
# include "RigActiveCellInfo.h"
# include "RigCaseCellResultsData.h"
# include "RigEclipseCaseData.h"
# include "RigMainGrid.h"
# include "RigSingleWellResultsData.h"
2014-08-27 07:05:29 -05:00
# include "cafProgressInfo.h"
2012-05-18 02:45:23 -05:00
2017-01-17 08:11:02 -06:00
# include "cvfTrace.h"
2016-05-26 07:49:13 -05:00
# include "ert/ecl/ecl_kw_magic.h"
2017-01-17 08:11:02 -06:00
# include "ert/ecl/ecl_nnc_export.h"
2013-02-27 04:27:02 -06:00
2017-01-17 08:11:02 -06:00
# include <cmath> // Needed for HUGE_VAL on Linux
2014-08-27 07:05:29 -05:00
# include <iostream>
2013-08-26 07:56:34 -05:00
# include <map>
2014-08-27 07:05:29 -05:00
2012-05-18 02:45:23 -05:00
//--------------------------------------------------------------------------------------------------
/// ECLIPSE cell numbering layout:
/// Lower layer: Upper layer
2013-12-18 08:36:28 -06:00
/// Low Depth High Depth
/// Low K High K
/// Shallow Deep
2012-05-18 02:45:23 -05:00
/// 2---3 6---7
/// | | | |
/// 0---1 4---5
///
///
///
//--------------------------------------------------------------------------------------------------
// The indexing conventions for vertices in ECLIPSE
//
2013-12-18 08:36:28 -06:00
// 2-------------3
// /| /|
// / | / | /j
// / | / | /
// 0-------------1 | *---i
// | | | | |
// | 6---------|---7 |
// | / | / |k
2012-05-18 02:45:23 -05:00
// | / | /
// |/ |/
2013-12-18 08:36:28 -06:00
// 4-------------5
2012-05-18 02:45:23 -05:00
// vertex indices
//
// The indexing conventions for vertices in ResInsight
//
2013-01-30 08:02:28 -06:00
// 7-------------6 |k
// /| /| | /j
// / | / | |/
// / | / | *---i
2012-05-18 02:45:23 -05: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 05:50:31 -05: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 02:45:23 -05:00
{
2013-03-13 05:50:31 -05:00
CVF_ASSERT ( activeCellInfo & & fractureActiveCellInfo ) ;
2013-02-12 04:15:36 -06:00
2012-05-18 02:45:23 -05:00
int cellCount = ecl_grid_get_global_size ( localEclGrid ) ;
2015-11-24 07:21:02 -06:00
size_t cellStartIndex = mainGrid - > globalCellArray ( ) . size ( ) ;
2012-05-18 02:45:23 -05:00
size_t nodeStartIndex = mainGrid - > nodes ( ) . size ( ) ;
RigCell defaultCell ;
defaultCell . setHostGrid ( localGrid ) ;
2015-11-24 07:21:02 -06:00
mainGrid - > globalCellArray ( ) . resize ( cellStartIndex + cellCount , defaultCell ) ;
2012-05-18 02:45:23 -05:00
mainGrid - > nodes ( ) . resize ( nodeStartIndex + cellCount * 8 , cvf : : Vec3d ( 0 , 0 , 0 ) ) ;
2012-09-11 02:22:36 -05:00
int progTicks = 100 ;
double cellsPrProgressTick = cellCount / ( float ) progTicks ;
caf : : ProgressInfo progInfo ( progTicks , " " ) ;
2012-06-26 09:10:41 -05:00
size_t computedCellCount = 0 ;
2012-05-18 02:45:23 -05:00
// Loop over cells and fill them with data
2012-09-11 02:22:36 -05:00
# pragma omp parallel for
2014-08-08 02:50:57 -05:00
for ( int gridLocalCellIndex = 0 ; gridLocalCellIndex < cellCount ; + + gridLocalCellIndex )
2012-05-18 02:45:23 -05:00
{
2015-11-24 07:21:02 -06:00
RigCell & cell = mainGrid - > globalCellArray ( ) [ cellStartIndex + gridLocalCellIndex ] ;
2012-05-18 02:45:23 -05:00
2014-08-22 01:01:31 -05:00
cell . setGridLocalCellIndex ( gridLocalCellIndex ) ;
2013-01-30 08:02:28 -06:00
2013-02-01 08:33:21 -06:00
// Active cell index
2014-08-08 02:50:57 -05:00
int matrixActiveIndex = ecl_grid_get_active_index1 ( localEclGrid , gridLocalCellIndex ) ;
2013-01-30 08:02:28 -06:00
if ( matrixActiveIndex ! = - 1 )
{
2014-08-08 02:50:57 -05:00
activeCellInfo - > setCellResultIndex ( cellStartIndex + gridLocalCellIndex , matrixActiveStartIndex + matrixActiveIndex ) ;
2013-01-30 08:02:28 -06:00
}
2013-01-30 02:30:48 -06:00
2014-08-08 02:50:57 -05:00
int fractureActiveIndex = ecl_grid_get_active_fracture_index1 ( localEclGrid , gridLocalCellIndex ) ;
2013-01-30 08:02:28 -06:00
if ( fractureActiveIndex ! = - 1 )
2013-01-30 02:30:48 -06:00
{
2014-08-08 02:50:57 -05:00
fractureActiveCellInfo - > setCellResultIndex ( cellStartIndex + gridLocalCellIndex , fractureActiveStartIndex + fractureActiveIndex ) ;
2013-01-30 08:02:28 -06:00
}
2012-05-18 02:45:23 -05:00
2013-02-01 08:33:21 -06:00
// Parent cell index
2014-08-08 02:50:57 -05:00
int parentCellIndex = ecl_grid_get_parent_cell1 ( localEclGrid , gridLocalCellIndex ) ;
2012-05-18 02:45:23 -05:00
if ( parentCellIndex = = - 1 )
{
cell . setParentCellIndex ( cvf : : UNDEFINED_SIZE_T ) ;
}
else
{
cell . setParentCellIndex ( parentCellIndex ) ;
}
// Corner coordinates
int cIdx ;
for ( cIdx = 0 ; cIdx < 8 ; + + cIdx )
{
2014-08-08 02:50:57 -05:00
double * point = mainGrid - > nodes ( ) [ nodeStartIndex + gridLocalCellIndex * 8 + cellMappingECLRi [ cIdx ] ] . ptr ( ) ;
2014-10-09 13:13:04 -05:00
ecl_grid_get_cell_corner_xyz1 ( localEclGrid , gridLocalCellIndex , cIdx , & ( point [ 0 ] ) , & ( point [ 1 ] ) , & ( point [ 2 ] ) ) ;
2013-12-19 01:48:36 -06:00
point [ 2 ] = - point [ 2 ] ; // Flipping Z making depth become negative z values
2014-08-08 02:50:57 -05:00
cell . cornerIndices ( ) [ cIdx ] = nodeStartIndex + gridLocalCellIndex * 8 + cIdx ;
2012-05-18 02:45:23 -05:00
}
// Sub grid in cell
2014-08-08 02:50:57 -05:00
const ecl_grid_type * subGrid = ecl_grid_get_cell_lgr1 ( localEclGrid , gridLocalCellIndex ) ;
2012-05-18 02:45:23 -05:00
if ( subGrid ! = NULL )
{
2013-09-05 06:03:53 -05:00
int subGridId = ecl_grid_get_lgr_nr ( subGrid ) ;
CVF_ASSERT ( subGridId > 0 ) ;
cell . setSubGrid ( static_cast < RigLocalGrid * > ( mainGrid - > gridById ( subGridId ) ) ) ;
2012-05-18 02:45:23 -05:00
}
2012-06-26 09:10:41 -05:00
2013-02-01 08:33:21 -06:00
// Mark inactive long pyramid looking cells as invalid
2013-02-11 08:12:53 -06:00
// Forslag
//if (!invalid && (cell.isInCoarseCell() || (!cell.isActiveInMatrixModel() && !cell.isActiveInFractureModel()) ) )
2013-08-26 14:56:40 -05:00
cell . setInvalid ( cell . isLongPyramidCell ( ) ) ;
2013-01-30 08:02:28 -06:00
2012-06-26 09:10:41 -05:00
# pragma omp atomic
computedCellCount + + ;
2012-09-11 02:22:36 -05:00
progInfo . setProgress ( ( int ) ( computedCellCount / cellsPrProgressTick ) ) ;
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
}
//==================================================================================================
//
// Class RigReaderInterfaceECL
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Constructor
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
RifReaderEclipseOutput : : RifReaderEclipseOutput ( )
2012-05-18 02:45:23 -05:00
{
2013-02-27 07:30:32 -06:00
m_fileName . clear ( ) ;
2013-04-10 04:02:10 -05:00
m_filesWithSameBaseName . clear ( ) ;
2013-02-27 07:30:32 -06:00
m_timeSteps . clear ( ) ;
m_eclipseCase = NULL ;
2013-02-27 07:13:37 -06:00
m_ecl_init_file = NULL ;
m_dynamicResultsAccess = NULL ;
2012-05-18 02:45:23 -05:00
}
//--------------------------------------------------------------------------------------------------
/// Destructor
//--------------------------------------------------------------------------------------------------
2012-06-26 09:10:41 -05:00
RifReaderEclipseOutput : : ~ RifReaderEclipseOutput ( )
2012-05-18 02:45:23 -05:00
{
2013-03-08 01:24:40 -06:00
close ( ) ;
2012-05-18 02:45:23 -05:00
2013-02-27 07:13:37 -06:00
if ( m_ecl_init_file )
2013-02-27 04:27:02 -06:00
{
2013-02-27 07:13:37 -06:00
ecl_file_close ( m_ecl_init_file ) ;
2013-02-27 04:27:02 -06:00
}
2013-02-27 07:13:37 -06:00
m_ecl_init_file = NULL ;
2013-02-27 04:27:02 -06:00
2013-02-27 07:13:37 -06:00
if ( m_dynamicResultsAccess . notNull ( ) )
{
m_dynamicResultsAccess - > close ( ) ;
}
2013-04-29 06:13:42 -05:00
}
//--------------------------------------------------------------------------------------------------
/// Close interface (for now, no files are kept open after calling methods, so just clear members)
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseOutput : : close ( )
{
2012-05-18 02:45:23 -05:00
}
//--------------------------------------------------------------------------------------------------
/// Read geometry from file given by name into given reservoir object
//--------------------------------------------------------------------------------------------------
2017-01-10 02:51:39 -06:00
bool RifReaderEclipseOutput : : transferGeometry ( const ecl_grid_type * mainEclGrid , RigEclipseCaseData * eclipseCase )
2012-05-18 02:45:23 -05:00
{
2013-02-13 06:24:39 -06:00
CVF_ASSERT ( eclipseCase ) ;
2012-05-18 02:45:23 -05:00
if ( ! mainEclGrid )
{
// Some error
return false ;
}
2013-03-13 05:50:31 -05:00
RigActiveCellInfo * activeCellInfo = eclipseCase - > activeCellInfo ( RifReaderInterface : : MATRIX_RESULTS ) ;
RigActiveCellInfo * fractureActiveCellInfo = eclipseCase - > activeCellInfo ( RifReaderInterface : : FRACTURE_RESULTS ) ;
CVF_ASSERT ( activeCellInfo & & fractureActiveCellInfo ) ;
2013-02-12 04:15:36 -06:00
2013-02-13 06:24:39 -06:00
RigMainGrid * mainGrid = eclipseCase - > mainGrid ( ) ;
2013-12-20 07:29:08 -06:00
CVF_ASSERT ( mainGrid ) ;
2012-05-18 02:45:23 -05: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 ) ;
}
2013-12-20 07:29:08 -06:00
// std::string mainGridName = ecl_grid_get_name(mainEclGrid);
// ERT returns file path to grid file as name for main grid
mainGrid - > setGridName ( " Main grid " ) ;
2012-05-18 02:45:23 -05:00
// 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 ) ;
2013-09-05 06:03:53 -05:00
int lgrId = ecl_grid_get_lgr_nr ( localEclGrid ) ;
2012-05-18 02:45:23 -05:00
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 ) ;
2013-09-05 06:03:53 -05:00
localGrid - > setGridId ( lgrId ) ;
2012-05-18 02:45:23 -05:00
mainGrid - > addLocalGrid ( localGrid ) ;
localGrid - > setIndexToStartOfCells ( totalCellCount ) ;
localGrid - > setGridName ( lgrName ) ;
localGrid - > setGridPointDimensions ( gridPointDim ) ;
totalCellCount + = ecl_grid_get_global_size ( localEclGrid ) ;
}
2013-02-12 04:15:36 -06:00
2014-08-08 03:27:29 -05:00
activeCellInfo - > setReservoirCellCount ( totalCellCount ) ;
fractureActiveCellInfo - > setReservoirCellCount ( totalCellCount ) ;
2012-05-18 02:45:23 -05:00
// Reserve room for the cells and nodes and fill them with data
2015-11-24 07:21:02 -06:00
mainGrid - > globalCellArray ( ) . reserve ( totalCellCount ) ;
2012-05-18 02:45:23 -05:00
mainGrid - > nodes ( ) . reserve ( 8 * totalCellCount ) ;
2012-09-11 02:22:36 -05:00
caf : : ProgressInfo progInfo ( 3 + numLGRs , " " ) ;
2012-06-26 09:10:41 -05:00
progInfo . setProgressDescription ( " Main Grid " ) ;
2012-09-11 02:22:36 -05:00
progInfo . setNextProgressIncrement ( 3 ) ;
2012-06-26 09:10:41 -05:00
2013-03-13 05:50:31 -05:00
transferGridCellData ( mainGrid , activeCellInfo , fractureActiveCellInfo , mainGrid , mainEclGrid , 0 , 0 ) ;
2012-05-18 02:45:23 -05:00
2012-09-11 02:22:36 -05:00
progInfo . setProgress ( 3 ) ;
2012-06-26 09:10:41 -05:00
2013-01-30 02:30:48 -06:00
size_t globalMatrixActiveSize = ecl_grid_get_nactive ( mainEclGrid ) ;
size_t globalFractureActiveSize = ecl_grid_get_nactive_fracture ( mainEclGrid ) ;
2012-05-18 02:45:23 -05:00
2013-02-12 04:15:36 -06:00
activeCellInfo - > setGridCount ( 1 + numLGRs ) ;
2013-03-13 05:50:31 -05:00
fractureActiveCellInfo - > setGridCount ( 1 + numLGRs ) ;
2013-02-12 04:15:36 -06:00
2013-03-13 05:50:31 -05:00
activeCellInfo - > setGridActiveCellCounts ( 0 , globalMatrixActiveSize ) ;
fractureActiveCellInfo - > setGridActiveCellCounts ( 0 , globalFractureActiveSize ) ;
2013-05-21 04:10:59 -05:00
transferCoarseningInfo ( mainEclGrid , mainGrid ) ;
2013-02-01 08:33:21 -06:00
2012-05-18 02:45:23 -05:00
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 ) ;
2013-02-01 08:33:21 -06:00
RigLocalGrid * localGrid = static_cast < RigLocalGrid * > ( mainGrid - > gridByIndex ( lgrIdx + 1 ) ) ;
2013-03-13 05:50:31 -05:00
transferGridCellData ( mainGrid , activeCellInfo , fractureActiveCellInfo , localGrid , localEclGrid , globalMatrixActiveSize , globalFractureActiveSize ) ;
2013-02-12 04:15:36 -06:00
int matrixActiveCellCount = ecl_grid_get_nactive ( localEclGrid ) ;
globalMatrixActiveSize + = matrixActiveCellCount ;
2013-02-01 08:33:21 -06:00
2013-02-12 04:15:36 -06:00
int fractureActiveCellCount = ecl_grid_get_nactive_fracture ( localEclGrid ) ;
globalFractureActiveSize + = fractureActiveCellCount ;
2013-02-01 08:33:21 -06:00
2013-03-13 05:50:31 -05:00
activeCellInfo - > setGridActiveCellCounts ( lgrIdx + 1 , matrixActiveCellCount ) ;
fractureActiveCellInfo - > setGridActiveCellCounts ( lgrIdx + 1 , fractureActiveCellCount ) ;
2013-05-21 04:10:59 -05:00
transferCoarseningInfo ( localEclGrid , localGrid ) ;
2012-09-11 02:22:36 -05:00
progInfo . setProgress ( 3 + lgrIdx ) ;
2012-05-18 02:45:23 -05:00
}
2013-02-12 04:15:36 -06:00
activeCellInfo - > computeDerivedData ( ) ;
2013-03-13 05:50:31 -05:00
fractureActiveCellInfo - > computeDerivedData ( ) ;
2013-02-12 04:15:36 -06:00
2012-05-18 02:45:23 -05:00
return true ;
}
//--------------------------------------------------------------------------------------------------
/// Open file and read geometry into given reservoir object
//--------------------------------------------------------------------------------------------------
2017-01-10 02:51:39 -06:00
bool RifReaderEclipseOutput : : open ( const QString & fileName , RigEclipseCaseData * eclipseCase )
2012-05-18 02:45:23 -05:00
{
2013-02-13 06:24:39 -06:00
CVF_ASSERT ( eclipseCase ) ;
2013-02-06 06:44:27 -06:00
caf : : ProgressInfo progInfo ( 100 , " " ) ;
2012-06-26 09:10:41 -05:00
progInfo . setProgressDescription ( " Reading Grid " ) ;
2012-05-18 02:45:23 -05:00
// Make sure everything's closed
close ( ) ;
// Get set of files
QStringList fileSet ;
2013-04-10 04:02:10 -05:00
if ( ! RifEclipseOutputFileTools : : findSiblingFilesWithSameBaseName ( fileName , & fileSet ) ) return false ;
2013-02-06 06:44:27 -06:00
progInfo . incrementProgress ( ) ;
2012-06-26 09:10:41 -05:00
2013-02-06 06:44:27 -06:00
progInfo . setNextProgressIncrement ( 20 ) ;
2012-05-18 02:45:23 -05:00
// Keep the set of files of interest
2013-04-10 04:02:10 -05:00
m_filesWithSameBaseName = fileSet ;
2012-05-18 02:45:23 -05:00
// Read geometry
2013-08-26 14:56:40 -05:00
// Todo: Needs to check existence of file before calling ert, else it will abort
2012-06-26 09:10:41 -05:00
ecl_grid_type * mainEclGrid = ecl_grid_alloc ( fileName . toAscii ( ) . data ( ) ) ;
2013-02-06 06:44:27 -06:00
progInfo . incrementProgress ( ) ;
progInfo . setNextProgressIncrement ( 10 ) ;
2012-06-26 09:10:41 -05:00
progInfo . setProgressDescription ( " Transferring grid geometry " ) ;
2013-02-13 06:24:39 -06:00
if ( ! transferGeometry ( mainEclGrid , eclipseCase ) ) return false ;
2013-12-03 13:30:32 -06:00
progInfo . incrementProgress ( ) ;
progInfo . setProgressDescription ( " Reading faults " ) ;
progInfo . setNextProgressIncrement ( 10 ) ;
2013-12-20 02:18:52 -06:00
if ( isFaultImportEnabled ( ) )
2013-12-03 13:30:32 -06:00
{
2016-10-21 01:48:33 -05:00
cvf : : Collection < RigFault > faults ;
2013-12-17 04:37:58 -06:00
2016-10-21 02:33:03 -05:00
importFaults ( fileSet , & faults ) ;
2014-01-08 03:07:42 -06:00
2016-10-21 01:48:33 -05:00
RigMainGrid * mainGrid = eclipseCase - > mainGrid ( ) ;
mainGrid - > setFaults ( faults ) ;
2013-12-17 04:37:58 -06:00
}
2013-12-03 13:30:32 -06:00
2013-02-06 06:44:27 -06:00
progInfo . incrementProgress ( ) ;
2013-08-26 06:56:42 -05:00
m_eclipseCase = eclipseCase ;
2012-06-26 09:10:41 -05:00
2012-05-18 02:45:23 -05:00
// Build results meta data
2013-12-11 07:55:14 -06:00
progInfo . setProgressDescription ( " Reading Result index " ) ;
progInfo . setNextProgressIncrement ( 25 ) ;
2013-04-22 06:24:49 -05:00
buildMetaData ( ) ;
2013-12-11 07:55:14 -06:00
progInfo . incrementProgress ( ) ;
2012-05-18 02:45:23 -05:00
2014-07-30 02:13:47 -05:00
if ( isNNCsEnabled ( ) )
{
2014-11-06 02:35:39 -06:00
progInfo . setProgressDescription ( " Reading NNC data " ) ;
progInfo . setNextProgressIncrement ( 5 ) ;
2014-07-30 02:13:47 -05:00
transferNNCData ( mainEclGrid , m_ecl_init_file , eclipseCase - > mainGrid ( ) ) ;
2014-11-06 02:35:39 -06:00
progInfo . incrementProgress ( ) ;
2013-12-03 13:30:32 -06:00
2014-11-06 02:35:39 -06:00
progInfo . setProgressDescription ( " Processing NNC data " ) ;
progInfo . setNextProgressIncrement ( 20 ) ;
2014-07-30 02:13:47 -05:00
eclipseCase - > mainGrid ( ) - > nncData ( ) - > processConnections ( * ( eclipseCase - > mainGrid ( ) ) ) ;
2014-11-06 02:35:39 -06:00
progInfo . incrementProgress ( ) ;
}
else
{
progInfo . setNextProgressIncrement ( 25 ) ;
progInfo . incrementProgress ( ) ;
2014-07-30 02:13:47 -05:00
}
2013-12-11 07:55:14 -06:00
2013-02-06 06:44:27 -06:00
progInfo . setNextProgressIncrement ( 8 ) ;
2012-06-26 09:10:41 -05:00
progInfo . setProgressDescription ( " Reading Well information " ) ;
2014-10-24 04:38:47 -05:00
readWellCells ( mainEclGrid , isImportOfCompleteMswDataEnabled ( ) ) ;
2014-11-06 02:35:39 -06:00
progInfo . incrementProgress ( ) ;
2013-02-05 03:51:32 -06:00
2013-08-26 06:56:42 -05:00
progInfo . setProgressDescription ( " Releasing reader memory " ) ;
ecl_grid_free ( mainEclGrid ) ;
progInfo . incrementProgress ( ) ;
2013-02-05 03:51:32 -06:00
2012-05-18 02:45:23 -05:00
return true ;
}
2016-10-21 01:48:33 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseOutput : : importFaults ( const QStringList & fileSet , cvf : : Collection < RigFault > * faults )
{
if ( this - > filenamesWithFaults ( ) . size ( ) > 0 )
{
for ( size_t i = 0 ; i < this - > filenamesWithFaults ( ) . size ( ) ; i + + )
{
QString faultFilename = this - > filenamesWithFaults ( ) [ i ] ;
2016-10-21 02:33:03 -05:00
RifEclipseInputFileTools : : parseAndReadFaults ( faultFilename , faults ) ;
2016-10-21 01:48:33 -05:00
}
}
else
{
foreach ( QString fname , fileSet )
{
if ( fname . endsWith ( " .DATA " ) )
{
std : : vector < QString > filenamesWithFaults ;
2017-04-18 04:32:04 -05:00
RifEclipseInputFileTools : : readFaultsInGridSection ( fname , faults , & filenamesWithFaults , faultIncludeFileAbsolutePathPrefix ( ) ) ;
2016-10-21 01:48:33 -05:00
std : : sort ( filenamesWithFaults . begin ( ) , filenamesWithFaults . end ( ) ) ;
std : : vector < QString > : : iterator last = std : : unique ( filenamesWithFaults . begin ( ) , filenamesWithFaults . end ( ) ) ;
filenamesWithFaults . erase ( last , filenamesWithFaults . end ( ) ) ;
this - > setFilenamesWithFaults ( filenamesWithFaults ) ;
}
}
}
}
2016-10-21 02:33:03 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-12-10 15:44:40 -06:00
void RifReaderEclipseOutput : : transferNNCData ( const ecl_grid_type * mainEclGrid , const ecl_file_type * init_file , RigMainGrid * mainGrid )
{
if ( ! m_ecl_init_file ) return ;
CVF_ASSERT ( mainEclGrid & & mainGrid ) ;
// Get the data from ERT
int numNNC = ecl_nnc_export_get_size ( mainEclGrid ) ;
2015-02-24 07:57:23 -06:00
if ( numNNC > 0 )
{
ecl_nnc_type * eclNNCData = new ecl_nnc_type [ numNNC ] ;
2013-12-10 15:44:40 -06:00
2015-02-24 07:57:23 -06:00
ecl_nnc_export ( mainEclGrid , init_file , eclNNCData ) ;
2013-12-10 15:44:40 -06:00
2015-02-24 07:57:23 -06:00
// Transform to our own datastructures
//cvf::Trace::show("Reading NNC. Count: " + cvf::String(numNNC));
2013-12-10 15:44:40 -06:00
2015-02-24 07:57:23 -06:00
mainGrid - > nncData ( ) - > connections ( ) . resize ( numNNC ) ;
std : : vector < double > & transmissibilityValues = mainGrid - > nncData ( ) - > makeConnectionScalarResult ( cvf : : UNDEFINED_SIZE_T ) ;
for ( int nIdx = 0 ; nIdx < numNNC ; + + nIdx )
{
RigGridBase * grid1 = mainGrid - > gridByIndex ( eclNNCData [ nIdx ] . grid_nr1 ) ;
mainGrid - > nncData ( ) - > connections ( ) [ nIdx ] . m_c1GlobIdx = grid1 - > reservoirCellIndex ( eclNNCData [ nIdx ] . global_index1 ) ;
RigGridBase * grid2 = mainGrid - > gridByIndex ( eclNNCData [ nIdx ] . grid_nr2 ) ;
mainGrid - > nncData ( ) - > connections ( ) [ nIdx ] . m_c2GlobIdx = grid2 - > reservoirCellIndex ( eclNNCData [ nIdx ] . global_index2 ) ;
transmissibilityValues [ nIdx ] = eclNNCData [ nIdx ] . trans ;
}
2013-12-10 15:44:40 -06:00
2015-02-24 07:57:23 -06:00
delete [ ] eclNNCData ;
}
2013-12-10 15:44:40 -06:00
}
2013-02-27 04:27:02 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-01-10 02:51:39 -06:00
bool RifReaderEclipseOutput : : openAndReadActiveCellData ( const QString & fileName , const std : : vector < QDateTime > & mainCaseTimeSteps , RigEclipseCaseData * eclipseCase )
2013-02-27 04:27:02 -06:00
{
CVF_ASSERT ( eclipseCase ) ;
2013-02-27 04:54:32 -06:00
// It is required to have a main grid before reading active cell data
if ( ! eclipseCase - > mainGrid ( ) )
{
return false ;
}
2013-02-27 04:27:02 -06:00
close ( ) ;
// Get set of files
QStringList fileSet ;
2013-04-10 04:02:10 -05:00
if ( ! RifEclipseOutputFileTools : : findSiblingFilesWithSameBaseName ( fileName , & fileSet ) ) return false ;
2013-02-27 04:27:02 -06:00
// Keep the set of files of interest
2013-04-10 04:02:10 -05:00
m_filesWithSameBaseName = fileSet ;
2013-02-27 07:13:37 -06:00
m_eclipseCase = eclipseCase ;
2013-02-27 04:27:02 -06:00
2013-02-27 07:13:37 -06:00
if ( ! readActiveCellInfo ( ) )
2013-02-27 04:54:32 -06:00
{
return false ;
}
2013-02-27 04:27:02 -06:00
2013-04-10 04:02:10 -05:00
m_dynamicResultsAccess = createDynamicResultsAccess ( ) ;
2013-04-22 06:24:49 -05:00
if ( m_dynamicResultsAccess . notNull ( ) )
{
m_dynamicResultsAccess - > setTimeSteps ( mainCaseTimeSteps ) ;
}
2013-03-05 06:10:26 -06:00
2013-02-27 04:27:02 -06:00
return true ;
}
//--------------------------------------------------------------------------------------------------
///
2013-03-07 06:13:34 -06:00
/// See also RigStatistics::computeActiveCellUnion()
2013-02-27 04:27:02 -06:00
//--------------------------------------------------------------------------------------------------
2013-02-27 07:13:37 -06:00
bool RifReaderEclipseOutput : : readActiveCellInfo ( )
2013-02-27 04:27:02 -06:00
{
2013-03-08 01:24:40 -06:00
CVF_ASSERT ( m_eclipseCase ) ;
2013-02-27 07:13:37 -06:00
CVF_ASSERT ( m_eclipseCase - > mainGrid ( ) ) ;
2013-02-27 04:27:02 -06:00
2013-04-10 04:02:10 -05:00
QString egridFileName = RifEclipseOutputFileTools : : firstFileNameOfType ( m_filesWithSameBaseName , ECL_EGRID_FILE ) ;
2013-02-27 04:27:02 -06:00
if ( egridFileName . size ( ) > 0 )
{
2013-04-29 06:13:42 -05:00
ecl_file_type * ecl_file = ecl_file_open ( egridFileName . toAscii ( ) . data ( ) , ECL_FILE_CLOSE_STREAM ) ;
2013-02-27 04:27:02 -06:00
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 ) ;
2014-08-08 03:45:52 -05:00
size_t reservoirCellCount = 0 ;
2013-03-02 03:18:27 -06:00
for ( size_t gridIdx = 0 ; gridIdx < static_cast < size_t > ( actnumKeywordCount ) ; gridIdx + + )
2013-02-27 04:27:02 -06:00
{
RifEclipseOutputFileTools : : keywordData ( ecl_file , ACTNUM_KW , gridIdx , & actnumValuesPerGrid [ gridIdx ] ) ;
2014-08-08 03:45:52 -05:00
reservoirCellCount + = actnumValuesPerGrid [ gridIdx ] . size ( ) ;
2013-02-27 04:27:02 -06:00
}
2013-02-27 04:54:32 -06:00
// Check if number of cells is matching
2015-11-24 07:21:02 -06:00
if ( m_eclipseCase - > mainGrid ( ) - > globalCellArray ( ) . size ( ) ! = reservoirCellCount )
2013-02-27 04:54:32 -06:00
{
return false ;
}
2013-03-13 05:50:31 -05:00
RigActiveCellInfo * activeCellInfo = m_eclipseCase - > activeCellInfo ( RifReaderInterface : : MATRIX_RESULTS ) ;
RigActiveCellInfo * fractureActiveCellInfo = m_eclipseCase - > activeCellInfo ( RifReaderInterface : : FRACTURE_RESULTS ) ;
2013-02-27 04:27:02 -06:00
2014-08-08 03:45:52 -05:00
activeCellInfo - > setReservoirCellCount ( reservoirCellCount ) ;
fractureActiveCellInfo - > setReservoirCellCount ( reservoirCellCount ) ;
2013-02-27 04:27:02 -06:00
activeCellInfo - > setGridCount ( actnumKeywordCount ) ;
2013-03-13 05:50:31 -05:00
fractureActiveCellInfo - > setGridCount ( actnumKeywordCount ) ;
2013-02-27 04:27:02 -06:00
size_t cellIdx = 0 ;
2013-03-07 06:13:34 -06:00
size_t globalActiveMatrixIndex = 0 ;
size_t globalActiveFractureIndex = 0 ;
2013-03-02 03:18:27 -06:00
for ( size_t gridIdx = 0 ; gridIdx < static_cast < size_t > ( actnumKeywordCount ) ; gridIdx + + )
2013-02-27 04:27:02 -06: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-22 03:32:42 -05:00
activeCellInfo - > setCellResultIndex ( cellIdx , globalActiveMatrixIndex + + ) ;
2013-03-07 06:13:34 -06:00
activeMatrixIndex + + ;
2013-02-27 04:27:02 -06:00
}
if ( actnumValues [ i ] = = 2 | | actnumValues [ i ] = = 3 )
{
2013-03-22 03:32:42 -05:00
fractureActiveCellInfo - > setCellResultIndex ( cellIdx , globalActiveFractureIndex + + ) ;
2013-03-07 06:13:34 -06:00
activeFractureIndex + + ;
2013-02-27 04:27:02 -06:00
}
cellIdx + + ;
}
2013-03-13 05:50:31 -05:00
activeCellInfo - > setGridActiveCellCounts ( gridIdx , activeMatrixIndex ) ;
fractureActiveCellInfo - > setGridActiveCellCounts ( gridIdx , activeFractureIndex ) ;
2013-02-27 04:27:02 -06:00
}
activeCellInfo - > computeDerivedData ( ) ;
2013-03-13 05:50:31 -05:00
fractureActiveCellInfo - > computeDerivedData ( ) ;
2013-02-27 04:27:02 -06:00
}
ecl_file_close ( ecl_file ) ;
return true ;
}
return false ;
}
2012-05-18 02:45:23 -05:00
//--------------------------------------------------------------------------------------------------
/// Build meta data - get states and results info
//--------------------------------------------------------------------------------------------------
2013-04-22 06:24:49 -05:00
void RifReaderEclipseOutput : : buildMetaData ( )
2012-05-18 02:45:23 -05:00
{
2013-03-08 01:24:40 -06:00
CVF_ASSERT ( m_eclipseCase ) ;
2013-04-10 04:02:10 -05:00
CVF_ASSERT ( m_filesWithSameBaseName . size ( ) > 0 ) ;
2012-05-18 02:45:23 -05:00
2013-04-10 04:02:10 -05:00
caf : : ProgressInfo progInfo ( m_filesWithSameBaseName . size ( ) + 3 , " " ) ;
2013-02-06 06:44:27 -06:00
2013-04-10 04:02:10 -05:00
progInfo . setNextProgressIncrement ( m_filesWithSameBaseName . size ( ) ) ;
2012-06-26 09:10:41 -05:00
2013-04-22 07:51:47 -05:00
RigCaseCellResultsData * matrixModelResults = m_eclipseCase - > results ( RifReaderInterface : : MATRIX_RESULTS ) ;
RigCaseCellResultsData * fractureModelResults = m_eclipseCase - > results ( RifReaderInterface : : FRACTURE_RESULTS ) ;
2012-05-18 02:45:23 -05:00
// Create access object for dynamic results
2013-04-10 04:02:10 -05:00
m_dynamicResultsAccess = createDynamicResultsAccess ( ) ;
2013-04-22 07:51:47 -05:00
if ( m_dynamicResultsAccess . notNull ( ) )
2013-01-30 07:13:50 -06:00
{
2013-04-22 07:51:47 -05:00
m_dynamicResultsAccess - > open ( ) ;
2013-03-05 06:10:26 -06:00
2013-04-22 07:51:47 -05:00
progInfo . incrementProgress ( ) ;
2013-02-06 06:44:27 -06:00
2012-06-26 09:10:41 -05:00
// Get time steps
2012-05-18 02:45:23 -05:00
m_timeSteps = m_dynamicResultsAccess - > timeSteps ( ) ;
2017-01-12 05:04:54 -06:00
std : : vector < int > reportNumbers = m_dynamicResultsAccess - > reportNumbers ( ) ;
2012-05-18 02:45:23 -05:00
2013-02-05 03:51:32 -06:00
QStringList resultNames ;
std : : vector < size_t > resultNamesDataItemCounts ;
m_dynamicResultsAccess - > resultNames ( & resultNames , & resultNamesDataItemCounts ) ;
2013-02-01 07:39:32 -06:00
{
2013-03-13 05:50:31 -05: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 07:39:32 -06:00
2013-02-05 03:51:32 -06:00
for ( int i = 0 ; i < matrixResultNames . size ( ) ; + + i )
2013-02-01 07:39:32 -06:00
{
2013-03-21 09:31:47 -05:00
size_t resIndex = matrixModelResults - > addEmptyScalarResult ( RimDefines : : DYNAMIC_NATIVE , matrixResultNames [ i ] , false ) ;
2017-01-12 05:04:54 -06:00
matrixModelResults - > setTimeStepDates ( resIndex , m_timeSteps , reportNumbers ) ;
2013-02-01 07:39:32 -06:00
}
}
2012-06-26 09:10:41 -05:00
{
2013-03-13 05:50:31 -05: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 07:39:32 -06:00
2013-02-05 03:51:32 -06:00
for ( int i = 0 ; i < fractureResultNames . size ( ) ; + + i )
2013-02-01 07:39:32 -06:00
{
2013-03-21 09:31:47 -05:00
size_t resIndex = fractureModelResults - > addEmptyScalarResult ( RimDefines : : DYNAMIC_NATIVE , fractureResultNames [ i ] , false ) ;
2017-01-12 05:04:54 -06:00
fractureModelResults - > setTimeStepDates ( resIndex , m_timeSteps , reportNumbers ) ;
2013-02-01 07:39:32 -06:00
}
2012-06-26 09:10:41 -05:00
}
2014-08-27 07:05:29 -05:00
// Default units type is METRIC
2017-01-10 02:51:39 -06:00
RigEclipseCaseData : : UnitsType unitsType = RigEclipseCaseData : : UNITS_METRIC ;
2014-08-27 07:05:29 -05:00
{
int unitsTypeValue = m_dynamicResultsAccess - > readUnitsType ( ) ;
if ( unitsTypeValue = = 2 )
{
2017-01-10 02:51:39 -06:00
unitsType = RigEclipseCaseData : : UNITS_FIELD ;
2014-08-27 07:05:29 -05:00
}
else if ( unitsTypeValue = = 3 )
{
2017-01-10 02:51:39 -06:00
unitsType = RigEclipseCaseData : : UNITS_LAB ;
2014-08-27 07:05:29 -05:00
}
}
m_eclipseCase - > setUnitsType ( unitsType ) ;
2012-05-18 02:45:23 -05:00
}
2013-02-06 06:44:27 -06:00
progInfo . incrementProgress ( ) ;
2012-06-26 09:10:41 -05:00
2013-03-05 06:10:26 -06:00
openInitFile ( ) ;
2013-02-27 07:13:37 -06:00
progInfo . incrementProgress ( ) ;
2013-02-05 03:51:32 -06:00
2013-03-05 06:10:26 -06:00
if ( m_ecl_init_file )
2013-02-27 07:13:37 -06:00
{
2013-03-05 06:10:26 -06:00
QStringList resultNames ;
std : : vector < size_t > resultNamesDataItemCounts ;
2016-07-14 06:35:32 -05:00
std : : vector < ecl_file_type * > filesUsedToFindAvailableKeywords ;
filesUsedToFindAvailableKeywords . push_back ( m_ecl_init_file ) ;
RifEclipseOutputFileTools : : findKeywordsAndItemCount ( filesUsedToFindAvailableKeywords , & resultNames , & resultNamesDataItemCounts ) ;
2012-08-31 12:12:47 -05:00
2017-01-12 05:04:54 -06:00
std : : vector < QDateTime > staticDate ;
std : : vector < int > staticReportNumber ;
2012-06-26 09:10:41 -05:00
{
2017-01-12 05:04:54 -06:00
if ( m_timeSteps . size ( ) > 0 )
2013-03-05 06:10:26 -06:00
{
staticDate . push_back ( m_timeSteps . front ( ) ) ;
}
2013-02-01 07:39:32 -06:00
2017-04-05 04:48:48 -05:00
std : : vector < int > reportNumbers ;
if ( m_dynamicResultsAccess . notNull ( ) )
{
reportNumbers = m_dynamicResultsAccess - > reportNumbers ( ) ;
}
2017-01-12 05:04:54 -06:00
if ( reportNumbers . size ( ) > 0 )
{
staticReportNumber . push_back ( reportNumbers . front ( ) ) ;
}
}
{
QStringList matrixResultNames = validKeywordsForPorosityModel ( resultNames , resultNamesDataItemCounts ,
m_eclipseCase - > activeCellInfo ( RifReaderInterface : : MATRIX_RESULTS ) ,
m_eclipseCase - > activeCellInfo ( RifReaderInterface : : FRACTURE_RESULTS ) ,
RifReaderInterface : : MATRIX_RESULTS , 1 ) ;
2013-08-26 14:56:40 -05:00
// Add ACTNUM
matrixResultNames + = " ACTNUM " ;
2013-03-05 06:10:26 -06:00
for ( int i = 0 ; i < matrixResultNames . size ( ) ; + + i )
{
2013-03-21 09:31:47 -05:00
size_t resIndex = matrixModelResults - > addEmptyScalarResult ( RimDefines : : STATIC_NATIVE , matrixResultNames [ i ] , false ) ;
2017-01-12 05:04:54 -06:00
matrixModelResults - > setTimeStepDates ( resIndex , staticDate , staticReportNumber ) ;
2013-03-05 06:10:26 -06:00
}
2012-06-26 09:10:41 -05:00
}
2012-05-18 02:45:23 -05:00
2013-02-27 07:13:37 -06:00
{
2013-03-13 05:50:31 -05:00
QStringList fractureResultNames = validKeywordsForPorosityModel ( resultNames , resultNamesDataItemCounts ,
m_eclipseCase - > activeCellInfo ( RifReaderInterface : : MATRIX_RESULTS ) ,
m_eclipseCase - > activeCellInfo ( RifReaderInterface : : FRACTURE_RESULTS ) ,
RifReaderInterface : : FRACTURE_RESULTS , 1 ) ;
2013-08-26 14:56:40 -05:00
// Add ACTNUM
fractureResultNames + = " ACTNUM " ;
2013-03-05 06:10:26 -06:00
for ( int i = 0 ; i < fractureResultNames . size ( ) ; + + i )
{
2013-03-21 09:31:47 -05:00
size_t resIndex = fractureModelResults - > addEmptyScalarResult ( RimDefines : : STATIC_NATIVE , fractureResultNames [ i ] , false ) ;
2017-01-12 05:04:54 -06:00
fractureModelResults - > setTimeStepDates ( resIndex , staticDate , staticReportNumber ) ;
2013-03-05 06:10:26 -06:00
}
2013-02-27 07:13:37 -06:00
}
2012-05-18 02:45:23 -05:00
}
}
//--------------------------------------------------------------------------------------------------
/// Create results access object (.UNRST or .X0001 ... .XNNNN)
//--------------------------------------------------------------------------------------------------
2013-04-10 04:02:10 -05:00
RifEclipseRestartDataAccess * RifReaderEclipseOutput : : createDynamicResultsAccess ( )
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
// Look for unified restart file
2013-04-10 04:02:10 -05:00
QString unrstFileName = RifEclipseOutputFileTools : : firstFileNameOfType ( m_filesWithSameBaseName , ECL_UNIFIED_RESTART_FILE ) ;
2012-05-18 02:45:23 -05:00
if ( unrstFileName . size ( ) > 0 )
{
2013-01-30 07:13:50 -06:00
resultsAccess = new RifEclipseUnifiedRestartFileAccess ( ) ;
2013-04-10 04:02:10 -05:00
resultsAccess - > setRestartFiles ( QStringList ( unrstFileName ) ) ;
2012-05-18 02:45:23 -05:00
}
else
{
// Look for set of restart files (one file per time step)
2013-04-10 04:02:10 -05:00
QStringList restartFiles = RifEclipseOutputFileTools : : filterFileNamesOfType ( m_filesWithSameBaseName , ECL_RESTART_FILE ) ;
2012-05-18 02:45:23 -05:00
if ( restartFiles . size ( ) > 0 )
{
2013-01-30 07:13:50 -06:00
resultsAccess = new RifEclipseRestartFilesetAccess ( ) ;
2013-04-10 04:02:10 -05:00
resultsAccess - > setRestartFiles ( restartFiles ) ;
2012-05-18 02:45:23 -05:00
}
}
return resultsAccess ;
}
//--------------------------------------------------------------------------------------------------
/// Get all values of a given static result as doubles
//--------------------------------------------------------------------------------------------------
2013-01-30 07:13:50 -06:00
bool RifReaderEclipseOutput : : staticResult ( const QString & result , PorosityModelResultType matrixOrFracture , std : : vector < double > * values )
2012-05-18 02:45:23 -05:00
{
CVF_ASSERT ( values ) ;
2013-02-27 07:13:37 -06:00
2013-08-26 14:56:40 -05:00
if ( result . compare ( " ACTNUM " , Qt : : CaseInsensitive ) = = 0 )
{
RigActiveCellInfo * activeCellInfo = m_eclipseCase - > activeCellInfo ( matrixOrFracture ) ;
2014-08-08 03:27:29 -05:00
values - > resize ( activeCellInfo - > reservoirActiveCellCount ( ) , 1.0 ) ;
2013-08-26 14:56:40 -05:00
return true ;
}
2013-04-22 07:51:47 -05:00
openInitFile ( ) ;
2013-02-27 07:13:37 -06:00
2013-04-22 07:51:47 -05:00
if ( m_ecl_init_file )
{
std : : vector < double > fileValues ;
2013-02-05 03:51:32 -06:00
2013-04-22 07:51:47 -05:00
size_t numOccurrences = ecl_file_get_num_named_kw ( m_ecl_init_file , result . toAscii ( ) . data ( ) ) ;
size_t i ;
for ( i = 0 ; i < numOccurrences ; i + + )
{
std : : vector < double > partValues ;
RifEclipseOutputFileTools : : keywordData ( m_ecl_init_file , result , i , & partValues ) ;
fileValues . insert ( fileValues . end ( ) , partValues . begin ( ) , partValues . end ( ) ) ;
}
2012-05-18 02:45:23 -05:00
2013-04-22 07:51:47 -05:00
extractResultValuesBasedOnPorosityModel ( matrixOrFracture , values , fileValues ) ;
2012-05-18 02:45:23 -05:00
}
return true ;
}
//--------------------------------------------------------------------------------------------------
/// Get dynamic result at given step index. Will concatenate values for the main grid and all sub grids.
//--------------------------------------------------------------------------------------------------
2013-01-30 07:13:50 -06:00
bool RifReaderEclipseOutput : : dynamicResult ( const QString & result , PorosityModelResultType matrixOrFracture , size_t stepIndex , std : : vector < double > * values )
2012-05-18 02:45:23 -05:00
{
2013-03-05 06:10:26 -06:00
if ( m_dynamicResultsAccess . isNull ( ) )
{
2013-04-10 04:02:10 -05:00
m_dynamicResultsAccess = createDynamicResultsAccess ( ) ;
2013-03-05 06:10:26 -06:00
}
2013-04-22 06:24:49 -05:00
if ( m_dynamicResultsAccess . notNull ( ) )
2013-03-05 06:10:26 -06:00
{
2013-04-22 06:24:49 -05:00
std : : vector < double > fileValues ;
if ( ! m_dynamicResultsAccess - > results ( result , stepIndex , m_eclipseCase - > mainGrid ( ) - > gridCount ( ) , & fileValues ) )
{
return false ;
}
2013-02-05 03:51:32 -06:00
2013-04-22 06:24:49 -05:00
extractResultValuesBasedOnPorosityModel ( matrixOrFracture , values , fileValues ) ;
2013-02-05 03:51:32 -06:00
}
return true ;
2012-05-18 02:45:23 -05:00
}
2013-08-26 06:56:42 -05:00
2013-08-28 08:36:29 -05:00
//--------------------------------------------------------------------------------------------------
/// Helper struct to store info on how a well-to-grid connection contributes to the position of
/// well segments without any connections.
//--------------------------------------------------------------------------------------------------
2013-08-26 07:56:34 -05:00
struct SegmentPositionContribution
{
SegmentPositionContribution ( int connectionSegmentId ,
cvf : : Vec3d connectionPosition ,
double lengthFromConnection ,
2013-08-26 08:28:34 -05:00
bool isInsolating ,
int segmentIdUnder ,
int segmentIdAbove ,
bool isFromAbove )
2013-08-26 07:56:34 -05:00
: m_connectionSegmentId ( connectionSegmentId ) ,
m_lengthFromConnection ( lengthFromConnection ) ,
2013-08-26 08:28:34 -05:00
m_isInsolating ( isInsolating ) ,
2013-08-26 07:56:34 -05:00
m_connectionPosition ( connectionPosition ) ,
2013-08-26 08:28:34 -05:00
m_segmentIdUnder ( segmentIdUnder ) ,
m_segmentIdAbove ( segmentIdAbove ) ,
m_isFromAbove ( isFromAbove )
2013-08-26 07:56:34 -05:00
{ }
int m_connectionSegmentId ;
double m_lengthFromConnection ;
2013-08-26 08:28:34 -05:00
bool m_isInsolating ;
2013-08-26 07:56:34 -05:00
cvf : : Vec3d m_connectionPosition ;
int m_segmentIdUnder ;
2013-08-26 08:28:34 -05:00
int m_segmentIdAbove ;
bool m_isFromAbove ;
2013-08-26 07:56:34 -05:00
} ;
2013-08-26 07:03:01 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-09-08 08:21:40 -05:00
RigWellResultPoint RifReaderEclipseOutput : : createWellResultPoint ( const RigGridBase * grid , const well_conn_type * ert_connection , int ertBranchId , int ertSegmentId , const char * wellName )
2013-08-26 07:03:01 -05:00
{
CVF_ASSERT ( ert_connection ) ;
CVF_ASSERT ( grid ) ;
int cellI = well_conn_get_i ( ert_connection ) ;
int cellJ = well_conn_get_j ( ert_connection ) ;
int cellK = well_conn_get_k ( ert_connection ) ;
bool isCellOpen = well_conn_open ( ert_connection ) ;
2017-02-07 06:47:00 -06:00
double volumeRate = well_conn_get_volume_rate ( ert_connection ) ;
2013-08-26 07:03:01 -05: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
if ( cellK > = static_cast < int > ( grid - > cellCountK ( ) ) )
{
cellK - = static_cast < int > ( grid - > cellCountK ( ) ) ;
}
2016-09-08 08:21:40 -05:00
// See description for keyword ICON at page 54/55 of Rile Formats Reference Manual 2010.2
/*
Integer completion data array
ICON ( NICONZ , NCWMAX , NWELLS ) with dimensions
defined by INTEHEAD . The following items are required for each completion in each well :
Item 1 - Well connection index ICON ( 1 , IC , IWELL ) = IC ( set to - IC if connection is not in current LGR )
Item 2 - I - coordinate ( < = 0 if not in this LGR )
Item 3 - J - coordinate ( < = 0 if not in this LGR )
Item 4 - K - coordinate ( < = 0 if not in this LGR )
Item 6 - Connection status > 0 open , < = 0 shut
Item 14 - Penetration direction ( 1 = x , 2 = y , 3 = z , 4 = fractured in x - direction , 5 = fractured in y - direction )
If undefined or zero , assume Z
Item 15 - Segment number containing connection ( for multi - segment wells , = 0 for ordinary wells )
Undefined items in this array may be set to zero .
*/
2013-08-26 07:03:01 -05:00
// The K value might also be -1. It is not yet known why, or what it is supposed to mean,
// but for now we will interpret as 0.
// TODO: Ask Joakim Haave regarding this.
2016-09-08 08:21:40 -05:00
if ( cellK < 0 )
{
//cvf::Trace::show("Well Connection for grid " + cvf::String(grid->gridName()) + "\n - Detected negative K value (K=" + cvf::String(cellK) + ") for well : " + cvf::String(wellName) + " K clamped to 0");
cellK = 0 ;
}
2016-10-21 01:08:07 -05:00
RigWellResultPoint resultPoint ;
2016-09-08 08:21:40 -05:00
// Introduced based on discussion with H<> kon H<> gst<73> l 08.09.2016
2016-09-28 08:07:19 -05:00
if ( cellK > = static_cast < int > ( grid - > cellCountK ( ) ) )
2016-09-08 08:21:40 -05:00
{
2017-03-06 04:17:47 -06:00
int maxCellK = static_cast < int > ( grid - > cellCountK ( ) ) ;
cvf : : Trace : : show ( " Well Connection for grid " + cvf : : String ( grid - > gridName ( ) ) + " \n - Ignored connection with invalid K value (K= " + cvf : : String ( cellK ) + " , max K = " + cvf : : String ( maxCellK ) + " ) for well : " + cvf : : String ( wellName ) ) ;
2016-09-08 08:21:40 -05:00
}
2016-10-21 01:08:07 -05:00
else
{
resultPoint . m_gridIndex = grid - > gridIndex ( ) ;
resultPoint . m_gridCellIndex = grid - > cellIndexFromIJK ( cellI , cellJ , cellK ) ;
2013-08-26 07:03:01 -05:00
2016-10-21 01:08:07 -05:00
resultPoint . m_isOpen = isCellOpen ;
2013-08-26 07:03:01 -05:00
2016-10-21 01:08:07 -05:00
resultPoint . m_ertBranchId = ertBranchId ;
resultPoint . m_ertSegmentId = ertSegmentId ;
2017-02-07 06:47:00 -06:00
resultPoint . m_flowRate = volumeRate ;
2016-10-21 01:08:07 -05:00
}
2013-08-26 07:03:01 -05:00
return resultPoint ;
}
2013-08-26 07:56:34 -05:00
//--------------------------------------------------------------------------------------------------
2013-08-28 08:36:29 -05:00
/// Inverse distance interpolation of the supplied points and distance weights for
/// the contributing points which are closest above, and closest below
2013-08-26 07:56:34 -05:00
//--------------------------------------------------------------------------------------------------
2015-11-27 09:37:26 -06:00
cvf : : Vec3d interpolate3DPosition ( const std : : vector < SegmentPositionContribution > & positions )
2013-08-26 07:56:34 -05:00
{
2013-08-26 08:16:20 -05:00
std : : vector < SegmentPositionContribution > filteredPositions ;
filteredPositions . reserve ( positions . size ( ) ) ;
2013-08-26 08:28:34 -05:00
double minDistFromContribAbove = HUGE_VAL ;
double minDistFromContribBelow = HUGE_VAL ;
std : : vector < SegmentPositionContribution > contrFromAbove ;
std : : vector < SegmentPositionContribution > contrFromBelow ;
2013-08-26 08:16:20 -05:00
for ( size_t i = 0 ; i < positions . size ( ) ; i + + )
{
if ( positions [ i ] . m_connectionPosition ! = cvf : : Vec3d : : UNDEFINED )
{
2013-08-26 08:28:34 -05:00
if ( positions [ i ] . m_isFromAbove & & positions [ i ] . m_lengthFromConnection < minDistFromContribAbove )
{
if ( contrFromAbove . size ( ) ) contrFromAbove [ 0 ] = positions [ i ] ;
else contrFromAbove . push_back ( positions [ i ] ) ;
minDistFromContribAbove = positions [ i ] . m_lengthFromConnection ;
}
if ( ! positions [ i ] . m_isFromAbove & & positions [ i ] . m_lengthFromConnection < minDistFromContribBelow )
{
if ( contrFromBelow . size ( ) ) contrFromBelow [ 0 ] = positions [ i ] ;
else contrFromBelow . push_back ( positions [ i ] ) ;
minDistFromContribBelow = positions [ i ] . m_lengthFromConnection ;
}
2013-08-26 08:16:20 -05:00
}
}
2013-08-26 08:28:34 -05:00
filteredPositions = contrFromAbove ;
filteredPositions . insert ( filteredPositions . end ( ) , contrFromBelow . begin ( ) , contrFromBelow . end ( ) ) ;
2013-08-26 08:16:20 -05:00
std : : vector < double > nominators ( filteredPositions . size ( ) , 0.0 ) ;
2013-08-26 07:56:34 -05:00
double denominator = 0.0 ;
cvf : : Vec3d interpolatedValue = cvf : : Vec3d : : ZERO ;
2013-08-26 08:16:20 -05:00
for ( size_t i = 0 ; i < filteredPositions . size ( ) ; i + + )
2013-08-26 07:56:34 -05:00
{
#if 0 // Pure average test
nominators [ i ] = 1.0 ;
# else
2017-03-06 04:17:47 -06:00
double distance = filteredPositions [ i ] . m_lengthFromConnection ;
2013-08-26 07:56:34 -05:00
if ( distance < 1e-6 )
{
2013-08-26 08:16:20 -05:00
return filteredPositions [ i ] . m_connectionPosition ;
2013-08-26 07:56:34 -05:00
}
2013-08-26 08:22:55 -05:00
else if ( distance < 1.0 )
{
2013-08-26 08:28:34 -05:00
//distance = 1.0;
2013-08-26 08:22:55 -05:00
}
2013-08-26 07:56:34 -05:00
distance = 1.0 / distance ;
nominators [ i ] = distance ;
denominator + = distance ;
# endif
}
#if 0 // Pure average test
denominator = positions . size ( ) ; // Pure average test
# endif
2013-08-26 08:16:20 -05:00
for ( size_t i = 0 ; i < filteredPositions . size ( ) ; i + + )
2013-08-26 07:56:34 -05:00
{
2013-08-26 08:16:20 -05:00
interpolatedValue + = ( nominators [ i ] / denominator ) * filteredPositions [ i ] . m_connectionPosition ;
2013-08-26 07:56:34 -05:00
}
return interpolatedValue ;
}
2013-08-26 08:16:20 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-08-26 07:56:34 -05:00
void propagatePosContribDownwards ( std : : map < int , std : : vector < SegmentPositionContribution > > & segmentIdToPositionContrib ,
const well_segment_collection_type * allErtSegments ,
int ertSegmentId ,
std : : vector < SegmentPositionContribution > posContrib )
{
std : : map < int , std : : vector < SegmentPositionContribution > > : : iterator posContribIt ;
posContribIt = segmentIdToPositionContrib . find ( ertSegmentId ) ;
if ( posContribIt ! = segmentIdToPositionContrib . end ( ) )
{
// Create a set of the segments below this, that has to be followed.
std : : set < int > segmentIdsBelow ;
for ( size_t i = 0 ; i < posContribIt - > second . size ( ) ; + + i )
{
segmentIdsBelow . insert ( posContribIt - > second [ i ] . m_segmentIdUnder ) ;
}
2013-08-26 08:10:34 -05:00
// Get the segment length to add to the contributions
well_segment_type * segment = well_segment_collection_get ( allErtSegments , posContribIt - > first ) ;
double sementLength = well_segment_get_length ( segment ) ;
// If we do not have the contribution represented, add it, and accumulate the length
2013-08-26 07:56:34 -05:00
// If it is already present, do not touch
for ( size_t i = 0 ; i < posContrib . size ( ) ; + + i )
{
bool foundContribution = false ;
for ( size_t j = 0 ; j < posContribIt - > second . size ( ) ; + + j )
{
if ( posContribIt - > second [ j ] . m_connectionSegmentId = = posContrib [ i ] . m_connectionSegmentId )
{
foundContribution = true ;
break ;
}
}
if ( ! foundContribution )
{
posContrib [ i ] . m_lengthFromConnection + = sementLength ;
2013-08-26 08:28:34 -05:00
posContrib [ i ] . m_isFromAbove = true ;
2013-08-26 08:10:34 -05:00
posContribIt - > second . push_back ( posContrib [ i ] ) ;
2013-08-26 07:56:34 -05:00
}
2013-08-26 08:28:34 -05:00
posContrib [ i ] . m_segmentIdAbove = ertSegmentId ;
2013-08-26 07:56:34 -05:00
}
for ( std : : set < int > : : iterator it = segmentIdsBelow . begin ( ) ; it ! = segmentIdsBelow . end ( ) ; + + it )
{
propagatePosContribDownwards ( segmentIdToPositionContrib , allErtSegments , ( * it ) , posContrib ) ;
}
}
}
2013-08-26 06:56:42 -05:00
2012-05-18 02:45:23 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2014-10-24 04:19:54 -05:00
void RifReaderEclipseOutput : : readWellCells ( const ecl_grid_type * mainEclGrid , bool importCompleteMswData )
2012-05-18 02:45:23 -05:00
{
2013-03-08 01:24:40 -06:00
CVF_ASSERT ( m_eclipseCase ) ;
2012-05-18 02:45:23 -05:00
if ( m_dynamicResultsAccess . isNull ( ) ) return ;
2013-08-26 06:56:42 -05:00
well_info_type * ert_well_info = well_info_alloc ( mainEclGrid ) ;
2012-05-18 02:45:23 -05:00
if ( ! ert_well_info ) return ;
2014-10-24 04:19:54 -05:00
m_dynamicResultsAccess - > readWellData ( ert_well_info , importCompleteMswData ) ;
2012-05-18 02:45:23 -05:00
2014-10-29 03:34:57 -05:00
std : : vector < QDateTime > timeSteps = m_dynamicResultsAccess - > timeSteps ( ) ;
std : : vector < int > reportNumbers = m_dynamicResultsAccess - > reportNumbers ( ) ;
2017-01-12 05:04:54 -06:00
2014-10-29 03:34:57 -05:00
bool sameCount = false ;
if ( timeSteps . size ( ) = = reportNumbers . size ( ) )
{
sameCount = true ;
}
2012-05-18 02:45:23 -05:00
std : : vector < RigGridBase * > grids ;
2013-02-27 07:13:37 -06:00
m_eclipseCase - > allGrids ( & grids ) ;
2012-05-18 02:45:23 -05:00
2013-03-22 09:43:42 -05:00
cvf : : Collection < RigSingleWellResultsData > wells ;
2013-02-06 06:44:27 -06:00
caf : : ProgressInfo progress ( well_info_get_num_wells ( ert_well_info ) , " " ) ;
2012-05-18 02:45:23 -05: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 ) ;
2013-03-22 09:43:42 -05:00
cvf : : ref < RigSingleWellResultsData > wellResults = new RigSingleWellResultsData ;
2012-05-18 02:45:23 -05:00
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
2014-10-29 03:34:57 -05:00
bool haveFoundTimeStamp = false ;
if ( sameCount )
2012-05-18 02:45:23 -05:00
{
2014-10-29 03:34:57 -05:00
int reportNr = well_state_get_report_nr ( ert_well_state ) ;
for ( size_t i = 0 ; i < reportNumbers . size ( ) ; i + + )
{
if ( reportNumbers [ i ] = = reportNr )
{
wellResFrame . m_timestamp = timeSteps [ i ] ;
haveFoundTimeStamp = true ;
}
}
}
if ( ! haveFoundTimeStamp )
{
// This fallback will not work for timesteps before 1970.
// 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 ) ;
2015-04-14 08:47:51 -05:00
if ( ert_well_type = = ERT_PRODUCER )
2012-05-18 02:45:23 -05:00
{
wellResFrame . m_productionType = RigWellResultFrame : : PRODUCER ;
}
2015-04-14 08:47:51 -05:00
else if ( ert_well_type = = ERT_WATER_INJECTOR )
2012-05-18 02:45:23 -05:00
{
wellResFrame . m_productionType = RigWellResultFrame : : WATER_INJECTOR ;
}
2015-04-14 08:47:51 -05:00
else if ( ert_well_type = = ERT_GAS_INJECTOR )
2012-05-18 02:45:23 -05:00
{
wellResFrame . m_productionType = RigWellResultFrame : : GAS_INJECTOR ;
}
2015-04-14 08:47:51 -05:00
else if ( ert_well_type = = ERT_OIL_INJECTOR )
2012-05-18 02:45:23 -05:00
{
wellResFrame . m_productionType = RigWellResultFrame : : OIL_INJECTOR ;
}
else
{
wellResFrame . m_productionType = RigWellResultFrame : : UNDEFINED_PRODUCTION_TYPE ;
}
wellResFrame . m_isOpen = well_state_is_open ( ert_well_state ) ;
2014-10-24 04:19:54 -05:00
if ( importCompleteMswData & & well_state_is_MSW ( ert_well_state ) )
2013-08-26 07:03:01 -05:00
{
2013-08-26 07:15:27 -05:00
wellResults - > setMultiSegmentWell ( true ) ;
2013-08-26 06:56:42 -05:00
2013-08-26 07:56:34 -05:00
// how do we handle LGR-s ?
// 1. Create separate visual branches for each Grid, with its own wellhead
// 2. Always use the connections to the grid with the highest number (innermost LGR).
// 3. Handle both and switch between them according to visual settings of grid visualization
// Will there ever exist connections to different grids for the same segment ?
2013-08-26 08:28:34 -05:00
// We have currently selected 2.
2013-08-26 07:56:34 -05:00
// Set the wellhead
int lastGridNr = static_cast < int > ( grids . size ( ) ) - 1 ;
for ( int gridNr = lastGridNr ; gridNr > = 0 ; - - gridNr )
{
// If several grids have a wellhead definition for this well, we use the last one.
// (Possibly the innermost LGR)
const well_conn_type * ert_wellhead = well_state_iget_wellhead ( ert_well_state , static_cast < int > ( gridNr ) ) ;
if ( ert_wellhead )
{
2016-09-08 08:21:40 -05:00
wellResFrame . m_wellHead = createWellResultPoint ( grids [ gridNr ] , ert_wellhead , - 1 , - 1 , wellName ) ;
2016-01-07 07:24:59 -06:00
// HACK: Ert returns open as "this is equally wrong as closed for well heads".
// Well heads are not open jfr mail communication with HHGS and JH Statoil 07.01.2016
wellResFrame . m_wellHead . m_isOpen = false ;
2013-08-26 07:56:34 -05:00
break ;
}
}
well_branch_collection_type * branches = well_state_get_branches ( ert_well_state ) ;
int branchCount = well_branch_collection_get_size ( branches ) ;
wellResFrame . m_wellResultBranches . resize ( branchCount ) ;
std : : map < int , std : : vector < SegmentPositionContribution > > segmentIdToPositionContrib ;
std : : vector < int > upperSegmentIdsOfUnpositionedSegementGroup ;
2013-08-26 08:28:34 -05:00
// For each branch, go from bottom segment upwards and transfer their connections to WellResultpoints.
// If they have no connections, create a resultpoint representing their bottom position, which will
// receive an actual position at a later stage.
// I addition, distribute contributions for calculating segment bottom positions from bottom and up.
2013-08-26 07:56:34 -05:00
for ( int bIdx = 0 ; bIdx < well_branch_collection_get_size ( branches ) ; bIdx + + )
{
RigWellResultBranch & wellResultBranch = wellResFrame . m_wellResultBranches [ bIdx ] ;
const well_segment_type * segment = well_branch_collection_iget_start_segment ( branches , bIdx ) ;
int branchId = well_segment_get_branch_id ( segment ) ;
wellResultBranch . m_ertBranchId = branchId ;
// Data for segment position calculation
int lastConnectionSegmentId = - 1 ;
cvf : : Vec3d lastConnectionPos = cvf : : Vec3d : : UNDEFINED ;
2013-08-28 03:22:30 -05:00
cvf : : Vec3d lastConnectionCellCorner = cvf : : Vec3d : : UNDEFINED ;
2013-08-26 08:28:34 -05:00
double lastConnectionCellSize = 0 ;
2013-08-26 07:56:34 -05:00
double accLengthFromLastConnection = 0 ;
int segmentIdBelow = - 1 ;
bool segmentBelowHasConnections = false ;
while ( segment & & branchId = = well_segment_get_branch_id ( segment ) )
{
// Loop backwards, making us select the connection in the innermost lgr as the truth
bool segmentHasConnections = false ;
for ( int gridNr = lastGridNr ; gridNr > = 0 ; - - gridNr )
{
std : : string gridName = this - > ertGridName ( gridNr ) ;
// If this segment has connections in any grid, transfer the innermost ones
if ( well_segment_has_grid_connections ( segment , gridName . data ( ) ) )
{
const well_conn_collection_type * connections = well_segment_get_connections ( segment , gridName . data ( ) ) ;
int connectionCount = well_conn_collection_get_size ( connections ) ;
// Loop backwards to put the deepest connections first in the array. (The segments are also traversed deep to shallow)
for ( int connIdx = connectionCount - 1 ; connIdx > = 0 ; connIdx - - )
{
well_conn_type * ert_connection = well_conn_collection_iget ( connections , connIdx ) ;
wellResultBranch . m_branchResultPoints . push_back (
2016-09-08 08:21:40 -05:00
createWellResultPoint ( grids [ gridNr ] , ert_connection , branchId , well_segment_get_id ( segment ) , wellName ) ) ;
2013-08-26 07:56:34 -05:00
}
segmentHasConnections = true ;
// Prepare data for segment position calculation
well_conn_type * ert_connection = well_conn_collection_iget ( connections , 0 ) ;
2016-09-08 08:21:40 -05:00
RigWellResultPoint point = createWellResultPoint ( grids [ gridNr ] , ert_connection , branchId , well_segment_get_id ( segment ) , wellName ) ;
2013-08-26 07:56:34 -05:00
lastConnectionPos = grids [ gridNr ] - > cell ( point . m_gridCellIndex ) . center ( ) ;
2013-08-26 08:28:34 -05:00
cvf : : Vec3d cellVxes [ 8 ] ;
grids [ gridNr ] - > cellCornerVertices ( point . m_gridCellIndex , cellVxes ) ;
2013-08-28 03:22:30 -05:00
lastConnectionCellCorner = cellVxes [ 0 ] ;
2013-08-26 08:28:34 -05:00
lastConnectionCellSize = ( lastConnectionPos - cellVxes [ 0 ] ) . length ( ) ;
2013-08-28 03:22:30 -05:00
2013-08-26 07:56:34 -05:00
lastConnectionSegmentId = well_segment_get_id ( segment ) ;
accLengthFromLastConnection = well_segment_get_length ( segment ) / ( connectionCount + 1 ) ;
if ( ! segmentBelowHasConnections ) upperSegmentIdsOfUnpositionedSegementGroup . push_back ( segmentIdBelow ) ;
break ; // Stop looping over grids
}
}
// If the segment did not have connections at all, we need to create a resultpoint representing the bottom of the segment
// and store it as an unpositioned segment
if ( ! segmentHasConnections )
{
RigWellResultPoint data ;
data . m_ertBranchId = branchId ;
data . m_ertSegmentId = well_segment_get_id ( segment ) ;
wellResultBranch . m_branchResultPoints . push_back ( data ) ;
// Store data for segment position calculation
2013-08-26 08:28:34 -05:00
bool isAnInsolationContribution = accLengthFromLastConnection < lastConnectionCellSize ;
2013-08-26 08:10:34 -05:00
2013-08-26 08:28:34 -05:00
2013-08-26 08:10:34 -05:00
segmentIdToPositionContrib [ well_segment_get_id ( segment ) ] . push_back (
2013-08-26 08:28:34 -05:00
SegmentPositionContribution ( lastConnectionSegmentId , lastConnectionPos , accLengthFromLastConnection , isAnInsolationContribution , segmentIdBelow , - 1 , false ) ) ;
2013-08-26 08:10:34 -05:00
accLengthFromLastConnection + = well_segment_get_length ( segment ) ;
2013-08-26 07:56:34 -05:00
}
segmentIdBelow = well_segment_get_id ( segment ) ;
segmentBelowHasConnections = segmentHasConnections ;
if ( well_segment_get_outlet_id ( segment ) = = - 1 )
{
segment = NULL ;
}
else
{
segment = well_segment_get_outlet ( segment ) ;
}
}
2013-08-26 08:28:34 -05:00
// Add resultpoint representing the outlet segment (bottom), if not the branch ends at the wellhead.
2013-08-26 07:56:34 -05:00
const well_segment_type * outletSegment = segment ;
if ( outletSegment )
{
bool outletSegmentHasConnections = false ;
for ( int gridNr = lastGridNr ; gridNr > = 0 ; - - gridNr )
{
std : : string gridName = this - > ertGridName ( gridNr ) ;
// If this segment has connections in any grid, use the deepest innermost one
if ( well_segment_has_grid_connections ( outletSegment , gridName . data ( ) ) )
{
const well_conn_collection_type * connections = well_segment_get_connections ( outletSegment , gridName . data ( ) ) ;
int connectionCount = well_conn_collection_get_size ( connections ) ;
// Select the deepest connection
well_conn_type * ert_connection = well_conn_collection_iget ( connections , connectionCount - 1 ) ;
wellResultBranch . m_branchResultPoints . push_back (
2016-09-08 08:21:40 -05:00
createWellResultPoint ( grids [ gridNr ] , ert_connection , branchId , well_segment_get_id ( outletSegment ) , wellName ) ) ;
2013-08-26 07:56:34 -05:00
outletSegmentHasConnections = true ;
break ; // Stop looping over grids
}
}
if ( ! outletSegmentHasConnections )
{
// Store the result point
RigWellResultPoint data ;
data . m_ertBranchId = well_segment_get_branch_id ( outletSegment ) ;
data . m_ertSegmentId = well_segment_get_id ( outletSegment ) ;
wellResultBranch . m_branchResultPoints . push_back ( data ) ;
2013-08-28 08:36:29 -05:00
// Store data for segment position calculation,
// and propagate it upwards until we meet a segment with connections
2013-08-26 08:28:34 -05:00
2013-08-28 08:36:29 -05:00
bool isAnInsolationContribution = accLengthFromLastConnection < lastConnectionCellSize ;
2013-08-26 08:28:34 -05:00
2013-08-28 08:36:29 -05:00
cvf : : Vec3d lastConnectionPosWOffset = lastConnectionPos ;
if ( isAnInsolationContribution ) lastConnectionPosWOffset + = 0.4 * ( lastConnectionCellCorner - lastConnectionPos ) ;
2013-08-26 07:56:34 -05:00
2013-08-28 08:36:29 -05:00
segmentIdToPositionContrib [ well_segment_get_id ( outletSegment ) ] . push_back (
SegmentPositionContribution ( lastConnectionSegmentId , lastConnectionPosWOffset , accLengthFromLastConnection , isAnInsolationContribution , segmentIdBelow , - 1 , false ) ) ;
2013-08-26 07:56:34 -05:00
2013-08-28 08:36:29 -05:00
/// Loop further to add this position contribution until a segment with connections is found
2013-08-26 07:56:34 -05:00
2013-08-28 08:36:29 -05:00
accLengthFromLastConnection + = well_segment_get_length ( outletSegment ) ;
segmentIdBelow = well_segment_get_id ( outletSegment ) ;
2013-08-26 07:56:34 -05:00
2013-08-28 08:36:29 -05:00
const well_segment_type * aboveOutletSegment = NULL ;
2013-08-26 07:56:34 -05:00
2013-08-28 08:36:29 -05:00
if ( well_segment_get_outlet_id ( outletSegment ) = = - 1 )
{
aboveOutletSegment = NULL ;
}
else
{
aboveOutletSegment = well_segment_get_outlet ( outletSegment ) ;
}
2013-08-26 07:56:34 -05:00
2013-08-28 08:36:29 -05:00
while ( aboveOutletSegment )
{
// Loop backwards, just because we do that the other places
bool segmentHasConnections = false ;
2013-08-26 07:56:34 -05:00
2013-08-28 08:36:29 -05:00
for ( int gridNr = lastGridNr ; gridNr > = 0 ; - - gridNr )
{
std : : string gridName = this - > ertGridName ( gridNr ) ;
2013-08-26 07:56:34 -05:00
2013-08-28 08:36:29 -05:00
// If this segment has connections in any grid, stop traversal
2013-08-26 07:56:34 -05:00
2013-08-28 08:36:29 -05:00
if ( well_segment_has_grid_connections ( aboveOutletSegment , gridName . data ( ) ) )
2013-08-26 07:56:34 -05:00
{
2013-08-28 08:36:29 -05:00
segmentHasConnections = true ;
break ;
2013-08-26 07:56:34 -05:00
}
2013-08-28 08:36:29 -05:00
}
if ( ! segmentHasConnections )
{
segmentIdToPositionContrib [ well_segment_get_id ( aboveOutletSegment ) ] . push_back (
SegmentPositionContribution ( lastConnectionSegmentId , lastConnectionPos , accLengthFromLastConnection , isAnInsolationContribution , segmentIdBelow , - 1 , false ) ) ;
accLengthFromLastConnection + = well_segment_get_length ( aboveOutletSegment ) ;
}
else
{
break ; // We have found a segment with connections. We do not need to propagate position contributions further
}
2013-08-26 07:56:34 -05:00
2013-08-28 08:36:29 -05:00
segmentIdBelow = well_segment_get_id ( aboveOutletSegment ) ;
2013-08-26 07:56:34 -05:00
2013-08-28 08:36:29 -05:00
if ( well_segment_get_outlet_id ( aboveOutletSegment ) = = - 1 )
{
aboveOutletSegment = NULL ;
2013-08-26 07:56:34 -05:00
}
2013-08-28 08:36:29 -05:00
else
{
aboveOutletSegment = well_segment_get_outlet ( aboveOutletSegment ) ;
}
}
2013-08-26 07:56:34 -05:00
}
}
else
{
2013-08-26 08:10:34 -05:00
// Add wellhead as result point Nope. Not Yet, but it is a good idea.
// The centerline calculations would be a bit simpler, I think.
2013-08-26 07:56:34 -05:00
}
// Reverse the order of the resultpoints in this branch, making the deepest come last
std : : reverse ( wellResultBranch . m_branchResultPoints . begin ( ) , wellResultBranch . m_branchResultPoints . end ( ) ) ;
2013-08-28 08:36:29 -05:00
} // End of the branch loop
2013-08-26 07:56:34 -05:00
// Propagate position contributions from connections above unpositioned segments downwards
well_segment_collection_type * allErtSegments = well_state_get_segments ( ert_well_state ) ;
for ( size_t bIdx = 0 ; bIdx < wellResFrame . m_wellResultBranches . size ( ) ; + + bIdx )
{
RigWellResultBranch & wellResultBranch = wellResFrame . m_wellResultBranches [ bIdx ] ;
bool previousResultPointWasCell = false ;
2013-08-26 08:10:34 -05:00
if ( bIdx = = 0 ) previousResultPointWasCell = true ; // Wellhead
2013-08-26 08:28:34 -05:00
// Go downwards until we find a none-cell resultpoint just after a cell-resultpoint
// When we do, start propagating
2013-08-26 07:56:34 -05:00
for ( size_t rpIdx = 0 ; rpIdx < wellResultBranch . m_branchResultPoints . size ( ) ; + + rpIdx )
{
2013-08-26 08:10:34 -05:00
RigWellResultPoint resPoint = wellResultBranch . m_branchResultPoints [ rpIdx ] ;
if ( resPoint . isCell ( ) )
2013-08-26 07:56:34 -05:00
{
previousResultPointWasCell = true ;
}
2013-08-26 08:10:34 -05:00
else
2013-08-26 07:56:34 -05:00
{
2013-08-26 08:10:34 -05:00
if ( previousResultPointWasCell )
{
RigWellResultPoint prevResPoint ;
if ( bIdx = = 0 & & rpIdx = = 0 )
{
prevResPoint = wellResFrame . m_wellHead ;
}
else
{
prevResPoint = wellResultBranch . m_branchResultPoints [ rpIdx - 1 ] ;
}
2013-08-26 07:56:34 -05:00
2013-08-26 08:10:34 -05:00
cvf : : Vec3d lastConnectionPos = grids [ prevResPoint . m_gridIndex ] - > cell ( prevResPoint . m_gridCellIndex ) . center ( ) ;
2013-08-26 07:56:34 -05:00
2013-08-26 08:28:34 -05:00
SegmentPositionContribution posContrib ( prevResPoint . m_ertSegmentId , lastConnectionPos , 0.0 , false , - 1 , prevResPoint . m_ertSegmentId , true ) ;
2013-08-26 07:56:34 -05:00
2013-08-26 08:10:34 -05:00
int ertSegmentId = resPoint . m_ertSegmentId ;
2013-08-26 07:56:34 -05:00
2013-08-26 08:10:34 -05:00
std : : map < int , std : : vector < SegmentPositionContribution > > : : iterator posContribIt ;
posContribIt = segmentIdToPositionContrib . find ( ertSegmentId ) ;
CVF_ASSERT ( posContribIt ! = segmentIdToPositionContrib . end ( ) ) ;
2013-08-26 07:56:34 -05:00
2013-08-26 08:10:34 -05:00
std : : vector < SegmentPositionContribution > posContributions = posContribIt - > second ;
2013-08-26 08:28:34 -05:00
for ( size_t i = 0 ; i < posContributions . size ( ) ; + + i )
{
posContributions [ i ] . m_segmentIdAbove = prevResPoint . m_ertSegmentId ;
}
2013-08-26 08:10:34 -05:00
posContributions . push_back ( posContrib ) ;
propagatePosContribDownwards ( segmentIdToPositionContrib , allErtSegments , ertSegmentId , posContributions ) ;
}
2013-08-26 07:56:34 -05:00
2013-08-26 08:10:34 -05:00
previousResultPointWasCell = false ;
2013-08-26 07:56:34 -05:00
}
}
}
// Calculate the bottom position of all the unpositioned segments
2013-08-26 08:28:34 -05:00
// Then do the calculation based on the refined contributions
2013-08-26 07:56:34 -05:00
std : : map < int , std : : vector < SegmentPositionContribution > > : : iterator posContribIt = segmentIdToPositionContrib . begin ( ) ;
std : : map < int , cvf : : Vec3d > bottomPositions ;
while ( posContribIt ! = segmentIdToPositionContrib . end ( ) )
{
bottomPositions [ posContribIt - > first ] = interpolate3DPosition ( posContribIt - > second ) ;
2015-11-27 09:37:26 -06:00
+ + posContribIt ;
2013-08-26 07:56:34 -05:00
}
// Distribute the positions to the resultpoints stored in the wellResultBranch.m_branchResultPoints
for ( size_t bIdx = 0 ; bIdx < wellResFrame . m_wellResultBranches . size ( ) ; + + bIdx )
{
RigWellResultBranch & wellResultBranch = wellResFrame . m_wellResultBranches [ bIdx ] ;
for ( size_t rpIdx = 0 ; rpIdx < wellResultBranch . m_branchResultPoints . size ( ) ; + + rpIdx )
{
RigWellResultPoint & resPoint = wellResultBranch . m_branchResultPoints [ rpIdx ] ;
if ( ! resPoint . isCell ( ) )
{
resPoint . m_bottomPosition = bottomPositions [ resPoint . m_ertSegmentId ] ;
}
}
}
2013-08-28 08:36:29 -05:00
} // End of the MSW section
2013-08-26 07:15:27 -05:00
else
2013-08-26 07:03:01 -05:00
{
2013-08-26 07:15:27 -05:00
// Code handling None-MSW Wells ... Normal wells that is.
2013-08-26 07:03:01 -05:00
// Loop over all the grids in the model. If we have connections in one, we will discard
// the main grid connections as the well connections are duplicated in the main grid and LGR grids
2013-08-26 07:09:25 -05:00
// Verified on 10 k case JJS. But smarter things could be done, like showing the "main grid well" if turning off the LGR's
2013-08-26 07:03:01 -05:00
bool hasWellConnectionsInLGR = false ;
2013-08-26 07:09:25 -05:00
2013-08-26 07:03:01 -05:00
for ( size_t gridIdx = 1 ; gridIdx < grids . size ( ) ; + + gridIdx )
{
RigGridBase * lgrGrid = m_eclipseCase - > grid ( gridIdx ) ;
if ( well_state_has_grid_connections ( ert_well_state , lgrGrid - > gridName ( ) . data ( ) ) )
{
hasWellConnectionsInLGR = true ;
break ;
}
}
2013-08-26 07:09:25 -05:00
2013-08-26 07:03:01 -05:00
size_t gridNr = hasWellConnectionsInLGR ? 1 : 0 ;
for ( ; gridNr < grids . size ( ) ; + + gridNr )
{
// Wellhead. If several grids have a wellhead definition for this well, we use the last one. (Possibly the innermost LGR)
const well_conn_type * ert_wellhead = well_state_iget_wellhead ( ert_well_state , static_cast < int > ( gridNr ) ) ;
if ( ert_wellhead )
{
2016-09-08 08:21:40 -05:00
wellResFrame . m_wellHead = createWellResultPoint ( grids [ gridNr ] , ert_wellhead , - 1 , - 1 , wellName ) ;
2016-01-07 07:24:59 -06:00
// HACK: Ert returns open as "this is equally wrong as closed for well heads".
// Well heads are not open jfr mail communication with HHGS and JH Statoil 07.01.2016
wellResFrame . m_wellHead . m_isOpen = false ;
2013-08-26 07:15:27 -05:00
//std::cout << "Wellhead YES at timeIdx: " << timeIdx << " wellIdx: " << wellIdx << " Grid: " << gridNr << std::endl;
2013-08-26 07:03:01 -05:00
}
else
{
2013-08-26 07:15:27 -05:00
// std::cout << "Wellhead NO at timeIdx: " << timeIdx << " wellIdx: " << wellIdx << " Grid: " << gridNr << std::endl;
//CVF_ASSERT(0); // This is just a test assert to see if this condition exists in some files and it does.
// All the grids does not necessarily have a well head definition.
2013-08-26 07:03:01 -05:00
}
2013-08-26 08:10:34 -05:00
const well_conn_collection_type * connections = well_state_get_grid_connections ( ert_well_state , this - > ertGridName ( gridNr ) . data ( ) ) ;
2013-08-26 07:03:01 -05:00
// Import all well result cells for all connections
if ( connections )
{
int connectionCount = well_conn_collection_get_size ( connections ) ;
if ( connectionCount )
{
wellResFrame . m_wellResultBranches . push_back ( RigWellResultBranch ( ) ) ;
RigWellResultBranch & wellResultBranch = wellResFrame . m_wellResultBranches . back ( ) ;
2013-08-26 08:10:34 -05:00
wellResultBranch . m_ertBranchId = 0 ; // Normal wells have only one branch
2013-08-26 07:03:01 -05:00
size_t existingCellCount = wellResultBranch . m_branchResultPoints . size ( ) ;
wellResultBranch . m_branchResultPoints . resize ( existingCellCount + connectionCount ) ;
for ( int connIdx = 0 ; connIdx < connectionCount ; connIdx + + )
{
well_conn_type * ert_connection = well_conn_collection_iget ( connections , connIdx ) ;
wellResultBranch . m_branchResultPoints [ existingCellCount + connIdx ] =
2016-09-08 08:21:40 -05:00
createWellResultPoint ( grids [ gridNr ] , ert_connection , - 1 , - 1 , wellName ) ;
2013-08-26 07:03:01 -05:00
}
}
}
}
}
2012-05-18 02:45:23 -05:00
}
2013-08-26 06:56:42 -05:00
2012-05-18 02:45:23 -05:00
wellResults - > computeMappingFromResultTimeIndicesToWellTimeIndices ( m_timeSteps ) ;
wells . push_back ( wellResults . p ( ) ) ;
2013-02-06 06:44:27 -06:00
progress . incrementProgress ( ) ;
2012-05-18 02:45:23 -05:00
}
well_info_free ( ert_well_info ) ;
2013-02-27 07:13:37 -06:00
m_eclipseCase - > setWellResults ( wells ) ;
2012-05-18 02:45:23 -05:00
}
2013-01-25 08:20:41 -06:00
2013-02-05 03:51:32 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-08-22 10:00:57 -05:00
QStringList RifReaderEclipseOutput : : validKeywordsForPorosityModel ( const QStringList & keywords ,
const std : : vector < size_t > & keywordDataItemCounts ,
const RigActiveCellInfo * matrixActiveCellInfo ,
const RigActiveCellInfo * fractureActiveCellInfo ,
PorosityModelResultType porosityModel ,
size_t timeStepCount ) const
2013-02-05 03:51:32 -06:00
{
2016-08-12 07:24:41 -05:00
CVF_ASSERT ( matrixActiveCellInfo ) ;
2013-02-12 04:15:36 -06:00
2013-03-02 03:18:27 -06:00
if ( keywords . size ( ) ! = static_cast < int > ( keywordDataItemCounts . size ( ) ) )
2013-02-05 03:51:32 -06:00
{
return QStringList ( ) ;
}
2016-07-14 06:35:32 -05:00
if ( porosityModel = = RifReaderInterface : : FRACTURE_RESULTS )
2013-02-05 03:51:32 -06:00
{
2014-08-08 03:27:29 -05:00
if ( fractureActiveCellInfo - > reservoirActiveCellCount ( ) = = 0 )
2013-02-05 03:51:32 -06:00
{
return QStringList ( ) ;
}
}
QStringList keywordsWithCorrectNumberOfDataItems ;
for ( int i = 0 ; i < keywords . size ( ) ; i + + )
{
QString keyword = keywords [ i ] ;
2016-08-12 07:24:41 -05:00
size_t keywordDataItemCount = keywordDataItemCounts [ i ] ;
2013-02-05 03:51:32 -06:00
2016-08-12 07:24:41 -05:00
bool validKeyword = false ;
size_t timeStepsAllCellsRest = keywordDataItemCount % matrixActiveCellInfo - > reservoirCellCount ( ) ;
if ( timeStepsAllCellsRest = = 0 & & keywordDataItemCount < = timeStepCount * matrixActiveCellInfo - > reservoirCellCount ( ) )
{
// Found result for all cells for N time steps, usually a static dataset for one time step
validKeyword = true ;
}
else
2013-02-27 04:27:02 -06:00
{
2016-08-12 07:24:41 -05:00
size_t timeStepsMatrixRest = keywordDataItemCount % matrixActiveCellInfo - > reservoirActiveCellCount ( ) ;
size_t timeStepsFractureRest = 0 ;
if ( fractureActiveCellInfo - > reservoirActiveCellCount ( ) > 0 )
{
timeStepsFractureRest = keywordDataItemCount % fractureActiveCellInfo - > reservoirActiveCellCount ( ) ;
}
2013-10-18 07:26:49 -05:00
2016-08-12 07:24:41 -05:00
size_t sumFractureMatrixActiveCellCount = matrixActiveCellInfo - > reservoirActiveCellCount ( ) + fractureActiveCellInfo - > reservoirActiveCellCount ( ) ;
size_t timeStepsMatrixAndFractureRest = keywordDataItemCount % sumFractureMatrixActiveCellCount ;
2013-02-05 03:51:32 -06:00
2016-08-12 07:24:41 -05:00
if ( porosityModel = = RifReaderInterface : : MATRIX_RESULTS & & timeStepsMatrixRest = = 0 )
2013-02-05 03:51:32 -06:00
{
2016-08-12 07:24:41 -05:00
if ( keywordDataItemCount < = timeStepCount * std : : max ( matrixActiveCellInfo - > reservoirActiveCellCount ( ) , sumFractureMatrixActiveCellCount ) )
2013-10-18 07:26:49 -05:00
{
2016-08-12 07:24:41 -05:00
validKeyword = true ;
2013-10-18 07:26:49 -05:00
}
2013-02-27 04:27:02 -06:00
}
2016-08-12 07:24:41 -05:00
else if ( porosityModel = = RifReaderInterface : : FRACTURE_RESULTS & & fractureActiveCellInfo - > reservoirActiveCellCount ( ) > 0 & & timeStepsFractureRest = = 0 )
2013-02-27 04:27:02 -06:00
{
2016-08-12 07:24:41 -05:00
if ( keywordDataItemCount < = timeStepCount * std : : max ( fractureActiveCellInfo - > reservoirActiveCellCount ( ) , sumFractureMatrixActiveCellCount ) )
2013-02-05 03:51:32 -06:00
{
2016-08-12 07:24:41 -05:00
validKeyword = true ;
2013-02-05 03:51:32 -06:00
}
2016-07-14 06:35:32 -05:00
}
2016-08-12 07:24:41 -05:00
else if ( timeStepsMatrixAndFractureRest = = 0 )
2016-07-14 06:35:32 -05:00
{
2016-08-12 07:24:41 -05:00
if ( keywordDataItemCount < = timeStepCount * sumFractureMatrixActiveCellCount )
2013-10-18 07:26:49 -05:00
{
2016-08-12 07:24:41 -05:00
validKeyword = true ;
2013-10-18 07:26:49 -05:00
}
2013-02-05 03:51:32 -06:00
}
}
2016-07-14 06:35:32 -05:00
2016-08-22 10:00:57 -05:00
// Check for INIT values that has only values for main grid active cells
if ( ! validKeyword )
{
if ( timeStepCount = = 1 )
{
size_t mainGridMatrixActiveCellCount ; matrixActiveCellInfo - > gridActiveCellCounts ( 0 , mainGridMatrixActiveCellCount ) ;
size_t mainGridFractureActiveCellCount ; fractureActiveCellInfo - > gridActiveCellCounts ( 0 , mainGridFractureActiveCellCount ) ;
if ( keywordDataItemCount = = mainGridMatrixActiveCellCount
| | keywordDataItemCount = = mainGridFractureActiveCellCount
| | keywordDataItemCount = = mainGridMatrixActiveCellCount + mainGridFractureActiveCellCount )
{
validKeyword = true ;
}
}
}
2016-08-12 07:24:41 -05:00
if ( validKeyword )
{
keywordsWithCorrectNumberOfDataItems . push_back ( keyword ) ;
2013-02-05 03:51:32 -06:00
}
}
return keywordsWithCorrectNumberOfDataItems ;
}
2013-02-27 04:27:02 -06:00
2013-02-05 03:51:32 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseOutput : : extractResultValuesBasedOnPorosityModel ( PorosityModelResultType matrixOrFracture , std : : vector < double > * destinationResultValues , const std : : vector < double > & sourceResultValues )
{
2016-08-12 07:24:41 -05:00
if ( sourceResultValues . size ( ) = = 0 ) return ;
2013-02-05 03:51:32 -06:00
2016-08-12 07:24:41 -05:00
RigActiveCellInfo * fracActCellInfo = m_eclipseCase - > activeCellInfo ( RifReaderInterface : : FRACTURE_RESULTS ) ;
2013-02-05 03:51:32 -06:00
2014-08-08 03:27:29 -05:00
if ( matrixOrFracture = = RifReaderInterface : : MATRIX_RESULTS & & fracActCellInfo - > reservoirActiveCellCount ( ) = = 0 )
2013-03-13 05:50:31 -05:00
{
destinationResultValues - > insert ( destinationResultValues - > end ( ) , sourceResultValues . begin ( ) , sourceResultValues . end ( ) ) ;
2013-02-05 03:51:32 -06:00
}
else
{
2013-03-13 05:50:31 -05:00
RigActiveCellInfo * actCellInfo = m_eclipseCase - > activeCellInfo ( RifReaderInterface : : MATRIX_RESULTS ) ;
2013-02-05 03:51:32 -06:00
size_t sourceStartPosition = 0 ;
2013-02-27 07:13:37 -06:00
for ( size_t i = 0 ; i < m_eclipseCase - > mainGrid ( ) - > gridCount ( ) ; i + + )
2013-02-05 03:51:32 -06:00
{
2013-02-12 04:15:36 -06:00
size_t matrixActiveCellCount = 0 ;
size_t fractureActiveCellCount = 0 ;
2013-03-13 05:50:31 -05:00
actCellInfo - > gridActiveCellCounts ( i , matrixActiveCellCount ) ;
fracActCellInfo - > gridActiveCellCounts ( i , fractureActiveCellCount ) ;
2013-02-05 03:51:32 -06:00
2013-03-13 05:50:31 -05: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 03:51:32 -06:00
sourceStartPosition + = ( matrixActiveCellCount + fractureActiveCellCount ) ;
}
}
}
2013-02-27 07:13:37 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-04-22 07:51:47 -05:00
void RifReaderEclipseOutput : : openInitFile ( )
2013-02-27 07:13:37 -06:00
{
if ( m_ecl_init_file )
{
2013-04-22 07:51:47 -05:00
return ;
2013-02-27 07:13:37 -06:00
}
2013-04-10 04:02:10 -05:00
QString initFileName = RifEclipseOutputFileTools : : firstFileNameOfType ( m_filesWithSameBaseName , ECL_INIT_FILE ) ;
2013-02-27 07:13:37 -06:00
if ( initFileName . size ( ) > 0 )
{
2013-04-29 06:13:42 -05:00
m_ecl_init_file = ecl_file_open ( initFileName . toAscii ( ) . data ( ) , ECL_FILE_CLOSE_STREAM ) ;
2013-02-27 07:13:37 -06:00
}
}
2013-03-05 06:10:26 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-03-18 05:40:39 -05:00
std : : vector < QDateTime > RifReaderEclipseOutput : : timeSteps ( )
2013-03-05 06:10:26 -06:00
{
return m_timeSteps ;
}
2013-05-21 04:10:59 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseOutput : : transferCoarseningInfo ( const ecl_grid_type * eclGrid , RigGridBase * grid )
{
int coarseGroupCount = ecl_grid_get_num_coarse_groups ( eclGrid ) ;
for ( int i = 0 ; i < coarseGroupCount ; i + + )
{
ecl_coarse_cell_type * coarse_cell = ecl_grid_iget_coarse_group ( eclGrid , i ) ;
CVF_ASSERT ( coarse_cell ) ;
size_t i1 = static_cast < size_t > ( ecl_coarse_cell_get_i1 ( coarse_cell ) ) ;
size_t i2 = static_cast < size_t > ( ecl_coarse_cell_get_i2 ( coarse_cell ) ) ;
size_t j1 = static_cast < size_t > ( ecl_coarse_cell_get_j1 ( coarse_cell ) ) ;
size_t j2 = static_cast < size_t > ( ecl_coarse_cell_get_j2 ( coarse_cell ) ) ;
size_t k1 = static_cast < size_t > ( ecl_coarse_cell_get_k1 ( coarse_cell ) ) ;
size_t k2 = static_cast < size_t > ( ecl_coarse_cell_get_k2 ( coarse_cell ) ) ;
2013-05-21 14:03:05 -05:00
grid - > addCoarseningBox ( i1 , i2 , j1 , j2 , k1 , k2 ) ;
2013-05-21 04:10:59 -05:00
}
}
2013-08-26 07:56:34 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std : : string RifReaderEclipseOutput : : ertGridName ( size_t gridNr )
{
std : : string gridName ;
if ( gridNr = = 0 )
{
gridName = ECL_GRID_GLOBAL_GRID ;
}
else
{
CVF_ASSERT ( m_eclipseCase ) ;
CVF_ASSERT ( m_eclipseCase - > gridCount ( ) > gridNr ) ;
gridName = m_eclipseCase - > grid ( gridNr ) - > gridName ( ) ;
}
return gridName ;
}