2012-06-26 09:10:41 -05:00
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
# include "RifEclipseInputFileTools.h"
# include "RifReaderEclipseOutput.h"
2013-03-22 10:58:44 -05:00
# include "RigCaseCellResultsData.h"
2012-06-26 09:10:41 -05:00
2013-03-22 10:58:44 -05:00
# include "RigCaseData.h"
2012-06-26 09:10:41 -05:00
# include "cafProgressInfo.h"
# include <vector>
# include <cmath>
# include <iostream>
# include <QFile>
2013-12-03 13:30:32 -06:00
# include <QFileInfo>
# include <QDir>
2012-06-26 09:10:41 -05:00
# include <QTextStream>
2012-10-08 12:44:10 -05:00
# include <QDebug>
2012-06-26 09:10:41 -05:00
# include "ecl_grid.h"
# include "well_state.h"
# include "util.h"
# include <fstream>
2012-10-08 12:44:10 -05:00
2013-12-03 13:30:32 -06:00
QString includeKeyword ( " INCLUDE " ) ;
QString faultsKeyword ( " FAULTS " ) ;
QString editKeyword ( " EDIT " ) ;
QString gridKeyword ( " GRID " ) ;
2012-10-08 12:44:10 -05:00
2012-06-26 09:10:41 -05:00
//--------------------------------------------------------------------------------------------------
/// Constructor
//--------------------------------------------------------------------------------------------------
RifEclipseInputFileTools : : RifEclipseInputFileTools ( )
{
}
//--------------------------------------------------------------------------------------------------
/// Destructor
//--------------------------------------------------------------------------------------------------
RifEclipseInputFileTools : : ~ RifEclipseInputFileTools ( )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-03-22 09:43:42 -05:00
bool RifEclipseInputFileTools : : openGridFile ( const QString & fileName , RigCaseData * eclipseCase )
2012-06-26 09:10:41 -05:00
{
2013-02-13 06:24:39 -06:00
CVF_ASSERT ( eclipseCase ) ;
2012-06-26 09:10:41 -05:00
2013-12-03 13:30:32 -06:00
std : : vector < RifKeywordAndFilePos > keywordsAndFilePos ;
findKeywordsOnFile ( fileName , keywordsAndFilePos ) ;
2012-10-08 12:44:10 -05:00
qint64 coordPos = - 1 ;
qint64 zcornPos = - 1 ;
qint64 specgridPos = - 1 ;
qint64 actnumPos = - 1 ;
qint64 mapaxesPos = - 1 ;
2013-12-03 13:30:32 -06:00
findGridKeywordPositions ( keywordsAndFilePos , & coordPos , & zcornPos , & specgridPos , & actnumPos , & mapaxesPos ) ;
2012-10-08 12:44:10 -05:00
2012-10-24 06:46:42 -05:00
if ( coordPos < 0 | | zcornPos < 0 | | specgridPos < 0 )
2012-10-08 12:44:10 -05:00
{
return false ;
}
2012-06-26 09:10:41 -05:00
FILE * gridFilePointer = util_fopen ( fileName . toLatin1 ( ) . data ( ) , " r " ) ;
if ( ! gridFilePointer ) return false ;
2012-08-31 12:12:47 -05:00
// Main grid dimensions
2012-06-26 09:10:41 -05:00
// SPECGRID - This is whats normally available, but not really the input to Eclipse.
// DIMENS - Is what Eclipse expects and uses, but is not defined in the GRID section and is not (?) available normally
// ZCORN, COORD, ACTNUM, MAPAXES
//ecl_kw_type * ecl_kw_fscanf_alloc_grdecl_dynamic__( FILE * stream , const char * kw , bool strict , ecl_type_enum ecl_type);
//ecl_grid_type * ecl_grid_alloc_GRDECL_kw( int nx, int ny , int nz , const ecl_kw_type * zcorn_kw , const ecl_kw_type * coord_kw , const ecl_kw_type * actnum_kw , const ecl_kw_type * mapaxes_kw );
2012-10-08 12:44:10 -05:00
2012-06-26 09:10:41 -05:00
ecl_kw_type * specGridKw = NULL ;
ecl_kw_type * zCornKw = NULL ;
ecl_kw_type * coordKw = NULL ;
ecl_kw_type * actNumKw = NULL ;
ecl_kw_type * mapAxesKw = NULL ;
// Try to read all the needed keywords. Early exit if some are not found
2013-12-03 13:30:32 -06:00
caf : : ProgressInfo progress ( 8 , " Read Grid from Eclipse Input file " ) ;
2012-10-08 12:44:10 -05:00
2012-06-26 09:10:41 -05:00
bool allKwReadOk = true ;
2012-10-08 12:44:10 -05:00
bool continueReading = true ;
2012-06-26 09:10:41 -05:00
2012-10-08 12:44:10 -05:00
fseek ( gridFilePointer , specgridPos , SEEK_SET ) ;
allKwReadOk = allKwReadOk & & NULL ! = ( specGridKw = ecl_kw_fscanf_alloc_current_grdecl__ ( gridFilePointer , false , ECL_INT_TYPE ) ) ;
2012-06-26 09:10:41 -05:00
progress . setProgress ( 1 ) ;
2012-10-08 12:44:10 -05:00
fseek ( gridFilePointer , zcornPos , SEEK_SET ) ;
allKwReadOk = allKwReadOk & & NULL ! = ( zCornKw = ecl_kw_fscanf_alloc_current_grdecl__ ( gridFilePointer , false , ECL_FLOAT_TYPE ) ) ;
2012-06-26 09:10:41 -05:00
progress . setProgress ( 2 ) ;
2012-10-08 12:44:10 -05:00
fseek ( gridFilePointer , coordPos , SEEK_SET ) ;
allKwReadOk = allKwReadOk & & NULL ! = ( coordKw = ecl_kw_fscanf_alloc_current_grdecl__ ( gridFilePointer , false , ECL_FLOAT_TYPE ) ) ;
2012-06-26 09:10:41 -05:00
progress . setProgress ( 3 ) ;
2012-10-08 12:44:10 -05:00
2012-10-24 06:46:42 -05:00
// If ACTNUM is not defined, this pointer will be NULL, which is a valid condition
if ( actnumPos > = 0 )
{
fseek ( gridFilePointer , actnumPos , SEEK_SET ) ;
allKwReadOk = allKwReadOk & & NULL ! = ( actNumKw = ecl_kw_fscanf_alloc_current_grdecl__ ( gridFilePointer , false , ECL_INT_TYPE ) ) ;
progress . setProgress ( 4 ) ;
}
2012-09-11 06:04:24 -05:00
// If MAPAXES is not defined, this pointer will be NULL, which is a valid condition
2012-10-08 12:44:10 -05:00
if ( mapaxesPos > = 0 )
{
fseek ( gridFilePointer , mapaxesPos , SEEK_SET ) ;
mapAxesKw = ecl_kw_fscanf_alloc_current_grdecl__ ( gridFilePointer , false , ECL_FLOAT_TYPE ) ;
}
2012-09-11 06:04:24 -05:00
2012-06-26 09:10:41 -05:00
if ( ! allKwReadOk )
{
if ( specGridKw ) ecl_kw_free ( specGridKw ) ;
if ( zCornKw ) ecl_kw_free ( zCornKw ) ;
if ( coordKw ) ecl_kw_free ( coordKw ) ;
if ( actNumKw ) ecl_kw_free ( actNumKw ) ;
if ( mapAxesKw ) ecl_kw_free ( mapAxesKw ) ;
return false ;
}
progress . setProgress ( 5 ) ;
int nx = ecl_kw_iget_int ( specGridKw , 0 ) ;
int ny = ecl_kw_iget_int ( specGridKw , 1 ) ;
int nz = ecl_kw_iget_int ( specGridKw , 2 ) ;
ecl_grid_type * inputGrid = ecl_grid_alloc_GRDECL_kw ( nx , ny , nz , zCornKw , coordKw , actNumKw , mapAxesKw ) ;
progress . setProgress ( 6 ) ;
2013-02-13 06:24:39 -06:00
RifReaderEclipseOutput : : transferGeometry ( inputGrid , eclipseCase ) ;
2012-06-26 09:10:41 -05:00
progress . setProgress ( 7 ) ;
2013-12-03 13:30:32 -06:00
progress . setProgressDescription ( " Read faults ... " ) ;
cvf : : Collection < RigFault > faults ;
RifEclipseInputFileTools : : readFaults ( fileName , faults , keywordsAndFilePos ) ;
RigMainGrid * mainGrid = eclipseCase - > mainGrid ( ) ;
mainGrid - > setFaults ( faults ) ;
progress . setProgress ( 8 ) ;
2012-06-26 09:10:41 -05:00
progress . setProgressDescription ( " Cleaning up ... " ) ;
ecl_kw_free ( specGridKw ) ;
ecl_kw_free ( zCornKw ) ;
ecl_kw_free ( coordKw ) ;
2012-10-24 06:46:42 -05:00
if ( actNumKw ) ecl_kw_free ( actNumKw ) ;
2012-09-11 06:04:24 -05:00
if ( mapAxesKw ) ecl_kw_free ( mapAxesKw ) ;
2012-06-26 09:10:41 -05:00
ecl_grid_free ( inputGrid ) ;
util_fclose ( gridFilePointer ) ;
return true ;
}
//--------------------------------------------------------------------------------------------------
/// Read known properties from the input file
//--------------------------------------------------------------------------------------------------
2013-03-22 09:43:42 -05:00
std : : map < QString , QString > RifEclipseInputFileTools : : readProperties ( const QString & fileName , RigCaseData * reservoir )
2012-06-26 09:10:41 -05:00
{
CVF_ASSERT ( reservoir ) ;
std : : set < QString > knownKeywordSet ;
{
const std : : vector < QString > & knownKeywords = RifEclipseInputFileTools : : knownPropertyKeywords ( ) ;
for ( size_t fkIt = 0 ; fkIt < knownKeywords . size ( ) ; + + fkIt ) knownKeywordSet . insert ( knownKeywords [ fkIt ] ) ;
}
caf : : ProgressInfo mainProgress ( 2 , " Reading Eclipse Input properties " ) ;
caf : : ProgressInfo startProgress ( knownKeywordSet . size ( ) , " Scanning for known properties " ) ;
2013-12-03 13:30:32 -06:00
std : : vector < RifKeywordAndFilePos > fileKeywords ;
RifEclipseInputFileTools : : findKeywordsOnFile ( fileName , fileKeywords ) ;
2012-06-26 09:10:41 -05:00
mainProgress . setProgress ( 1 ) ;
caf : : ProgressInfo progress ( fileKeywords . size ( ) , " Reading properties " ) ;
FILE * gridFilePointer = util_fopen ( fileName . toLatin1 ( ) . data ( ) , " r " ) ;
if ( ! gridFilePointer | | ! fileKeywords . size ( ) )
{
return std : : map < QString , QString > ( ) ;
}
bool isSomethingRead = false ;
std : : map < QString , QString > newResults ;
for ( size_t i = 0 ; i < fileKeywords . size ( ) ; + + i )
{
2012-10-25 00:39:42 -05:00
//std::cout << fileKeywords[i].keyword.toLatin1().data() << std::endl;
2012-10-08 12:44:10 -05:00
if ( knownKeywordSet . count ( fileKeywords [ i ] . keyword ) )
2012-06-26 09:10:41 -05:00
{
2012-10-08 12:44:10 -05:00
fseek ( gridFilePointer , fileKeywords [ i ] . filePos , SEEK_SET ) ;
ecl_kw_type * eclKeyWordData = ecl_kw_fscanf_alloc_current_grdecl__ ( gridFilePointer , false , ECL_FLOAT_TYPE ) ;
2012-06-26 09:10:41 -05:00
if ( eclKeyWordData )
{
2013-02-13 06:10:54 -06:00
QString newResultName = reservoir - > results ( RifReaderInterface : : MATRIX_RESULTS ) - > makeResultNameUnique ( fileKeywords [ i ] . keyword ) ;
2012-06-26 09:10:41 -05:00
2013-03-21 09:31:47 -05:00
size_t resultIndex = reservoir - > results ( RifReaderInterface : : MATRIX_RESULTS ) - > addEmptyScalarResult ( RimDefines : : INPUT_PROPERTY , newResultName , false ) ; // Should really merge with inputProperty object information because we need to use PropertyName, and not keyword
2012-06-26 09:10:41 -05:00
2013-02-13 06:10:54 -06:00
std : : vector < std : : vector < double > > & newPropertyData = reservoir - > results ( RifReaderInterface : : MATRIX_RESULTS ) - > cellScalarResults ( resultIndex ) ;
2012-06-26 09:10:41 -05:00
newPropertyData . push_back ( std : : vector < double > ( ) ) ;
newPropertyData [ 0 ] . resize ( ecl_kw_get_size ( eclKeyWordData ) , HUGE_VAL ) ;
ecl_kw_get_data_as_double ( eclKeyWordData , newPropertyData [ 0 ] . data ( ) ) ;
ecl_kw_free ( eclKeyWordData ) ;
2012-10-08 12:44:10 -05:00
newResults [ newResultName ] = fileKeywords [ i ] . keyword ;
2012-06-26 09:10:41 -05:00
}
}
progress . setProgress ( i ) ;
}
util_fclose ( gridFilePointer ) ;
return newResults ;
}
//--------------------------------------------------------------------------------------------------
/// Read all the keywords from a file
2012-10-08 12:44:10 -05:00
//
// This code was originally written using QTextStream, but due to a bug in Qt version up to 4.8.0
// we had to implement the reading using QFile and QFile::readLine
//
// See:
// https://bugreports.qt-project.org/browse/QTBUG-9814
//
2012-06-26 09:10:41 -05:00
//--------------------------------------------------------------------------------------------------
2013-12-03 13:30:32 -06:00
void RifEclipseInputFileTools : : findKeywordsOnFile ( const QString & fileName , std : : vector < RifKeywordAndFilePos > & keywords )
2012-06-26 09:10:41 -05:00
{
2012-10-08 12:44:10 -05:00
char buf [ 1024 ] ;
2012-06-26 09:10:41 -05:00
2012-10-08 12:44:10 -05:00
QFile data ( fileName ) ;
data . open ( QFile : : ReadOnly ) ;
2012-06-26 09:10:41 -05:00
2012-10-08 12:44:10 -05:00
QString line ;
qint64 filepos = - 1 ;
qint64 lineLength = - 1 ;
2012-06-26 09:10:41 -05:00
2012-10-08 12:44:10 -05:00
do
2012-06-26 09:10:41 -05:00
{
2012-10-08 12:44:10 -05:00
lineLength = data . readLine ( buf , sizeof ( buf ) ) ;
if ( lineLength > 0 )
{
line = QString : : fromAscii ( buf ) ;
if ( line . size ( ) & & line [ 0 ] . isLetter ( ) )
{
RifKeywordAndFilePos keyPos ;
filepos = data . pos ( ) - lineLength ;
keyPos . filePos = filepos ;
keyPos . keyword = line . left ( 8 ) . trimmed ( ) ;
keywords . push_back ( keyPos ) ;
//qDebug() << keyPos.keyword << " - " << keyPos.filePos;
}
}
2012-06-26 09:10:41 -05:00
}
2012-10-08 12:44:10 -05:00
while ( lineLength ! = - 1 ) ;
2012-06-26 09:10:41 -05:00
}
//--------------------------------------------------------------------------------------------------
/// Reads the property data requested into the \a reservoir, overwriting any previous
/// propeties with the same name.
//--------------------------------------------------------------------------------------------------
2013-03-22 09:43:42 -05:00
bool RifEclipseInputFileTools : : readProperty ( const QString & fileName , RigCaseData * eclipseCase , const QString & eclipseKeyWord , const QString & resultName )
2012-06-26 09:10:41 -05:00
{
2013-02-13 06:24:39 -06:00
CVF_ASSERT ( eclipseCase ) ;
2012-06-26 09:10:41 -05:00
FILE * filePointer = util_fopen ( fileName . toLatin1 ( ) . data ( ) , " r " ) ;
if ( ! filePointer ) return false ;
ecl_kw_type * eclKeyWordData = ecl_kw_fscanf_alloc_grdecl_dynamic__ ( filePointer , eclipseKeyWord . toLatin1 ( ) . data ( ) , false , ECL_FLOAT_TYPE ) ;
bool isOk = false ;
if ( eclKeyWordData )
{
QString newResultName = resultName ;
2013-02-13 06:24:39 -06:00
size_t resultIndex = eclipseCase - > results ( RifReaderInterface : : MATRIX_RESULTS ) - > findScalarResultIndex ( newResultName ) ;
2012-06-26 09:10:41 -05:00
if ( resultIndex = = cvf : : UNDEFINED_SIZE_T )
{
2013-03-21 09:31:47 -05:00
resultIndex = eclipseCase - > results ( RifReaderInterface : : MATRIX_RESULTS ) - > addEmptyScalarResult ( RimDefines : : INPUT_PROPERTY , newResultName , false ) ;
2012-06-26 09:10:41 -05:00
}
2013-02-13 06:24:39 -06:00
std : : vector < std : : vector < double > > & newPropertyData = eclipseCase - > results ( RifReaderInterface : : MATRIX_RESULTS ) - > cellScalarResults ( resultIndex ) ;
2012-06-26 09:10:41 -05:00
newPropertyData . resize ( 1 ) ;
newPropertyData [ 0 ] . resize ( ecl_kw_get_size ( eclKeyWordData ) , HUGE_VAL ) ;
ecl_kw_get_data_as_double ( eclKeyWordData , newPropertyData [ 0 ] . data ( ) ) ;
isOk = true ;
ecl_kw_free ( eclKeyWordData ) ;
}
util_fclose ( filePointer ) ;
return isOk ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std : : vector < QString > & RifEclipseInputFileTools : : knownPropertyKeywords ( )
{
static std : : vector < QString > knownKeywords ;
static bool isInitialized = false ;
if ( ! isInitialized )
{
knownKeywords . push_back ( " AQUIFERA " ) ;
knownKeywords . push_back ( " ACTNUM " ) ;
knownKeywords . push_back ( " EQLNUM " ) ;
knownKeywords . push_back ( " FIPNUM " ) ;
knownKeywords . push_back ( " KRG " ) ;
knownKeywords . push_back ( " KRGR " ) ;
knownKeywords . push_back ( " KRO " ) ;
knownKeywords . push_back ( " KRORG " ) ;
knownKeywords . push_back ( " KRORW " ) ;
knownKeywords . push_back ( " KRW " ) ;
knownKeywords . push_back ( " KRWR " ) ;
knownKeywords . push_back ( " MINPVV " ) ;
knownKeywords . push_back ( " MULTPV " ) ;
knownKeywords . push_back ( " MULTX " ) ;
knownKeywords . push_back ( " MULTX- " ) ;
knownKeywords . push_back ( " MULTY " ) ;
knownKeywords . push_back ( " MULTY- " ) ;
knownKeywords . push_back ( " MULTZ " ) ;
knownKeywords . push_back ( " NTG " ) ;
knownKeywords . push_back ( " PCG " ) ;
knownKeywords . push_back ( " PCW " ) ;
knownKeywords . push_back ( " PERMX " ) ;
knownKeywords . push_back ( " PERMY " ) ;
knownKeywords . push_back ( " PERMZ " ) ;
knownKeywords . push_back ( " PORO " ) ;
knownKeywords . push_back ( " PVTNUM " ) ;
knownKeywords . push_back ( " SATNUM " ) ;
knownKeywords . push_back ( " SGCR " ) ;
knownKeywords . push_back ( " SGL " ) ;
knownKeywords . push_back ( " SGLPC " ) ;
knownKeywords . push_back ( " SGU " ) ;
knownKeywords . push_back ( " SGWCR " ) ;
knownKeywords . push_back ( " SWATINIT " ) ;
knownKeywords . push_back ( " SWCR " ) ;
knownKeywords . push_back ( " SWGCR " ) ;
knownKeywords . push_back ( " SWL " ) ;
knownKeywords . push_back ( " SWLPC " ) ;
knownKeywords . push_back ( " TRANX " ) ;
knownKeywords . push_back ( " TRANY " ) ;
knownKeywords . push_back ( " TRANZ " ) ;
isInitialized = true ;
}
return knownKeywords ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-03-22 09:43:42 -05:00
bool RifEclipseInputFileTools : : writePropertyToTextFile ( const QString & fileName , RigCaseData * eclipseCase , size_t timeStep , const QString & resultName , const QString & eclipseKeyWord )
2012-06-26 09:10:41 -05:00
{
2013-02-13 06:24:39 -06:00
CVF_ASSERT ( eclipseCase ) ;
2012-06-26 09:10:41 -05:00
2013-02-13 06:24:39 -06:00
size_t resultIndex = eclipseCase - > results ( RifReaderInterface : : MATRIX_RESULTS ) - > findScalarResultIndex ( resultName ) ;
2012-06-26 09:10:41 -05:00
if ( resultIndex = = cvf : : UNDEFINED_SIZE_T )
{
return false ;
}
QFile file ( fileName ) ;
if ( ! file . open ( QIODevice : : WriteOnly | QIODevice : : Text ) )
{
return false ;
}
2013-02-13 06:24:39 -06:00
std : : vector < std : : vector < double > > & resultData = eclipseCase - > results ( RifReaderInterface : : MATRIX_RESULTS ) - > cellScalarResults ( resultIndex ) ;
2012-06-26 09:10:41 -05:00
if ( resultData . size ( ) = = 0 )
{
return false ;
}
std : : vector < double > & singleTimeStepData = resultData [ timeStep ] ;
writeDataToTextFile ( & file , eclipseKeyWord , singleTimeStepData ) ;
return true ;
}
//--------------------------------------------------------------------------------------------------
/// Create and write a result vector with values for all cells.
/// undefinedValue is used for cells with no result
//--------------------------------------------------------------------------------------------------
2013-03-22 09:43:42 -05:00
bool RifEclipseInputFileTools : : writeBinaryResultToTextFile ( const QString & fileName , RigCaseData * eclipseCase , RifReaderInterface : : PorosityModelResultType porosityModel , size_t timeStep , const QString & resultName , const QString & eclipseKeyWord , const double undefinedValue )
2012-06-26 09:10:41 -05:00
{
2013-02-13 06:24:39 -06:00
CVF_ASSERT ( eclipseCase ) ;
2012-06-26 09:10:41 -05:00
2013-02-13 06:24:39 -06:00
size_t resultIndex = eclipseCase - > results ( porosityModel ) - > findScalarResultIndex ( resultName ) ;
2012-06-26 09:10:41 -05:00
if ( resultIndex = = cvf : : UNDEFINED_SIZE_T )
{
return false ;
}
QFile file ( fileName ) ;
if ( ! file . open ( QIODevice : : WriteOnly | QIODevice : : Text ) )
{
return false ;
}
2013-02-13 06:24:39 -06:00
cvf : : ref < cvf : : StructGridScalarDataAccess > dataAccessObject = eclipseCase - > dataAccessObject ( eclipseCase - > mainGrid ( ) , porosityModel , timeStep , resultIndex ) ;
2013-02-01 06:10:31 -06:00
if ( dataAccessObject . isNull ( ) )
{
return false ;
}
2012-06-26 09:10:41 -05:00
std : : vector < double > resultData ;
size_t i , j , k ;
2013-02-13 06:24:39 -06:00
for ( k = 0 ; k < eclipseCase - > mainGrid ( ) - > cellCountK ( ) ; k + + )
2012-06-26 09:10:41 -05:00
{
2013-02-13 06:24:39 -06:00
for ( j = 0 ; j < eclipseCase - > mainGrid ( ) - > cellCountJ ( ) ; j + + )
2012-06-26 09:10:41 -05:00
{
2013-02-13 06:24:39 -06:00
for ( i = 0 ; i < eclipseCase - > mainGrid ( ) - > cellCountI ( ) ; i + + )
2012-06-26 09:10:41 -05:00
{
2013-03-01 09:00:34 -06:00
double resultValue = dataAccessObject - > cellScalar ( eclipseCase - > mainGrid ( ) - > cellIndexFromIJK ( i , j , k ) ) ;
2012-06-26 09:10:41 -05:00
if ( resultValue = = HUGE_VAL )
{
resultValue = undefinedValue ;
}
resultData . push_back ( resultValue ) ;
}
}
}
writeDataToTextFile ( & file , eclipseKeyWord , resultData ) ;
return true ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifEclipseInputFileTools : : writeDataToTextFile ( QFile * file , const QString & eclipseKeyWord , const std : : vector < double > & resultData )
{
QTextStream out ( file ) ;
out < < " \n " ;
out < < " -- Exported from ResInsight " < < " \n " ;
out < < eclipseKeyWord < < " \n " < < right < < qSetFieldWidth ( 16 ) ;
caf : : ProgressInfo pi ( resultData . size ( ) , QString ( " Writing data to file %1 " ) . arg ( file - > fileName ( ) ) ) ;
2013-01-23 03:56:09 -06:00
size_t progressSteps = resultData . size ( ) / 20 ;
2012-06-26 09:10:41 -05:00
size_t i ;
for ( i = 0 ; i < resultData . size ( ) ; i + + )
{
out < < resultData [ i ] ;
if ( ( i + 1 ) % 5 = = 0 )
{
out < < " \n " ;
}
if ( i % progressSteps = = 0 )
{
pi . setProgress ( i ) ;
}
}
out < < " \n " < < " / " < < " \n " ;
}
2012-10-08 12:44:10 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-12-03 13:30:32 -06:00
void RifEclipseInputFileTools : : findGridKeywordPositions ( const std : : vector < RifKeywordAndFilePos > & keywordsAndFilePos , qint64 * coordPos , qint64 * zcornPos , qint64 * specgridPos , qint64 * actnumPos , qint64 * mapaxesPos )
2012-10-08 12:44:10 -05:00
{
CVF_ASSERT ( coordPos & & zcornPos & & specgridPos & & actnumPos & & mapaxesPos ) ;
size_t i ;
for ( i = 0 ; i < keywordsAndFilePos . size ( ) ; i + + )
{
if ( keywordsAndFilePos [ i ] . keyword = = " COORD " )
{
* coordPos = keywordsAndFilePos [ i ] . filePos ;
}
else if ( keywordsAndFilePos [ i ] . keyword = = " ZCORN " )
{
* zcornPos = keywordsAndFilePos [ i ] . filePos ;
}
else if ( keywordsAndFilePos [ i ] . keyword = = " SPECGRID " )
{
* specgridPos = keywordsAndFilePos [ i ] . filePos ;
}
else if ( keywordsAndFilePos [ i ] . keyword = = " ACTNUM " )
{
* actnumPos = keywordsAndFilePos [ i ] . filePos ;
}
else if ( keywordsAndFilePos [ i ] . keyword = = " MAPAXES " )
{
* mapaxesPos = keywordsAndFilePos [ i ] . filePos ;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-03-22 09:43:42 -05:00
bool RifEclipseInputFileTools : : readPropertyAtFilePosition ( const QString & fileName , RigCaseData * eclipseCase , const QString & eclipseKeyWord , qint64 filePos , const QString & resultName )
2012-10-08 12:44:10 -05:00
{
2013-02-13 06:24:39 -06:00
CVF_ASSERT ( eclipseCase ) ;
2012-10-08 12:44:10 -05:00
FILE * filePointer = util_fopen ( fileName . toLatin1 ( ) . data ( ) , " r " ) ;
if ( ! filePointer ) return false ;
fseek ( filePointer , filePos , SEEK_SET ) ;
ecl_kw_type * eclKeyWordData = ecl_kw_fscanf_alloc_current_grdecl__ ( filePointer , false , ECL_FLOAT_TYPE ) ;
bool isOk = false ;
if ( eclKeyWordData )
{
QString newResultName = resultName ;
2013-02-13 06:24:39 -06:00
size_t resultIndex = eclipseCase - > results ( RifReaderInterface : : MATRIX_RESULTS ) - > findScalarResultIndex ( newResultName ) ;
2012-10-08 12:44:10 -05:00
if ( resultIndex = = cvf : : UNDEFINED_SIZE_T )
{
2013-03-21 09:31:47 -05:00
resultIndex = eclipseCase - > results ( RifReaderInterface : : MATRIX_RESULTS ) - > addEmptyScalarResult ( RimDefines : : INPUT_PROPERTY , newResultName , false ) ;
2012-10-08 12:44:10 -05:00
}
2013-02-13 06:24:39 -06:00
std : : vector < std : : vector < double > > & newPropertyData = eclipseCase - > results ( RifReaderInterface : : MATRIX_RESULTS ) - > cellScalarResults ( resultIndex ) ;
2012-10-08 12:44:10 -05:00
newPropertyData . resize ( 1 ) ;
newPropertyData [ 0 ] . resize ( ecl_kw_get_size ( eclKeyWordData ) , HUGE_VAL ) ;
ecl_kw_get_data_as_double ( eclKeyWordData , newPropertyData [ 0 ] . data ( ) ) ;
isOk = true ;
ecl_kw_free ( eclKeyWordData ) ;
}
util_fclose ( filePointer ) ;
return isOk ;
}
2013-12-03 13:30:32 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifEclipseInputFileTools : : readFaults ( const QString & fileName , cvf : : Collection < RigFault > & faults , const std : : vector < RifKeywordAndFilePos > & fileKeywords )
{
QFile data ( fileName ) ;
if ( ! data . open ( QFile : : ReadOnly ) )
{
return ;
}
for ( size_t i = 0 ; i < fileKeywords . size ( ) ; i + + )
{
if ( fileKeywords [ i ] . keyword . compare ( editKeyword , Qt : : CaseInsensitive ) = = 0 )
{
return ;
}
else if ( fileKeywords [ i ] . keyword . compare ( faultsKeyword , Qt : : CaseInsensitive ) ! = 0 )
{
continue ;
}
qint64 filePos = fileKeywords [ i ] . filePos ;
bool isEditKeywordDetected = false ;
readFaults ( data , filePos , faults , & isEditKeywordDetected ) ;
if ( isEditKeywordDetected )
{
return ;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifEclipseInputFileTools : : readFaultsInGridSection ( const QString & fileName , cvf : : Collection < RigFault > & faults )
{
QFile data ( fileName ) ;
if ( ! data . open ( QFile : : ReadOnly ) )
{
return ;
}
QString gridKeyword ( " GRID " ) ;
// Search for keyword grid
qint64 gridPos = findKeyword ( gridKeyword , data ) ;
if ( gridPos < 0 )
{
return ;
}
bool isEditKeywordDetected = false ;
readFaultsAndParseIncludeStatementsRecursively ( data , gridPos , faults , & isEditKeywordDetected ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RifEclipseInputFileTools : : findFaultByName ( const cvf : : Collection < RigFault > & faults , const QString & name )
{
for ( size_t i = 0 ; i < faults . size ( ) ; i + + )
{
if ( faults . at ( i ) - > name ( ) = = name )
{
return i ;
}
}
return cvf : : UNDEFINED_SIZE_T ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
qint64 RifEclipseInputFileTools : : findKeyword ( const QString & keyword , QFile & file )
{
QString line ;
do
{
line = file . readLine ( ) ;
if ( line . startsWith ( " -- " , Qt : : CaseInsensitive ) )
{
continue ;
}
line = line . trimmed ( ) ;
if ( line . startsWith ( keyword , Qt : : CaseInsensitive ) )
{
return file . pos ( ) ;
}
} while ( ! file . atEnd ( ) ) ;
return - 1 ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifEclipseInputFileTools : : readFaultsAndParseIncludeStatementsRecursively ( QFile & file , qint64 startPos , cvf : : Collection < RigFault > & faults , bool * isEditKeywordDetected )
{
QString line ;
if ( ! file . seek ( startPos ) )
{
return false ;
}
bool continueParsing = true ;
do
{
line = file . readLine ( ) ;
if ( line . startsWith ( " -- " , Qt : : CaseInsensitive ) )
{
continue ;
}
else if ( line . startsWith ( editKeyword , Qt : : CaseInsensitive ) )
{
if ( isEditKeywordDetected )
{
* isEditKeywordDetected = true ;
}
return false ;
}
line = line . trimmed ( ) ;
if ( line . startsWith ( includeKeyword , Qt : : CaseInsensitive ) )
{
QString nextLine = file . readLine ( ) ;
int firstQuote = nextLine . indexOf ( " ' " ) ;
int lastQuote = nextLine . lastIndexOf ( " ' " ) ;
if ( ! ( firstQuote < 0 | | lastQuote < 0 | | firstQuote = = lastQuote ) )
{
QDir currentFileFolder ;
{
QFileInfo fi ( file . fileName ( ) ) ;
currentFileFolder = fi . absoluteDir ( ) ;
}
// Read include file name, and both relative and absolute path is supported
QString includeFilename = nextLine . mid ( firstQuote + 1 , lastQuote - firstQuote - 1 ) ;
QFileInfo fi ( currentFileFolder , includeFilename ) ;
if ( fi . exists ( ) )
{
QString absoluteFilename = fi . canonicalFilePath ( ) ;
QFile includeFile ( absoluteFilename ) ;
if ( includeFile . open ( QFile : : ReadOnly ) )
{
qDebug ( ) < < " Found include statement, and start parsing of \n " < < absoluteFilename ;
if ( ! readFaultsAndParseIncludeStatementsRecursively ( includeFile , 0 , faults , isEditKeywordDetected ) )
{
qDebug ( ) < < " Error when parsing include file : " < < absoluteFilename ;
}
}
}
}
}
else if ( line . startsWith ( faultsKeyword , Qt : : CaseInsensitive ) )
{
readFaults ( file , file . pos ( ) , faults , isEditKeywordDetected ) ;
}
if ( isEditKeywordDetected & & * isEditKeywordDetected )
{
continueParsing = false ;
}
if ( file . atEnd ( ) )
{
continueParsing = false ;
}
} while ( continueParsing ) ;
return true ;
}
//--------------------------------------------------------------------------------------------------
/// The file pointer is pointing at the line following the FAULTS keyword.
/// Parse content of this keyword until end of file or
/// end of keyword when a single line with '/' is found
//--------------------------------------------------------------------------------------------------
void RifEclipseInputFileTools : : readFaults ( QFile & data , qint64 filePos , cvf : : Collection < RigFault > & faults , bool * isEditKeywordDetected )
{
if ( ! data . seek ( filePos ) )
{
return ;
}
qDebug ( ) < < " Reading faults from \n " < < data . fileName ( ) ;
RigFault * fault = NULL ;
do
{
QString line = data . readLine ( ) ;
line = line . trimmed ( ) ;
if ( line . startsWith ( " -- " , Qt : : CaseInsensitive ) )
{
// Skip comment lines
continue ;
}
else if ( line . startsWith ( " / " , Qt : : CaseInsensitive ) )
{
// Detected end of keyword data section
return ;
}
else if ( line . startsWith ( editKeyword , Qt : : CaseInsensitive ) )
{
// End parsing when edit keyword is detected
if ( isEditKeywordDetected )
{
* isEditKeywordDetected = true ;
}
return ;
}
// Replace tab with space to be able to split the string using space as splitter
line . replace ( " \t " , " " ) ;
QStringList entries = line . split ( " " , QString : : SkipEmptyParts ) ;
if ( entries . size ( ) < 8 )
{
continue ;
}
QString name = entries [ 0 ] ;
name . remove ( " ' " ) ;
int i1 , i2 , j1 , j2 , k1 , k2 ;
i1 = entries [ 1 ] . toInt ( ) ;
i2 = entries [ 2 ] . toInt ( ) ;
j1 = entries [ 3 ] . toInt ( ) ;
j2 = entries [ 4 ] . toInt ( ) ;
k1 = entries [ 5 ] . toInt ( ) ;
k2 = entries [ 6 ] . toInt ( ) ;
QString faceString = entries [ 7 ] ;
faceString . remove ( " ' " ) ;
cvf : : StructGridInterface : : FaceEnum cellFaceEnum = cvf : : StructGridInterface : : FaceEnum : : fromText ( faceString ) ;
cvf : : CellRange cellrange ( i1 - 1 , j1 - 1 , k1 - 1 , i2 - 1 , j2 - 1 , k2 - 1 ) ; // Adjust from 1-based to 0-based cell indices
if ( ! ( fault & & fault - > name ( ) = = name ) )
{
if ( findFaultByName ( faults , name ) = = cvf : : UNDEFINED_SIZE_T )
{
RigFault * newFault = new RigFault ;
newFault - > setName ( name ) ;
faults . push_back ( newFault ) ;
}
size_t faultIndex = findFaultByName ( faults , name ) ;
if ( faultIndex = = cvf : : UNDEFINED_SIZE_T )
{
CVF_ASSERT ( faultIndex ! = cvf : : UNDEFINED_SIZE_T ) ;
continue ;
}
fault = faults . at ( faultIndex ) ;
}
CVF_ASSERT ( fault ) ;
fault - > addCellRangeForFace ( cellFaceEnum , cellrange ) ;
} while ( ! data . atEnd ( ) ) ;
}