2013-05-24 11:07:59 +02:00
//
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaStdInclude.h"
#include "RiaSocketCommand.h"
#include "RiaSocketServer.h"
#include "RiaSocketTools.h"
2013-05-28 09:20:09 +02:00
#include "RiuMainWindow.h"
2013-05-24 11:07:59 +02:00
#include "RigCaseData.h"
#include "RigCaseCellResultsData.h"
2013-05-24 12:02:52 +02:00
#include "RimReservoirCellResultsCacher.h"
2013-05-28 09:20:09 +02:00
#include "RimCase.h"
#include "RimInputCase.h"
#include "RimInputPropertyCollection.h"
#include "RimUiTreeModelPdm.h"
#include "RimReservoirView.h"
#include "RimResultSlot.h"
#include "RimCellEdgeResultSlot.h"
#include "RimCellRangeFilterCollection.h"
#include "RimCellPropertyFilterCollection.h"
#include "RimWellCollection.h"
#include "Rim3dOverlayInfoConfig.h"
#include <QTcpSocket>
2013-05-24 11:07:59 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaGetActiveCellProperty : public RiaSocketCommand
{
public :
static QString commandName () { return QString ( "GetActiveCellProperty" ); }
virtual bool interpretCommand ( RiaSocketServer * server , const QList < QByteArray >& args , QDataStream & socketStream )
{
RimCase * rimCase = RiaSocketTools :: findCaseFromArgs ( server , args );
QString propertyName = args [ 2 ];
QString porosityModelName = args [ 3 ];
RifReaderInterface :: PorosityModelResultType porosityModelEnum = RifReaderInterface :: MATRIX_RESULTS ;
if ( porosityModelName == "Fracture" )
{
porosityModelEnum = RifReaderInterface :: FRACTURE_RESULTS ;
}
// Find the requested data
size_t scalarResultIndex = cvf :: UNDEFINED_SIZE_T ;
std :: vector < std :: vector < double > >* scalarResultFrames = NULL ;
if ( rimCase && rimCase -> results ( porosityModelEnum ))
{
scalarResultIndex = rimCase -> results ( porosityModelEnum ) -> findOrLoadScalarResult ( propertyName );
if ( scalarResultIndex != cvf :: UNDEFINED_SIZE_T )
{
scalarResultFrames = & ( rimCase -> results ( porosityModelEnum ) -> cellResults () -> cellScalarResults ( scalarResultIndex ));
}
}
if ( scalarResultFrames == NULL )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) + RiaSocketServer :: tr ( "Could not find the %1 model property named: \" %2 \" " ). arg ( porosityModelName ). arg ( propertyName ));
}
// Write data back : timeStepCount, bytesPrTimestep, dataForTimestep0 ... dataForTimestepN
if ( scalarResultFrames == NULL )
{
// No data available
socketStream << ( quint64 ) 0 << ( quint64 ) 0 ;
}
else
{
// Create a list of all the requested timesteps
std :: vector < size_t > requestedTimesteps ;
if ( args . size () <= 4 )
{
// Select all
for ( size_t tsIdx = 0 ; tsIdx < scalarResultFrames -> size (); ++ tsIdx )
{
requestedTimesteps . push_back ( tsIdx );
}
}
else
{
bool timeStepReadError = false ;
for ( int argIdx = 4 ; argIdx < args . size (); ++ argIdx )
{
bool conversionOk = false ;
int tsIdx = args [ argIdx ]. toInt ( & conversionOk );
if ( conversionOk )
{
requestedTimesteps . push_back ( tsIdx );
}
else
{
timeStepReadError = true ;
}
}
if ( timeStepReadError )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: riGetActiveCellProperty : \n " ) + RiaSocketServer :: tr ( "An error occured while interpreting the requested timesteps." ));
}
}
// First write timestep count
quint64 timestepCount = ( quint64 ) requestedTimesteps . size ();
socketStream << timestepCount ;
// then the byte-size of the result values in one timestep
const RigActiveCellInfo * activeInfo = rimCase -> reservoirData () -> activeCellInfo ( porosityModelEnum );
size_t timestepResultCount = activeInfo -> globalActiveCellCount ();
quint64 timestepByteCount = ( quint64 )( timestepResultCount * sizeof ( double ));
socketStream << timestepByteCount ;
// Then write the data.
size_t globalCellCount = activeInfo -> globalCellCount ();
for ( size_t tIdx = 0 ; tIdx < requestedTimesteps . size (); ++ tIdx )
{
for ( size_t gcIdx = 0 ; gcIdx < globalCellCount ; ++ gcIdx )
{
size_t resultIdx = activeInfo -> cellResultIndex ( gcIdx );
if ( resultIdx != cvf :: UNDEFINED_SIZE_T )
{
if ( resultIdx < scalarResultFrames -> at ( requestedTimesteps [ tIdx ]). size ())
{
socketStream << scalarResultFrames -> at ( requestedTimesteps [ tIdx ])[ resultIdx ];
}
else
{
socketStream << HUGE_VAL ;
}
}
}
}
#if 0
// This aproach is faster but does not handle coarsening
size_t timestepResultCount = scalarResultFrames->front().size();
quint64 timestepByteCount = (quint64)(timestepResultCount*sizeof(double));
socketStream << timestepByteCount ;
// Then write the data.
for (size_t tIdx = 0; tIdx < requestedTimesteps.size(); ++tIdx)
{
#if 1 // Write data as raw bytes, fast but does not handle byteswapping
server->currentClient()->write((const char *)scalarResultFrames->at(requestedTimesteps[tIdx]).data(), timestepByteCount); // Raw print of data. Fast but no platform conversion
#else // Write data using QDataStream, does byteswapping for us. Must use QDataStream on client as well
for (size_t cIdx = 0; cIdx < scalarResultFrames->at(requestedTimesteps[tIdx]).size(); ++cIdx)
{
socketStream << scalarResultFrames->at(tIdx)[cIdx];
}
#endif
}
#endif
}
return true ;
}
};
static bool RiaGetActiveCellProperty_init = RiaSocketCommandFactory :: instance () -> registerCreator < RiaGetActiveCellProperty > ( RiaGetActiveCellProperty :: commandName ());
2013-05-24 12:02:52 +02:00
2013-05-27 12:22:05 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaGetGridProperty : public RiaSocketCommand
{
public :
static QString commandName () { return QString ( "GetGridProperty" ); }
virtual bool interpretCommand ( RiaSocketServer * server , const QList < QByteArray >& args , QDataStream & socketStream )
{
2013-05-28 09:20:09 +02:00
int caseId = args [ 1 ]. toInt ();
int gridIdx = args [ 2 ]. toInt ();
QString propertyName = args [ 3 ];
2013-05-27 12:22:05 +02:00
QString porosityModelName = args [ 4 ];
2013-05-28 09:20:09 +02:00
RimCase * rimCase = server -> findReservoir ( caseId );
if ( rimCase == NULL )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) + RiaSocketServer :: tr ( "Could not find the case with ID: \" %1 \" " ). arg ( caseId ));
// No data available
socketStream << ( quint64 ) 0 << ( quint64 ) 0 << ( quint64 ) 0 << ( quint64 ) 0 ;
return true ;
}
2013-05-27 12:22:05 +02:00
RifReaderInterface :: PorosityModelResultType porosityModelEnum = RifReaderInterface :: MATRIX_RESULTS ;
if ( porosityModelName == "Fracture" )
{
porosityModelEnum = RifReaderInterface :: FRACTURE_RESULTS ;
}
size_t scalarResultIndex = cvf :: UNDEFINED_SIZE_T ;
if ( gridIdx < 0 || rimCase -> reservoirData () -> gridCount () <= ( size_t ) gridIdx )
{
server -> errorMessageDialog () -> showMessage ( "ResInsight SocketServer: riGetGridProperty : \n "
"The gridIndex \" " + QString :: number ( gridIdx ) + " \" does not point to an existing grid." );
}
else
{
// Find the requested data
if ( rimCase && rimCase -> results ( porosityModelEnum ))
{
scalarResultIndex = rimCase -> results ( porosityModelEnum ) -> findOrLoadScalarResult ( propertyName );
}
}
2013-08-12 10:04:30 +02:00
if ( scalarResultIndex == cvf :: UNDEFINED_SIZE_T )
2013-05-27 12:22:05 +02:00
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) + RiaSocketServer :: tr ( "Could not find the %1 model property named: \" %2 \" " ). arg ( porosityModelName ). arg ( propertyName ));
// No data available
socketStream << ( quint64 ) 0 << ( quint64 ) 0 << ( quint64 ) 0 << ( quint64 ) 0 ;
return true ;
}
2013-08-12 10:04:30 +02:00
2013-05-28 09:20:09 +02:00
// Create a list of all the requested time steps
2013-05-27 12:22:05 +02:00
std :: vector < size_t > requestedTimesteps ;
2013-05-28 09:20:09 +02:00
if ( args . size () <= 5 )
2013-05-27 12:22:05 +02:00
{
// Select all
2013-08-12 10:04:30 +02:00
for ( size_t tsIdx = 0 ; tsIdx < rimCase -> results ( porosityModelEnum ) -> cellResults () -> timeStepCount ( scalarResultIndex ); ++ tsIdx )
2013-05-27 12:22:05 +02:00
{
requestedTimesteps . push_back ( tsIdx );
}
}
else
{
bool timeStepReadError = false ;
2013-05-28 09:20:09 +02:00
for ( int argIdx = 5 ; argIdx < args . size (); ++ argIdx )
2013-05-27 12:22:05 +02:00
{
bool conversionOk = false ;
int tsIdx = args [ argIdx ]. toInt ( & conversionOk );
if ( conversionOk )
{
requestedTimesteps . push_back ( tsIdx );
}
else
{
timeStepReadError = true ;
}
}
if ( timeStepReadError )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: riGetGridProperty : \n " )
+ RiaSocketServer :: tr ( "An error occured while interpreting the requested timesteps." ));
}
}
RigGridBase * rigGrid = rimCase -> reservoirData () -> grid ( gridIdx );
quint64 cellCountI = ( quint64 ) rigGrid -> cellCountI ();
quint64 cellCountJ = ( quint64 ) rigGrid -> cellCountJ ();
quint64 cellCountK = ( quint64 ) rigGrid -> cellCountK ();
socketStream << cellCountI ;
socketStream << cellCountJ ;
socketStream << cellCountK ;
2013-05-28 09:20:09 +02:00
// Write time step count
2013-05-27 12:22:05 +02:00
quint64 timestepCount = ( quint64 ) requestedTimesteps . size ();
socketStream << timestepCount ;
2013-05-28 09:20:09 +02:00
size_t doubleValueCount = cellCountI * cellCountJ * cellCountK * timestepCount * sizeof ( double );
std :: vector < double > values ( doubleValueCount );
size_t valueIdx = 0 ;
2013-05-27 12:22:05 +02:00
for ( size_t tsIdx = 0 ; tsIdx < timestepCount ; tsIdx ++ )
{
2013-08-12 10:04:30 +02:00
cvf :: ref < cvf :: StructGridScalarDataAccess > cellCenterDataAccessObject = rimCase -> reservoirData () -> dataAccessObject ( rigGrid , porosityModelEnum , requestedTimesteps [ tsIdx ], scalarResultIndex );
if ( cellCenterDataAccessObject . isNull ())
2013-05-27 12:22:05 +02:00
{
2013-08-12 10:04:30 +02:00
continue ;
}
2013-05-27 12:22:05 +02:00
2013-09-11 10:26:53 +02:00
for ( size_t cellIdx = 0 ; cellIdx < rigGrid -> cellCount (); cellIdx ++ )
2013-08-12 10:04:30 +02:00
{
2013-08-12 17:04:31 +02:00
double cellValue = cellCenterDataAccessObject -> cellScalar ( cellIdx );
if ( cellValue == HUGE_VAL )
{
cellValue = 0.0 ;
}
2013-09-11 10:26:53 +02:00
values [ valueIdx ++ ] = cellValue ;
2013-05-27 12:22:05 +02:00
}
}
2013-05-28 09:20:09 +02:00
server -> currentClient () -> write (( const char * ) values . data (), doubleValueCount );
2013-05-27 12:22:05 +02:00
return true ;
}
};
static bool RiaGetGridProperty_init = RiaSocketCommandFactory :: instance () -> registerCreator < RiaGetGridProperty > ( RiaGetGridProperty :: commandName ());
2013-05-24 12:02:52 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaSetActiveCellProperty : public RiaSocketCommand
{
public :
RiaSetActiveCellProperty () :
m_currentReservoir ( NULL ),
m_scalarResultsToAdd ( NULL ),
m_currentScalarIndex ( cvf :: UNDEFINED_SIZE_T ),
m_timeStepCountToRead ( 0 ),
m_bytesPerTimeStepToRead ( 0 ),
2013-05-26 12:07:42 +02:00
m_currentTimeStepNumberToRead ( 0 ),
2013-05-24 12:02:52 +02:00
m_invalidActiveCellCountDetected ( false ),
m_porosityModelEnum ( RifReaderInterface :: MATRIX_RESULTS )
{}
static QString commandName () { return QString ( "SetActiveCellProperty" ); }
virtual bool interpretCommand ( RiaSocketServer * server , const QList < QByteArray >& args , QDataStream & socketStream )
{
RimCase * rimCase = RiaSocketTools :: findCaseFromArgs ( server , args );
QString propertyName = args [ 2 ];
QString porosityModelName = args [ 3 ];
if ( porosityModelName == "Fracture" )
{
m_porosityModelEnum = RifReaderInterface :: FRACTURE_RESULTS ;
}
// Find the requested data, Or create a set if we are setting data and it is not found
size_t scalarResultIndex = cvf :: UNDEFINED_SIZE_T ;
std :: vector < std :: vector < double > >* scalarResultFrames = NULL ;
if ( rimCase && rimCase -> results ( m_porosityModelEnum ))
{
2013-05-26 12:07:42 +02:00
scalarResultIndex = rimCase -> results ( m_porosityModelEnum ) -> findOrLoadScalarResult ( RimDefines :: GENERATED , propertyName );
2013-05-24 12:02:52 +02:00
if ( scalarResultIndex == cvf :: UNDEFINED_SIZE_T )
{
scalarResultIndex = rimCase -> results ( m_porosityModelEnum ) -> cellResults () -> addEmptyScalarResult ( RimDefines :: GENERATED , propertyName , true );
}
if ( scalarResultIndex != cvf :: UNDEFINED_SIZE_T )
{
scalarResultFrames = & ( rimCase -> results ( m_porosityModelEnum ) -> cellResults () -> cellScalarResults ( scalarResultIndex ));
m_currentScalarIndex = scalarResultIndex ;
m_currentPropertyName = propertyName ;
}
}
if ( scalarResultFrames == NULL )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) + RiaSocketServer :: tr ( "Could not find the %1 model property named: \" %2 \" " ). arg ( porosityModelName ). arg ( propertyName ));
return true ;
}
2013-05-28 16:02:00 +02:00
// If we have not read the header and there are data enough: Read it.
// Do nothing if we have not enough data
if ( m_timeStepCountToRead == 0 || m_bytesPerTimeStepToRead == 0 )
{
if ( server -> currentClient () -> bytesAvailable () < ( int ) sizeof ( quint64 ) * 2 ) return true ;
socketStream >> m_timeStepCountToRead ;
socketStream >> m_bytesPerTimeStepToRead ;
}
// std::cout << "RiaSetActiveCellProperty: " << propertyName.data() << " timeStepCount " << m_timeStepCountToRead << " bytesPerTimeStep " << m_bytesPerTimeStepToRead;
2013-05-24 12:02:52 +02:00
// Create a list of all the requested timesteps
m_requestedTimesteps . clear ();
if ( args . size () <= 4 )
{
// Select all
2013-05-28 16:02:00 +02:00
for ( size_t tsIdx = 0 ; tsIdx < m_timeStepCountToRead ; ++ tsIdx )
2013-05-24 12:02:52 +02:00
{
m_requestedTimesteps . push_back ( tsIdx );
}
}
else
{
bool timeStepReadError = false ;
for ( int argIdx = 4 ; argIdx < args . size (); ++ argIdx )
{
bool conversionOk = false ;
int tsIdx = args [ argIdx ]. toInt ( & conversionOk );
if ( conversionOk )
{
m_requestedTimesteps . push_back ( tsIdx );
}
else
{
timeStepReadError = true ;
}
}
if ( timeStepReadError )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: riGetActiveCellProperty : \n " ) + RiaSocketServer :: tr ( "An error occured while interpreting the requested timesteps." ));
}
}
2013-05-26 12:07:42 +02:00
if ( ! m_requestedTimesteps . size ())
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) + RiaSocketServer :: tr ( "No time steps specified" ). arg ( porosityModelName ). arg ( propertyName ));
return true ;
}
// Resize the result container to be able to receive timesteps at the specified timestep idices
std :: vector < size_t >:: iterator maxTimeStepIt = std :: max_element ( m_requestedTimesteps . begin (), m_requestedTimesteps . end ());
CVF_ASSERT ( maxTimeStepIt != m_requestedTimesteps . end ());
size_t maxTimeStepIdx = ( * maxTimeStepIt );
if ( scalarResultFrames -> size () <= maxTimeStepIdx )
{
scalarResultFrames -> resize ( maxTimeStepIdx + 1 );
}
2013-05-24 12:02:52 +02:00
m_currentReservoir = rimCase ;
m_scalarResultsToAdd = scalarResultFrames ;
if ( server -> currentClient () -> bytesAvailable ())
{
return this -> interpretMore ( server , server -> currentClient ());
}
return false ;
}
virtual bool interpretMore ( RiaSocketServer * server , QTcpSocket * currentClient )
{
2013-05-28 16:02:00 +02:00
// std::cout << "RiaSetActiveCellProperty, interpretMore: scalarIndex : " << m_currentScalarIndex;
2013-05-24 12:02:52 +02:00
if ( m_invalidActiveCellCountDetected ) return true ;
if ( ! currentClient -> bytesAvailable ()) return false ;
QDataStream socketStream ( currentClient );
socketStream . setVersion ( riOctavePlugin :: qtDataStreamVersion );
2013-05-26 12:07:42 +02:00
if ( m_timeStepCountToRead != m_requestedTimesteps . size ())
{
CVF_ASSERT ( false );
}
2013-05-24 12:02:52 +02:00
// If nothing should be read, or we already have read everything, do nothing
2013-05-26 12:07:42 +02:00
if (( m_timeStepCountToRead == 0 ) || ( m_currentTimeStepNumberToRead >= m_timeStepCountToRead ) ) return true ;
2013-05-24 12:02:52 +02:00
// Check if a complete timestep is available, return and whait for readyRead() if not
if ( currentClient -> bytesAvailable () < ( int ) m_bytesPerTimeStepToRead ) return false ;
size_t cellCountFromOctave = m_bytesPerTimeStepToRead / sizeof ( double );
2013-05-26 12:07:42 +02:00
RigActiveCellInfo * activeCellInfo = m_currentReservoir -> reservoirData () -> activeCellInfo ( m_porosityModelEnum );
2013-05-27 12:22:05 +02:00
size_t globalActiveCellCount = activeCellInfo -> globalActiveCellCount ();
size_t totalCellCount = activeCellInfo -> globalCellCount ();
size_t globalCellResultCount = activeCellInfo -> globalCellResultCount ();
2013-05-26 12:16:32 +02:00
bool isCoarseningActive = globalCellResultCount != globalActiveCellCount ;
2013-05-24 12:02:52 +02:00
2013-05-26 12:16:32 +02:00
if ( cellCountFromOctave != globalActiveCellCount )
2013-05-24 12:02:52 +02:00
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) +
RiaSocketServer :: tr ( "The number of cells in the data coming from octave does not match the case" ) + ": \" " + m_currentReservoir -> caseUserDescription () + " \"\n "
" Octave: " + QString :: number ( cellCountFromOctave ) + " \n "
2013-05-26 12:16:32 +02:00
" " + m_currentReservoir -> caseUserDescription () + ": Active cell count: " + QString :: number ( globalActiveCellCount ) + " Total cell count: " + QString :: number ( totalCellCount )) ;
2013-05-24 12:02:52 +02:00
cellCountFromOctave = 0 ;
m_invalidActiveCellCountDetected = true ;
currentClient -> abort ();
return true ;
}
// Make sure the size of the retreiving container is correct.
// If it is, this is noops
2013-05-26 12:07:42 +02:00
2013-05-24 12:02:52 +02:00
for ( size_t tIdx = 0 ; tIdx < m_timeStepCountToRead ; ++ tIdx )
{
2013-05-26 12:07:42 +02:00
size_t tsId = m_requestedTimesteps [ tIdx ];
2013-05-26 12:16:32 +02:00
m_scalarResultsToAdd -> at ( tsId ). resize ( globalCellResultCount , HUGE_VAL );
2013-05-26 12:07:42 +02:00
}
std :: vector < double > readBuffer ;
double * internalMatrixData = NULL ;
2013-05-26 12:16:32 +02:00
if ( isCoarseningActive )
2013-05-26 12:07:42 +02:00
{
readBuffer . resize ( cellCountFromOctave , HUGE_VAL );
internalMatrixData = readBuffer . data ();
2013-05-24 12:02:52 +02:00
}
// Read available complete timestepdata
2013-05-26 12:16:32 +02:00
2013-05-26 12:07:42 +02:00
while (( currentClient -> bytesAvailable () >= ( int ) m_bytesPerTimeStepToRead ) && ( m_currentTimeStepNumberToRead < m_timeStepCountToRead ))
2013-05-24 12:02:52 +02:00
{
qint64 bytesRead = 0 ;
2013-05-26 12:16:32 +02:00
if ( ! isCoarseningActive )
2013-05-26 12:07:42 +02:00
{
internalMatrixData = m_scalarResultsToAdd -> at ( m_requestedTimesteps [ m_currentTimeStepNumberToRead ]). data ();
}
2013-05-24 12:02:52 +02:00
#if 1 // Use raw data transfer. Faster.
bytesRead = currentClient -> read (( char * )( internalMatrixData ), m_bytesPerTimeStepToRead );
#else
for ( size_t cIdx = 0 ; cIdx < cellCountFromOctave ; ++ cIdx )
{
socketStream >> internalMatrixData [ cIdx ];
if ( socketStream . status () == QDataStream :: Ok ) bytesRead += sizeof ( double );
}
#endif
2013-05-26 12:07:42 +02:00
// Map data from active to result index based container ( Coarsening is active)
2013-05-26 12:16:32 +02:00
if ( isCoarseningActive )
2013-05-26 12:07:42 +02:00
{
size_t acIdx = 0 ;
2013-05-26 12:16:32 +02:00
for ( size_t gcIdx = 0 ; gcIdx < totalCellCount ; ++ gcIdx )
2013-05-26 12:07:42 +02:00
{
if ( activeCellInfo -> isActive ( gcIdx ))
{
m_scalarResultsToAdd -> at ( m_requestedTimesteps [ m_currentTimeStepNumberToRead ])[ activeCellInfo -> cellResultIndex ( gcIdx )] = readBuffer [ acIdx ];
++ acIdx ;
}
}
}
2013-05-24 12:02:52 +02:00
if (( int ) m_bytesPerTimeStepToRead != bytesRead )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) +
RiaSocketServer :: tr ( "Could not read binary double data properly from socket" ));
}
2013-05-26 12:07:42 +02:00
++ m_currentTimeStepNumberToRead ;
2013-05-24 12:02:52 +02:00
}
2013-05-28 16:02:00 +02:00
2013-05-24 12:02:52 +02:00
// If we have read all the data, refresh the views
2013-05-26 12:16:32 +02:00
2013-05-26 12:07:42 +02:00
if ( m_currentTimeStepNumberToRead == m_timeStepCountToRead )
2013-05-24 12:02:52 +02:00
{
if ( m_currentReservoir != NULL )
{
// Create a new input property if we have an input reservoir
RimInputCase * inputRes = dynamic_cast < RimInputCase *> ( m_currentReservoir );
if ( inputRes )
{
RimInputProperty * inputProperty = NULL ;
inputProperty = inputRes -> m_inputPropertyCollection -> findInputProperty ( m_currentPropertyName );
if ( ! inputProperty )
{
inputProperty = new RimInputProperty ;
inputProperty -> resultName = m_currentPropertyName ;
inputProperty -> eclipseKeyword = "" ;
inputProperty -> fileName = "" ;
inputRes -> m_inputPropertyCollection -> inputProperties . push_back ( inputProperty );
RimUiTreeModelPdm * treeModel = RiuMainWindow :: instance () -> uiPdmModel ();
treeModel -> updateUiSubTree ( inputRes -> m_inputPropertyCollection ());
}
inputProperty -> resolvedState = RimInputProperty :: RESOLVED_NOT_SAVED ;
}
if ( m_currentScalarIndex != cvf :: UNDEFINED_SIZE_T &&
m_currentReservoir -> reservoirData () &&
m_currentReservoir -> reservoirData () -> results ( m_porosityModelEnum ) )
{
m_currentReservoir -> reservoirData () -> results ( m_porosityModelEnum ) -> recalculateMinMax ( m_currentScalarIndex );
}
for ( size_t i = 0 ; i < m_currentReservoir -> reservoirViews . size (); ++ i )
{
if ( m_currentReservoir -> reservoirViews [ i ])
{
2013-09-13 09:23:13 +02:00
// As new result might have been introduced, update all editors connected
m_currentReservoir -> reservoirViews [ i ] -> cellResult -> updateConnectedEditors ();
// It is usually not needed to create new display model, but if any derived geometry based on generated data (from Octave)
// a full display model rebuild is required
m_currentReservoir -> reservoirViews [ i ] -> scheduleCreateDisplayModelAndRedraw ();
2013-05-24 12:02:52 +02:00
}
}
}
return true ;
}
return false ;
}
private :
RimCase * m_currentReservoir ;
std :: vector < std :: vector < double > >* m_scalarResultsToAdd ;
size_t m_currentScalarIndex ;
QString m_currentPropertyName ;
std :: vector < size_t > m_requestedTimesteps ;
RifReaderInterface :: PorosityModelResultType m_porosityModelEnum ;
quint64 m_timeStepCountToRead ;
quint64 m_bytesPerTimeStepToRead ;
2013-05-26 12:07:42 +02:00
size_t m_currentTimeStepNumberToRead ;
2013-05-24 12:02:52 +02:00
bool m_invalidActiveCellCountDetected ;
};
static bool RiaSetActiveCellProperty_init = RiaSocketCommandFactory :: instance () -> registerCreator < RiaSetActiveCellProperty > ( RiaSetActiveCellProperty :: commandName ());
2013-05-28 10:43:32 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaSetGridProperty : public RiaSocketCommand
{
public :
RiaSetGridProperty () :
m_currentReservoir ( NULL ),
m_scalarResultsToAdd ( NULL ),
m_currentGridIndex ( cvf :: UNDEFINED_SIZE_T ),
m_currentScalarIndex ( cvf :: UNDEFINED_SIZE_T ),
m_timeStepCountToRead ( 0 ),
m_bytesPerTimeStepToRead ( 0 ),
m_currentTimeStepNumberToRead ( 0 ),
m_invalidDataDetected ( false ),
m_porosityModelEnum ( RifReaderInterface :: MATRIX_RESULTS )
2013-05-28 11:11:32 +02:00
{}
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
static QString commandName () { return QString ( "SetGridProperty" ); }
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
virtual bool interpretCommand ( RiaSocketServer * server , const QList < QByteArray >& args , QDataStream & socketStream )
{
int caseId = args [ 1 ]. toInt ();
RimCase * rimCase = server -> findReservoir ( caseId );
if ( ! rimCase )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) + RiaSocketServer :: tr ( "Could not find the case with ID : \" %1 \" " ). arg ( caseId ));
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
return true ;
}
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
m_currentGridIndex = args [ 2 ]. toInt ();
QString propertyName = args [ 3 ];
QString porosityModelName = args [ 4 ];
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
if ( porosityModelName == "Fracture" )
{
m_porosityModelEnum = RifReaderInterface :: FRACTURE_RESULTS ;
}
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
RigGridBase * grid = rimCase -> reservoirData () -> grid ( m_currentGridIndex );
if ( ! grid )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) + RiaSocketServer :: tr ( "Could not find the grid index : %1" ). arg ( m_currentGridIndex ));
return true ;
}
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
// Read header
if ( server -> currentClient () -> bytesAvailable () < ( int ) sizeof ( quint64 ) * 5 ) return true ;
quint64 cellCountI = 0 ;
quint64 cellCountJ = 0 ;
quint64 cellCountK = 0 ;
socketStream >> cellCountI ;
socketStream >> cellCountJ ;
socketStream >> cellCountK ;
if ( grid -> cellCountI () != cellCountI ||
grid -> cellCountJ () != cellCountJ ||
grid -> cellCountK () != cellCountK )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) + RiaSocketServer :: tr ( "Destination grid size do not match incoming grid size for grid index : %1" ). arg ( m_currentGridIndex ));
return true ;
}
socketStream >> m_timeStepCountToRead ;
socketStream >> m_bytesPerTimeStepToRead ;
if ( m_timeStepCountToRead == 0 || m_bytesPerTimeStepToRead == 0 )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) +
RiaSocketServer :: tr ( "Zero data to read for " ) + ": \" " + m_currentReservoir -> caseUserDescription () + " \"\n " );
}
size_t scalarResultIndex = cvf :: UNDEFINED_SIZE_T ;
std :: vector < std :: vector < double > >* scalarResultFrames = NULL ;
if ( rimCase && rimCase -> results ( m_porosityModelEnum ))
{
scalarResultIndex = rimCase -> results ( m_porosityModelEnum ) -> findOrLoadScalarResult ( RimDefines :: GENERATED , propertyName );
if ( scalarResultIndex == cvf :: UNDEFINED_SIZE_T )
{
scalarResultIndex = rimCase -> results ( m_porosityModelEnum ) -> cellResults () -> addEmptyScalarResult ( RimDefines :: GENERATED , propertyName , true );
}
if ( scalarResultIndex != cvf :: UNDEFINED_SIZE_T )
{
scalarResultFrames = & ( rimCase -> results ( m_porosityModelEnum ) -> cellResults () -> cellScalarResults ( scalarResultIndex ));
m_currentScalarIndex = scalarResultIndex ;
m_currentPropertyName = propertyName ;
}
}
if ( scalarResultFrames == NULL )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) + RiaSocketServer :: tr ( "Could not find the %1 model property named: \" %2 \" " ). arg ( porosityModelName ). arg ( propertyName ));
return true ;
}
// Create a list of all the requested timesteps
m_requestedTimesteps . clear ();
if ( args . size () <= 5 )
{
// Select all
for ( size_t tsIdx = 0 ; tsIdx < m_timeStepCountToRead ; ++ tsIdx )
{
m_requestedTimesteps . push_back ( tsIdx );
}
}
else
{
bool timeStepReadError = false ;
for ( int argIdx = 5 ; argIdx < args . size (); ++ argIdx )
{
bool conversionOk = false ;
int tsIdx = args [ argIdx ]. toInt ( & conversionOk );
if ( conversionOk )
{
m_requestedTimesteps . push_back ( tsIdx );
}
else
{
timeStepReadError = true ;
}
}
if ( timeStepReadError )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: riGetActiveCellProperty : \n " ) + RiaSocketServer :: tr ( "An error occured while interpreting the requested timesteps." ));
}
}
if ( ! m_requestedTimesteps . size ())
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) + RiaSocketServer :: tr ( "No time steps specified" ). arg ( porosityModelName ). arg ( propertyName ));
return true ;
}
// Resize the result container to be able to receive time steps at the specified time step indices
std :: vector < size_t >:: iterator maxTimeStepIt = std :: max_element ( m_requestedTimesteps . begin (), m_requestedTimesteps . end ());
CVF_ASSERT ( maxTimeStepIt != m_requestedTimesteps . end ());
size_t maxTimeStepIdx = ( * maxTimeStepIt );
if ( scalarResultFrames -> size () <= maxTimeStepIdx )
{
scalarResultFrames -> resize ( maxTimeStepIdx + 1 );
}
m_currentReservoir = rimCase ;
m_scalarResultsToAdd = scalarResultFrames ;
if ( server -> currentClient () -> bytesAvailable ())
{
return this -> interpretMore ( server , server -> currentClient ());
}
return false ;
}
virtual bool interpretMore ( RiaSocketServer * server , QTcpSocket * currentClient )
{
if ( m_invalidDataDetected ) return true ;
if ( ! currentClient -> bytesAvailable ()) return false ;
QDataStream socketStream ( currentClient );
socketStream . setVersion ( riOctavePlugin :: qtDataStreamVersion );
RigGridBase * grid = m_currentReservoir -> reservoirData () -> grid ( m_currentGridIndex );
if ( ! grid )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) +
RiaSocketServer :: tr ( "No grid found" ) + ": \" " + m_currentReservoir -> caseUserDescription () + " \"\n " );
m_invalidDataDetected = true ;
currentClient -> abort ();
return true ;
}
// Do nothing if we have not enough data
if ( m_timeStepCountToRead == 0 || m_bytesPerTimeStepToRead == 0 )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) +
RiaSocketServer :: tr ( "Zero data to read for " ) + ": \" " + m_currentReservoir -> caseUserDescription () + " \"\n " );
m_invalidDataDetected = true ;
currentClient -> abort ();
return true ;
}
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
if ( m_timeStepCountToRead != m_requestedTimesteps . size ())
{
CVF_ASSERT ( false );
}
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
// If nothing should be read, or we already have read everything, do nothing
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
if (( m_timeStepCountToRead == 0 ) || ( m_currentTimeStepNumberToRead >= m_timeStepCountToRead ) ) return true ;
// Check if a complete timestep is available, return and whait for readyRead() if not
if ( currentClient -> bytesAvailable () < ( int ) m_bytesPerTimeStepToRead ) return false ;
size_t cellCountFromOctave = m_bytesPerTimeStepToRead / sizeof ( double );
2013-08-12 10:04:30 +02:00
if ( cellCountFromOctave != grid -> cellCount ())
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) +
RiaSocketServer :: tr ( "Mismatch between expected and received data. Expected : %1, Received : %2" ). arg ( grid -> cellCount ()). arg ( cellCountFromOctave ));
2013-05-28 11:11:32 +02:00
2013-08-12 10:04:30 +02:00
m_invalidDataDetected = true ;
currentClient -> abort ();
return true ;
}
2013-05-28 11:11:32 +02:00
for ( size_t tIdx = 0 ; tIdx < m_timeStepCountToRead ; ++ tIdx )
{
size_t tsId = m_requestedTimesteps [ tIdx ];
2013-08-12 10:04:30 +02:00
// Result data is stored in an array containing all cells for all grids
// The size of this array must match the test in RigCaseCellResultsData::isUsingGlobalActiveIndex(),
// as it is used to determine if we have data for active cells or all cells
// See RigCaseCellResultsData::isUsingGlobalActiveIndex()
size_t totalNumberOfCellsIncludingLgrCells = grid -> mainGrid () -> cells (). size ();
m_scalarResultsToAdd -> at ( tsId ). resize ( totalNumberOfCellsIncludingLgrCells , HUGE_VAL );
2013-05-28 11:11:32 +02:00
}
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
if (( currentClient -> bytesAvailable () >= ( int ) m_bytesPerTimeStepToRead ) && ( m_currentTimeStepNumberToRead < m_timeStepCountToRead ))
{
// Read a single time step with data
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
std :: vector < double > doubleValues ( cellCountFromOctave );
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
qint64 bytesRead = currentClient -> read (( char * )( doubleValues . data ()), m_bytesPerTimeStepToRead );
size_t doubleValueIndex = 0 ;
2013-05-28 10:43:32 +02:00
2013-09-09 14:33:37 +02:00
cvf :: ref < cvf :: StructGridScalarDataAccess > cellCenterDataAccessObject = m_currentReservoir -> reservoirData () -> dataAccessObject ( grid , m_porosityModelEnum , m_requestedTimesteps [ m_currentTimeStepNumberToRead ], m_currentScalarIndex );
2013-08-12 10:04:30 +02:00
if ( ! cellCenterDataAccessObject . isNull ())
2013-05-28 11:11:32 +02:00
{
2013-08-12 10:04:30 +02:00
for ( size_t cellIdx = 0 ; static_cast < size_t > ( cellIdx ) < cellCountFromOctave ; cellIdx ++ )
2013-05-28 11:11:32 +02:00
{
2013-08-12 10:04:30 +02:00
cellCenterDataAccessObject -> setCellScalar ( cellIdx , doubleValues [ cellIdx ]);
2013-05-28 11:11:32 +02:00
}
}
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
++ m_currentTimeStepNumberToRead ;
}
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
// If we have read all the data, refresh the views
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
if ( m_currentTimeStepNumberToRead == m_timeStepCountToRead )
{
if ( m_currentReservoir != NULL )
{
// Create a new input property if we have an input reservoir
RimInputCase * inputRes = dynamic_cast < RimInputCase *> ( m_currentReservoir );
if ( inputRes )
{
RimInputProperty * inputProperty = NULL ;
inputProperty = inputRes -> m_inputPropertyCollection -> findInputProperty ( m_currentPropertyName );
if ( ! inputProperty )
{
inputProperty = new RimInputProperty ;
inputProperty -> resultName = m_currentPropertyName ;
inputProperty -> eclipseKeyword = "" ;
inputProperty -> fileName = "" ;
inputRes -> m_inputPropertyCollection -> inputProperties . push_back ( inputProperty );
RimUiTreeModelPdm * treeModel = RiuMainWindow :: instance () -> uiPdmModel ();
treeModel -> updateUiSubTree ( inputRes -> m_inputPropertyCollection ());
}
inputProperty -> resolvedState = RimInputProperty :: RESOLVED_NOT_SAVED ;
}
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
if ( m_currentScalarIndex != cvf :: UNDEFINED_SIZE_T &&
m_currentReservoir -> reservoirData () &&
m_currentReservoir -> reservoirData () -> results ( m_porosityModelEnum ) )
{
m_currentReservoir -> reservoirData () -> results ( m_porosityModelEnum ) -> recalculateMinMax ( m_currentScalarIndex );
}
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
for ( size_t i = 0 ; i < m_currentReservoir -> reservoirViews . size (); ++ i )
{
if ( m_currentReservoir -> reservoirViews [ i ])
{
2013-09-12 08:11:56 +02:00
// As new result might have been introduced, update all editors connected
m_currentReservoir -> reservoirViews [ i ] -> cellResult -> updateConnectedEditors ();
// It is usually not needed to create new display model, but if any derived geometry based on generated data (from Octave)
// a full display model rebuild is required
m_currentReservoir -> reservoirViews [ i ] -> scheduleCreateDisplayModelAndRedraw ();
2013-05-28 11:11:32 +02:00
}
}
}
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
return true ;
}
2013-05-28 10:43:32 +02:00
2013-05-28 11:11:32 +02:00
return false ;
}
2013-05-28 10:43:32 +02:00
private :
RimCase * m_currentReservoir ;
std :: vector < std :: vector < double > >* m_scalarResultsToAdd ;
size_t m_currentGridIndex ;
size_t m_currentScalarIndex ;
QString m_currentPropertyName ;
std :: vector < size_t > m_requestedTimesteps ;
RifReaderInterface :: PorosityModelResultType m_porosityModelEnum ;
quint64 m_timeStepCountToRead ;
quint64 m_bytesPerTimeStepToRead ;
size_t m_currentTimeStepNumberToRead ;
bool m_invalidDataDetected ;
};
static bool RiaSetGridProperty_init = RiaSocketCommandFactory :: instance () -> registerCreator < RiaSetGridProperty > ( RiaSetGridProperty :: commandName ());
2013-08-30 15:26:35 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaGetPropertyNames : public RiaSocketCommand
{
public :
static QString commandName () { return QString ( "GetPropertyNames" ); }
virtual bool interpretCommand ( RiaSocketServer * server , const QList < QByteArray >& args , QDataStream & socketStream )
{
int caseId = args [ 1 ]. toInt ();
RimCase * rimCase = server -> findReservoir ( caseId );
if ( ! rimCase )
{
server -> errorMessageDialog () -> showMessage ( RiaSocketServer :: tr ( "ResInsight SocketServer: \n " ) + RiaSocketServer :: tr ( "Could not find the case with ID : \" %1 \" " ). arg ( caseId ));
return true ;
}
QString porosityModelName = args [ 2 ];
RifReaderInterface :: PorosityModelResultType porosityModelEnum = RifReaderInterface :: MATRIX_RESULTS ;
if ( porosityModelName == "Fracture" )
{
porosityModelEnum = RifReaderInterface :: FRACTURE_RESULTS ;
}
std :: vector < QString > propNames ;
std :: vector < QString > propTypes ;
RigCaseCellResultsData * results = rimCase -> reservoirData () -> results ( porosityModelEnum );
std :: vector < RimDefines :: ResultCatType > resTypes ;
std :: vector < QString > resTypeNames ;
resTypes . push_back ( RimDefines :: DYNAMIC_NATIVE );
resTypeNames . push_back ( "DynamicNative" );
resTypes . push_back ( RimDefines :: STATIC_NATIVE );
resTypeNames . push_back ( "StaticNative" );
resTypes . push_back ( RimDefines :: GENERATED );
resTypeNames . push_back ( "Generated" );
resTypes . push_back ( RimDefines :: INPUT_PROPERTY );
resTypeNames . push_back ( "Input" );
for ( size_t rtIdx = 0 ; rtIdx < resTypes . size (); ++ rtIdx )
{
RimDefines :: ResultCatType resType = resTypes [ rtIdx ];
QStringList names = results -> resultNames ( resType );
for ( int pnIdx = 0 ; pnIdx < names . size (); ++ pnIdx ){
propNames . push_back ( names [ pnIdx ]);
propTypes . push_back ( resTypeNames [ rtIdx ]);
}
}
quint64 byteCount = sizeof ( quint64 );
quint64 propCount = propNames . size ();
for ( size_t rtIdx = 0 ; rtIdx < propCount ; rtIdx ++ )
{
byteCount += propNames [ rtIdx ]. size () * sizeof ( QChar );
byteCount += propTypes [ rtIdx ]. size () * sizeof ( QChar );
}
socketStream << byteCount ;
socketStream << propCount ;
for ( size_t rtIdx = 0 ; rtIdx < propCount ; rtIdx ++ )
{
socketStream << propNames [ rtIdx ];
socketStream << propTypes [ rtIdx ];
}
return true ;
}
};
static bool RiaGetPropertyNames_init = RiaSocketCommandFactory :: instance () -> registerCreator < RiaGetPropertyNames > ( RiaGetPropertyNames :: commandName ());