2013-05-28 10:43:32 +02:00
# include <QtNetwork>
# include <octave/oct.h>
# include "riSettings.h"
void setEclipseProperty ( const NDArray & propertyFrames , const QString & hostName , quint16 port ,
const qint64 & caseId , const qint64 & gridIndex , QString propertyName , const int32NDArray & timeStepIndices , QString porosityModel )
{
QTcpSocket socket ;
socket . connectToHost ( hostName , port ) ;
2013-08-12 11:38:09 +02:00
if ( ! socket . waitForConnected ( riOctavePlugin : : shortTimeOutMilliSecs ) )
2013-05-28 10:43:32 +02:00
{
error ( ( ( " Connection: " ) + socket . errorString ( ) ) . toLatin1 ( ) . data ( ) ) ;
return ;
}
QDataStream socketStream ( & socket ) ;
socketStream . setVersion ( riOctavePlugin : : qtDataStreamVersion ) ;
// Create command as a string with arguments , and send it:
QString command = QString ( " SetGridProperty %1 %2 %3 %4 " ) . arg ( caseId ) . arg ( gridIndex ) . arg ( propertyName ) . arg ( porosityModel ) ;
for ( int i = 0 ; i < timeStepIndices . length ( ) ; + + i )
{
if ( i = = 0 ) command + = " " ;
command + = QString : : number ( static_cast < int > ( timeStepIndices . elem ( i ) ) - 1 ) ; // To make the index 0-based
if ( i ! = timeStepIndices . length ( ) - 1 ) command + = " " ;
}
QByteArray cmdBytes = command . toLatin1 ( ) ;
socketStream < < ( qint64 ) ( cmdBytes . size ( ) ) ;
socket . write ( cmdBytes ) ;
// Write property data header
dim_vector mxDims = propertyFrames . dims ( ) ;
qint64 cellCountI = mxDims . elem ( 0 ) ;
qint64 cellCountJ = mxDims . elem ( 1 ) ;
qint64 cellCountK = mxDims . elem ( 2 ) ;
2013-08-09 13:42:25 +02:00
qint64 timeStepCount = 0 ;
if ( mxDims . length ( ) > 3 )
{
timeStepCount = mxDims . elem ( 3 ) ;
}
else
{
timeStepCount = 1 ;
}
2013-05-28 10:43:32 +02:00
qint64 singleTimeStepByteCount = cellCountI * cellCountJ * cellCountK * sizeof ( double ) ;
//octave_stdout << " Cell count I: " << cellCountI << " Cell count J: " << cellCountJ << " Cell count K: " << cellCountK << std::endl;
//octave_stdout << " Time step count: " << timeStepCount << std::endl;
socketStream < < ( qint64 ) ( cellCountI ) ;
socketStream < < ( qint64 ) ( cellCountJ ) ;
socketStream < < ( qint64 ) ( cellCountK ) ;
socketStream < < ( qint64 ) ( timeStepCount ) ;
socketStream < < ( qint64 ) singleTimeStepByteCount ;
const double * internalData = propertyFrames . fortran_vec ( ) ;
int dataWritten = socket . write ( ( const char * ) internalData , singleTimeStepByteCount * timeStepCount ) ;
if ( dataWritten = = singleTimeStepByteCount * timeStepCount )
{
QString tmp = QString ( " riSetGridProperty : Wrote %1 " ) . arg ( propertyName ) ;
if ( caseId = = - 1 )
{
2013-08-12 10:12:36 +02:00
tmp + = QString ( " to current case, " ) ;
2013-05-28 10:43:32 +02:00
}
else
{
2013-08-12 10:12:36 +02:00
tmp + = QString ( " to case with Id = %1, " ) . arg ( caseId ) ;
2013-05-28 10:43:32 +02:00
}
2013-08-12 10:12:36 +02:00
tmp + = QString ( " grid index: %1, " ) . arg ( gridIndex ) ;
octave_stdout < < tmp . toStdString ( ) < < " Time steps : " < < timeStepCount < < std : : endl ;
2013-05-28 10:43:32 +02:00
}
else
{
size_t cellCount = cellCountI * cellCountJ * cellCountK ;
error ( " riSetGridProperty : Was not able to write the proper amount of data to ResInsight: " ) ;
octave_stdout < < " Cell count : " < < cellCount < < " Time steps : " < < timeStepCount < < " Data Written: " < < dataWritten < < " Should have written: " < < timeStepCount * cellCount * sizeof ( double ) < < std : : endl ;
}
while ( socket . bytesToWrite ( ) & & socket . state ( ) = = QAbstractSocket : : ConnectedState )
{
// octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl;
2013-08-12 11:38:09 +02:00
socket . waitForBytesWritten ( riOctavePlugin : : longTimeOutMilliSecs ) ;
2013-05-28 10:43:32 +02:00
OCTAVE_QUIT ;
}
if ( socket . bytesToWrite ( ) & & socket . state ( ) ! = QAbstractSocket : : ConnectedState )
{
2013-08-09 13:42:25 +02:00
error ( " riSetGridProperty : ResInsight refused to accept the data. Maybe the dimensions or porosity model is wrong. \n " ) ;
2013-05-28 10:43:32 +02:00
}
return ;
}
DEFUN_DLD ( riSetGridProperty , args , nargout ,
" Usage: \n "
" \n "
" \t riSetGridProperty( Matrix[numI][numJ][numK][numTimeSteps], [CaseId], GridIndex, PropertyName, [TimeStepIndices], [PorosityModel = \" Matrix \" | \" Fracture \" ] ) \n "
" \n "
" Interprets the supplied matrix as a property set defined for all cells in one of the grids in a case, and puts the data into ResInsight as a \" Generated \" property with the name \" PropertyName \" . \n "
" If the CaseId is not defined, ResInsight’ s Current Case is used. \n "
)
{
int nargin = args . length ( ) ;
if ( nargin < 2 )
{
error ( " riSetGridProperty: Too few arguments, required input parameters are the data matrix, grid index and property name. \n " ) ;
print_usage ( ) ;
return octave_value_list ( ) ;
}
if ( nargin > 6 )
{
error ( " riSetGridProperty: Too many arguments. \n " ) ;
print_usage ( ) ;
return octave_value_list ( ) ;
}
NDArray propertyFrames = args ( 0 ) . array_value ( ) ;
if ( error_state )
{
error ( " riSetGridProperty: The supplied first argument is not a valid Matrix " ) ;
print_usage ( ) ;
return octave_value_list ( ) ;
}
dim_vector mxDims = propertyFrames . dims ( ) ;
2013-08-09 13:42:25 +02:00
if ( ! ( mxDims . length ( ) = = 3 | | mxDims . length ( ) = = 4 ) )
2013-05-28 10:43:32 +02:00
{
2013-08-09 13:42:25 +02:00
error ( " riSetGridProperty: The supplied Data Matrix must have three dimensions (numI*numJ*numK*1) or four dimensions (numI*numJ*numK*numTimeSteps) " ) ;
2013-05-28 10:43:32 +02:00
print_usage ( ) ;
return octave_value_list ( ) ;
}
std : : vector < int > argIndices ;
2013-05-28 11:11:11 +02:00
argIndices . push_back ( 0 ) ; // Array data
argIndices . push_back ( 1 ) ; // Case Id
argIndices . push_back ( 2 ) ; // GridIndex
argIndices . push_back ( 3 ) ; // Property name
argIndices . push_back ( 4 ) ; // Time step indices
argIndices . push_back ( 5 ) ; // Porosity model
2013-06-04 16:10:39 +02:00
// Check that the second argument is an integer
if ( ! args ( argIndices [ 1 ] ) . is_real_scalar ( ) ) // Check if second argument is an int. If it is
{
error ( " riSetGridProperty: The GridIndex argument is missing " ) ;
print_usage ( ) ;
return octave_value_list ( ) ;
}
2013-05-28 11:11:11 +02:00
// Check if we do not have a CaseId:
if ( args ( argIndices [ 2 ] ) . is_string ( ) ) // Check if second argument is a text. If it is, the caseid is missing
2013-05-28 10:43:32 +02:00
{
argIndices [ 1 ] = - 1 ;
for ( size_t aIdx = 2 ; aIdx < argIndices . size ( ) ; + + aIdx )
- - argIndices [ aIdx ] ;
}
// Check if we have a Requested TimeSteps
if ( ! ( nargin > argIndices [ 4 ] & & args ( argIndices [ 4 ] ) . is_matrix_type ( ) ) )
{
argIndices [ 4 ] = - 1 ;
for ( size_t aIdx = 5 ; aIdx < argIndices . size ( ) ; + + aIdx )
- - argIndices [ aIdx ] ;
}
// Check if we have a PorosityModel
int lastArgumentIndex = argIndices [ 5 ] ;
if ( ! ( nargin > argIndices [ 5 ] & & args ( argIndices [ 5 ] ) . is_string ( ) ) )
{
argIndices [ 5 ] = - 1 ;
for ( size_t aIdx = 6 ; aIdx < argIndices . size ( ) ; + + aIdx )
- - argIndices [ aIdx ] ;
}
// Check if we have more arguments than we should
if ( nargin > lastArgumentIndex + 1 )
{
error ( " riSetGridProperty: Unexpected argument after the PorosityModel. \n " ) ;
print_usage ( ) ;
return octave_value_list ( ) ;
}
int caseId = - 1 ;
int gridIndex = 0 ;
std : : string propertyName = " UNDEFINED " ;
int32NDArray timeStepIndices ;
std : : string porosityModel = " Matrix " ;
if ( argIndices [ 1 ] > = 0 ) caseId = args ( argIndices [ 1 ] ) . int_value ( ) ;
if ( argIndices [ 2 ] > = 0 ) gridIndex = args ( argIndices [ 2 ] ) . int_value ( ) ;
if ( argIndices [ 3 ] > = 0 ) propertyName = args ( argIndices [ 3 ] ) . char_matrix_value ( ) . row_as_string ( 0 ) ;
if ( argIndices [ 4 ] > = 0 ) timeStepIndices = args ( argIndices [ 4 ] ) . int32_array_value ( ) ;
if ( argIndices [ 5 ] > = 0 ) porosityModel = args ( argIndices [ 5 ] ) . string_value ( ) ;
2013-08-09 13:42:25 +02:00
if ( timeStepIndices . length ( ) > 1 )
2013-05-28 10:43:32 +02:00
{
2013-08-09 13:42:25 +02:00
if ( mxDims . length ( ) = = 3 )
{
error ( " riSetGridProperty: The input matrix has three dimensions, but there are more than one time step in [TimeStepIndices]. If more than one time step is defined, the data matrix must be 4D. " ) ;
print_usage ( ) ;
return octave_value_list ( ) ;
}
2013-06-04 16:10:39 +02:00
int timeStepCount = mxDims . elem ( 3 ) ;
2013-05-28 10:43:32 +02:00
if ( timeStepIndices . length ( ) ! = timeStepCount )
{
error ( " riSetGridProperty: The number of time steps in the input matrix must match the number of time steps in the TimeStepIndices array. " ) ;
print_usage ( ) ;
return octave_value_list ( ) ;
}
}
if ( porosityModel ! = " Matrix " & & porosityModel ! = " Fracture " )
{
2013-08-09 13:42:25 +02:00
error ( " riSetGridProperty: The value for \" PorosityModel \" is unknown. Please use either \" Matrix \" or \" Fracture \" \n " ) ;
2013-05-28 10:43:32 +02:00
print_usage ( ) ;
return octave_value_list ( ) ;
}
setEclipseProperty ( propertyFrames , " 127.0.0.1 " , 40001 , caseId , gridIndex , propertyName . c_str ( ) , timeStepIndices , porosityModel . c_str ( ) ) ;
return octave_value_list ( ) ;
}