mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Rename ApplicationCode to ApplicationLibCode
This commit is contained in:
671
ApplicationLibCode/SocketInterface/RiaCaseInfoCommands.cpp
Normal file
671
ApplicationLibCode/SocketInterface/RiaCaseInfoCommands.cpp
Normal file
@@ -0,0 +1,671 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011- Statoil ASA
|
||||
// Copyright (C) 2013- Ceetron Solutions AS
|
||||
// Copyright (C) 2011-2012 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 "RiaSocketCommand.h"
|
||||
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaSocketServer.h"
|
||||
#include "RiaSocketTools.h"
|
||||
|
||||
#include "RigActiveCellInfo.h"
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigFemPart.h"
|
||||
#include "RigFemPartCollection.h"
|
||||
#include "RigFemPartGrid.h"
|
||||
#include "RigGeoMechCaseData.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
#include "Rim3dOverlayInfoConfig.h"
|
||||
#include "RimCellEdgeColors.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseCellColors.h"
|
||||
#include "RimEclipsePropertyFilterCollection.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimGeoMechCase.h"
|
||||
#include "RimGeoMechView.h"
|
||||
#include "RimReservoirCellResultsStorage.h"
|
||||
#include "RimSimWellInViewCollection.h"
|
||||
|
||||
#include "Riu3dSelectionManager.h"
|
||||
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include "RimGeoMechResultDefinition.h"
|
||||
#include <array>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// OBSOLETE, to be deleted
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetMainGridDimensions : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetMainGridDimensions" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args );
|
||||
if ( !rimCase ) return true;
|
||||
|
||||
// Write data back to octave: I, J, K dimensions
|
||||
|
||||
size_t iCount = 0;
|
||||
size_t jCount = 0;
|
||||
size_t kCount = 0;
|
||||
|
||||
if ( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() )
|
||||
{
|
||||
iCount = rimCase->eclipseCaseData()->mainGrid()->cellCountI();
|
||||
jCount = rimCase->eclipseCaseData()->mainGrid()->cellCountJ();
|
||||
kCount = rimCase->eclipseCaseData()->mainGrid()->cellCountK();
|
||||
}
|
||||
|
||||
socketStream << (quint64)iCount << (quint64)jCount << (quint64)kCount;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetMainGridDimensions_init = RiaSocketCommandFactory::instance()->registerCreator<RiaGetMainGridDimensions>(
|
||||
RiaGetMainGridDimensions::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetActiveCellInfo : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetActiveCellInfo" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args );
|
||||
if ( !rimCase ) return true;
|
||||
|
||||
RiaDefines::PorosityModelType porosityModel = RiaDefines::PorosityModelType::MATRIX_MODEL;
|
||||
|
||||
if ( args.size() > 2 )
|
||||
{
|
||||
QString prorosityModelString = args[2];
|
||||
if ( prorosityModelString.toUpper() == "FRACTURE" )
|
||||
{
|
||||
porosityModel = RiaDefines::PorosityModelType::FRACTURE_MODEL;
|
||||
}
|
||||
}
|
||||
|
||||
// Write data back to octave: columnCount, bytesPrTimestep, GridNr I J K ParentGridNr PI PJ PK CoarseBoxIdx
|
||||
|
||||
std::array<std::vector<qint32>, 9> activeCellInfo;
|
||||
if ( !( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() ) )
|
||||
{
|
||||
// No data available
|
||||
socketStream << (quint64)0 << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
calculateMatrixModelActiveCellInfo( rimCase,
|
||||
porosityModel,
|
||||
activeCellInfo[0],
|
||||
activeCellInfo[1],
|
||||
activeCellInfo[2],
|
||||
activeCellInfo[3],
|
||||
activeCellInfo[4],
|
||||
activeCellInfo[5],
|
||||
activeCellInfo[6],
|
||||
activeCellInfo[7],
|
||||
activeCellInfo[8] );
|
||||
|
||||
// First write column count
|
||||
quint64 columnCount = (quint64)9;
|
||||
socketStream << columnCount;
|
||||
|
||||
// then the byte-size of the size of one column
|
||||
size_t timestepResultCount = activeCellInfo[0].size();
|
||||
quint64 timestepByteCount = ( quint64 )( timestepResultCount * sizeof( qint32 ) );
|
||||
socketStream << timestepByteCount;
|
||||
|
||||
for ( size_t tIdx = 0; tIdx < columnCount; ++tIdx )
|
||||
{
|
||||
RiaSocketTools::writeBlockData( server,
|
||||
server->currentClient(),
|
||||
(const char*)activeCellInfo[tIdx].data(),
|
||||
timestepByteCount );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void calculateMatrixModelActiveCellInfo( RimEclipseCase* reservoirCase,
|
||||
RiaDefines::PorosityModelType porosityModel,
|
||||
std::vector<qint32>& gridNumber,
|
||||
std::vector<qint32>& cellI,
|
||||
std::vector<qint32>& cellJ,
|
||||
std::vector<qint32>& cellK,
|
||||
std::vector<qint32>& parentGridNumber,
|
||||
std::vector<qint32>& hostCellI,
|
||||
std::vector<qint32>& hostCellJ,
|
||||
std::vector<qint32>& hostCellK,
|
||||
std::vector<qint32>& globalCoarseningBoxIdx )
|
||||
{
|
||||
gridNumber.clear();
|
||||
cellI.clear();
|
||||
cellJ.clear();
|
||||
cellK.clear();
|
||||
parentGridNumber.clear();
|
||||
hostCellI.clear();
|
||||
hostCellJ.clear();
|
||||
hostCellK.clear();
|
||||
globalCoarseningBoxIdx.clear();
|
||||
|
||||
if ( !reservoirCase || !reservoirCase->eclipseCaseData() || !reservoirCase->eclipseCaseData()->mainGrid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RigActiveCellInfo* actCellInfo = reservoirCase->eclipseCaseData()->activeCellInfo( porosityModel );
|
||||
size_t numMatrixModelActiveCells = actCellInfo->reservoirActiveCellCount();
|
||||
|
||||
gridNumber.reserve( numMatrixModelActiveCells );
|
||||
cellI.reserve( numMatrixModelActiveCells );
|
||||
cellJ.reserve( numMatrixModelActiveCells );
|
||||
cellK.reserve( numMatrixModelActiveCells );
|
||||
parentGridNumber.reserve( numMatrixModelActiveCells );
|
||||
hostCellI.reserve( numMatrixModelActiveCells );
|
||||
hostCellJ.reserve( numMatrixModelActiveCells );
|
||||
hostCellK.reserve( numMatrixModelActiveCells );
|
||||
globalCoarseningBoxIdx.reserve( numMatrixModelActiveCells );
|
||||
|
||||
const std::vector<RigCell>& reservoirCells = reservoirCase->eclipseCaseData()->mainGrid()->globalCellArray();
|
||||
|
||||
std::vector<size_t> globalCoarseningBoxIndexStart;
|
||||
{
|
||||
size_t globalCoarseningBoxCount = 0;
|
||||
|
||||
for ( size_t gridIdx = 0; gridIdx < reservoirCase->eclipseCaseData()->gridCount(); gridIdx++ )
|
||||
{
|
||||
globalCoarseningBoxIndexStart.push_back( globalCoarseningBoxCount );
|
||||
|
||||
RigGridBase* grid = reservoirCase->eclipseCaseData()->grid( gridIdx );
|
||||
|
||||
size_t localCoarseningBoxCount = grid->coarseningBoxCount();
|
||||
globalCoarseningBoxCount += localCoarseningBoxCount;
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t cIdx = 0; cIdx < reservoirCells.size(); ++cIdx )
|
||||
{
|
||||
if ( actCellInfo->isActive( cIdx ) )
|
||||
{
|
||||
RigGridBase* grid = reservoirCells[cIdx].hostGrid();
|
||||
CVF_ASSERT( grid != nullptr );
|
||||
size_t cellIndex = reservoirCells[cIdx].gridLocalCellIndex();
|
||||
|
||||
size_t i, j, k;
|
||||
grid->ijkFromCellIndex( cellIndex, &i, &j, &k );
|
||||
|
||||
size_t pi, pj, pk;
|
||||
RigGridBase* parentGrid = nullptr;
|
||||
|
||||
if ( grid->isMainGrid() )
|
||||
{
|
||||
pi = i;
|
||||
pj = j;
|
||||
pk = k;
|
||||
parentGrid = grid;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t parentCellIdx = reservoirCells[cIdx].parentCellIndex();
|
||||
parentGrid = ( static_cast<RigLocalGrid*>( grid ) )->parentGrid();
|
||||
CVF_ASSERT( parentGrid != nullptr );
|
||||
parentGrid->ijkFromCellIndex( parentCellIdx, &pi, &pj, &pk );
|
||||
}
|
||||
|
||||
gridNumber.push_back( static_cast<qint32>( grid->gridIndex() ) );
|
||||
cellI.push_back( static_cast<qint32>( i + 1 ) ); // NB: 1-based index in Octave
|
||||
cellJ.push_back( static_cast<qint32>( j + 1 ) ); // NB: 1-based index in Octave
|
||||
cellK.push_back( static_cast<qint32>( k + 1 ) ); // NB: 1-based index in Octave
|
||||
|
||||
parentGridNumber.push_back( static_cast<qint32>( parentGrid->gridIndex() ) );
|
||||
hostCellI.push_back( static_cast<qint32>( pi + 1 ) ); // NB: 1-based index in Octave
|
||||
hostCellJ.push_back( static_cast<qint32>( pj + 1 ) ); // NB: 1-based index in Octave
|
||||
hostCellK.push_back( static_cast<qint32>( pk + 1 ) ); // NB: 1-based index in Octave
|
||||
|
||||
size_t coarseningIdx = reservoirCells[cIdx].coarseningBoxIndex();
|
||||
if ( coarseningIdx != cvf::UNDEFINED_SIZE_T )
|
||||
{
|
||||
size_t globalCoarseningIdx = globalCoarseningBoxIndexStart[grid->gridIndex()] + coarseningIdx;
|
||||
|
||||
globalCoarseningBoxIdx.push_back( static_cast<qint32>( globalCoarseningIdx + 1 ) ); // NB: 1-based
|
||||
// index in Octave
|
||||
}
|
||||
else
|
||||
{
|
||||
globalCoarseningBoxIdx.push_back( -1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetActiveCellInfo_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetActiveCellInfo>( RiaGetActiveCellInfo::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetCoarseningInfo : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetCoarseningInfo" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
int argCaseGroupId = -1;
|
||||
|
||||
if ( args.size() == 2 )
|
||||
{
|
||||
argCaseGroupId = args[1].toInt();
|
||||
}
|
||||
|
||||
RimEclipseCase* rimCase = server->findReservoir( argCaseGroupId );
|
||||
if ( !rimCase || !rimCase->eclipseCaseData() || !rimCase->eclipseCaseData()->mainGrid() )
|
||||
{
|
||||
quint64 byteCount = 0;
|
||||
|
||||
socketStream << byteCount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Write data back to octave: I1, I2, J1, J2, K1, K2 for all coarsening boxes
|
||||
|
||||
if ( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() )
|
||||
{
|
||||
size_t globalCoarseningBoxCount = 0;
|
||||
|
||||
for ( size_t gridIdx = 0; gridIdx < rimCase->eclipseCaseData()->gridCount(); gridIdx++ )
|
||||
{
|
||||
RigGridBase* grid = rimCase->eclipseCaseData()->grid( gridIdx );
|
||||
|
||||
size_t localCoarseningBoxCount = grid->coarseningBoxCount();
|
||||
globalCoarseningBoxCount += localCoarseningBoxCount;
|
||||
}
|
||||
|
||||
quint64 byteCount = globalCoarseningBoxCount * 6 * sizeof( qint32 );
|
||||
socketStream << byteCount;
|
||||
|
||||
for ( size_t gridIdx = 0; gridIdx < rimCase->eclipseCaseData()->gridCount(); gridIdx++ )
|
||||
{
|
||||
RigGridBase* grid = rimCase->eclipseCaseData()->grid( gridIdx );
|
||||
|
||||
size_t localCoarseningBoxCount = grid->coarseningBoxCount();
|
||||
for ( size_t boxIdx = 0; boxIdx < localCoarseningBoxCount; boxIdx++ )
|
||||
{
|
||||
size_t i1, i2, j1, j2, k1, k2;
|
||||
grid->coarseningBox( boxIdx, &i1, &i2, &j1, &j2, &k1, &k2 );
|
||||
|
||||
// Write 1-based coordinates for coarsening box
|
||||
socketStream << static_cast<qint32>( i1 + 1 );
|
||||
socketStream << static_cast<qint32>( i2 + 1 );
|
||||
socketStream << static_cast<qint32>( j1 + 1 );
|
||||
socketStream << static_cast<qint32>( j2 + 1 );
|
||||
socketStream << static_cast<qint32>( k1 + 1 );
|
||||
socketStream << static_cast<qint32>( k2 + 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetCoarseningInfo_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetCoarseningInfo>( RiaGetCoarseningInfo::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetGridDimensions : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetGridDimensions" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
int argCaseGroupId = -1;
|
||||
|
||||
if ( args.size() == 2 )
|
||||
{
|
||||
argCaseGroupId = args[1].toInt();
|
||||
}
|
||||
|
||||
RimEclipseCase* rimCase = server->findReservoir( argCaseGroupId );
|
||||
if ( !rimCase || !rimCase->eclipseCaseData() || !rimCase->eclipseCaseData()->mainGrid() )
|
||||
{
|
||||
quint64 byteCount = 0;
|
||||
|
||||
socketStream << byteCount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Write data back to octave: I, J, K dimensions
|
||||
|
||||
if ( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() )
|
||||
{
|
||||
std::vector<RigGridBase*> grids;
|
||||
rimCase->eclipseCaseData()->allGrids( &grids );
|
||||
|
||||
quint64 byteCount = grids.size() * 3 * sizeof( quint64 );
|
||||
socketStream << byteCount;
|
||||
|
||||
for ( size_t i = 0; i < grids.size(); i++ )
|
||||
{
|
||||
size_t iCount = 0;
|
||||
size_t jCount = 0;
|
||||
size_t kCount = 0;
|
||||
|
||||
iCount = grids[i]->cellCountI();
|
||||
jCount = grids[i]->cellCountJ();
|
||||
kCount = grids[i]->cellCountK();
|
||||
|
||||
socketStream << (quint64)iCount << (quint64)jCount << (quint64)kCount;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetGridDimensions_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetGridDimensions>( RiaGetGridDimensions::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetTimeStepDates : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetTimeStepDates" ); }
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
int argCaseGroupId = -1;
|
||||
|
||||
if ( args.size() == 2 )
|
||||
{
|
||||
argCaseGroupId = args[1].toInt();
|
||||
}
|
||||
|
||||
RimEclipseCase* rimCase = server->findReservoir( argCaseGroupId );
|
||||
|
||||
bool canFetchData = true;
|
||||
|
||||
if ( !rimCase || !rimCase->eclipseCaseData() )
|
||||
{
|
||||
canFetchData = false;
|
||||
}
|
||||
|
||||
RigEclipseResultAddress addrToMaxTimeStepCountResult;
|
||||
if ( rimCase && rimCase->eclipseCaseData() )
|
||||
{
|
||||
rimCase->eclipseCaseData()
|
||||
->results( RiaDefines::PorosityModelType::MATRIX_MODEL )
|
||||
->maxTimeStepCount( &addrToMaxTimeStepCountResult );
|
||||
if ( !addrToMaxTimeStepCountResult.isValid() )
|
||||
{
|
||||
canFetchData = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Did not find any result to fetch data from, return zero data found
|
||||
if ( !canFetchData )
|
||||
{
|
||||
quint64 timeStepCount = 0;
|
||||
quint64 byteCount = sizeof( quint64 );
|
||||
|
||||
socketStream << byteCount;
|
||||
socketStream << timeStepCount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<QDateTime> timeStepDates =
|
||||
rimCase->eclipseCaseData()
|
||||
->results( RiaDefines::PorosityModelType::MATRIX_MODEL )
|
||||
->timeStepDates( RigEclipseResultAddress( addrToMaxTimeStepCountResult ) );
|
||||
|
||||
quint64 timeStepCount = timeStepDates.size();
|
||||
quint64 byteCount = sizeof( quint64 ) + 6 * timeStepCount * sizeof( qint32 );
|
||||
|
||||
socketStream << byteCount;
|
||||
socketStream << timeStepCount;
|
||||
|
||||
for ( size_t i = 0; i < timeStepCount; i++ )
|
||||
{
|
||||
qint32 intValue = 0;
|
||||
|
||||
intValue = timeStepDates[i].date().year();
|
||||
socketStream << intValue;
|
||||
|
||||
intValue = timeStepDates[i].date().month();
|
||||
socketStream << intValue;
|
||||
|
||||
intValue = timeStepDates[i].date().day();
|
||||
socketStream << intValue;
|
||||
|
||||
intValue = timeStepDates[i].time().hour();
|
||||
socketStream << intValue;
|
||||
|
||||
intValue = timeStepDates[i].time().minute();
|
||||
socketStream << intValue;
|
||||
|
||||
intValue = timeStepDates[i].time().second();
|
||||
socketStream << intValue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetTimeStepDates_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetTimeStepDates>( RiaGetTimeStepDates::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetTimeStepDays : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetTimeStepDays" ); }
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
int argCaseGroupId = -1;
|
||||
|
||||
if ( args.size() == 2 )
|
||||
{
|
||||
argCaseGroupId = args[1].toInt();
|
||||
}
|
||||
|
||||
RimEclipseCase* rimCase = server->findReservoir( argCaseGroupId );
|
||||
|
||||
bool canFetchData = true;
|
||||
|
||||
if ( !rimCase || !rimCase->eclipseCaseData() )
|
||||
{
|
||||
canFetchData = false;
|
||||
}
|
||||
|
||||
RigEclipseResultAddress addrToMaxTimeStepCountResult;
|
||||
if ( rimCase && rimCase->eclipseCaseData() )
|
||||
{
|
||||
rimCase->eclipseCaseData()
|
||||
->results( RiaDefines::PorosityModelType::MATRIX_MODEL )
|
||||
->maxTimeStepCount( &addrToMaxTimeStepCountResult );
|
||||
if ( !addrToMaxTimeStepCountResult.isValid() )
|
||||
{
|
||||
canFetchData = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Did not find any result to fetch data from, return zero data found
|
||||
if ( !canFetchData )
|
||||
{
|
||||
quint64 timeStepCount = 0;
|
||||
quint64 byteCount = sizeof( quint64 );
|
||||
|
||||
socketStream << byteCount;
|
||||
socketStream << timeStepCount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<double> daysSinceSimulationStart = rimCase->eclipseCaseData()
|
||||
->results( RiaDefines::PorosityModelType::MATRIX_MODEL )
|
||||
->daysSinceSimulationStart( addrToMaxTimeStepCountResult );
|
||||
|
||||
quint64 timeStepCount = daysSinceSimulationStart.size();
|
||||
quint64 byteCount = sizeof( quint64 ) + timeStepCount * sizeof( qint32 );
|
||||
|
||||
socketStream << byteCount;
|
||||
socketStream << timeStepCount;
|
||||
|
||||
for ( double day : daysSinceSimulationStart )
|
||||
{
|
||||
socketStream << day;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetTimeStepDays_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetTimeStepDays>( RiaGetTimeStepDays::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetSelectedCells : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetSelectedCells" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
// findCaseFromArgs only returns RimEclipseCase, so geomech cases are not supported because of this.
|
||||
// The rest of the function supports geomech cases, so using a findCaseFromArgs that supports geomech
|
||||
// cases is the only change needed to add geomech support.
|
||||
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args );
|
||||
if ( !rimCase ) return true;
|
||||
|
||||
// Write data back to octave: column count, bytes per column, caseId, gridNumber, cellI, cellJ, cellK
|
||||
|
||||
std::array<std::vector<qint32>, 5> selectedCellInfo;
|
||||
getSelectedCells( rimCase,
|
||||
selectedCellInfo[0],
|
||||
selectedCellInfo[1],
|
||||
selectedCellInfo[2],
|
||||
selectedCellInfo[3],
|
||||
selectedCellInfo[4] );
|
||||
|
||||
// First write column count
|
||||
quint64 columnCount = 5;
|
||||
socketStream << columnCount;
|
||||
|
||||
// then the byte-size of the size of one column
|
||||
quint64 columnByteCount = ( quint64 )( selectedCellInfo[0].size() * sizeof( qint32 ) );
|
||||
socketStream << columnByteCount;
|
||||
|
||||
// Write back table data
|
||||
for ( size_t tIdx = 0; tIdx < columnCount; ++tIdx )
|
||||
{
|
||||
RiaSocketTools::writeBlockData( server,
|
||||
server->currentClient(),
|
||||
(const char*)selectedCellInfo[tIdx].data(),
|
||||
columnByteCount );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void getSelectedCells( const RimCase* reservoirCase,
|
||||
std::vector<qint32>& caseNumber,
|
||||
std::vector<qint32>& gridNumber,
|
||||
std::vector<qint32>& cellI,
|
||||
std::vector<qint32>& cellJ,
|
||||
std::vector<qint32>& cellK )
|
||||
{
|
||||
std::vector<RiuSelectionItem*> items;
|
||||
Riu3dSelectionManager::instance()->selectedItems( items );
|
||||
|
||||
for ( const RiuSelectionItem* item : items )
|
||||
{
|
||||
size_t i, j, k;
|
||||
size_t gridIndex;
|
||||
int caseId;
|
||||
bool validIndex = true;
|
||||
|
||||
if ( item->type() == RiuSelectionItem::ECLIPSE_SELECTION_OBJECT )
|
||||
{
|
||||
const RiuEclipseSelectionItem* eclipseItem = static_cast<const RiuEclipseSelectionItem*>( item );
|
||||
|
||||
eclipseItem->m_resultDefinition->eclipseCase()
|
||||
->eclipseCaseData()
|
||||
->grid( eclipseItem->m_gridIndex )
|
||||
->ijkFromCellIndex( eclipseItem->m_gridLocalCellIndex, &i, &j, &k );
|
||||
|
||||
gridIndex = eclipseItem->m_gridIndex;
|
||||
caseId = eclipseItem->m_resultDefinition->eclipseCase()->caseId;
|
||||
}
|
||||
else if ( item->type() == RiuSelectionItem::GEOMECH_SELECTION_OBJECT )
|
||||
{
|
||||
const RiuGeoMechSelectionItem* geomechItem = static_cast<const RiuGeoMechSelectionItem*>( item );
|
||||
|
||||
validIndex = geomechItem->m_resultDefinition->ownerCaseData()
|
||||
->femParts()
|
||||
->part( geomechItem->m_gridIndex )
|
||||
->getOrCreateStructGrid()
|
||||
->ijkFromCellIndex( geomechItem->m_cellIndex, &i, &j, &k );
|
||||
|
||||
CVF_ASSERT( validIndex );
|
||||
|
||||
gridIndex = geomechItem->m_gridIndex;
|
||||
caseId = geomechItem->m_resultDefinition->geoMechCase()->caseId;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( caseId == reservoirCase->caseId && validIndex )
|
||||
{
|
||||
caseNumber.push_back( static_cast<int>( caseId ) );
|
||||
gridNumber.push_back( static_cast<int>( gridIndex ) );
|
||||
cellI.push_back( static_cast<int>( i + 1 ) );
|
||||
cellJ.push_back( static_cast<int>( j + 1 ) );
|
||||
cellK.push_back( static_cast<int>( k + 1 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetSelectedCells_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetSelectedCells>( RiaGetSelectedCells::commandName() );
|
||||
411
ApplicationLibCode/SocketInterface/RiaGeometryCommands.cpp
Normal file
411
ApplicationLibCode/SocketInterface/RiaGeometryCommands.cpp
Normal file
@@ -0,0 +1,411 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011- Statoil ASA
|
||||
// Copyright (C) 2013- Ceetron Solutions AS
|
||||
// Copyright (C) 2011-2012 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 "RiaSocketCommand.h"
|
||||
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaSocketServer.h"
|
||||
#include "RiaSocketTools.h"
|
||||
|
||||
#include "RigActiveCellInfo.h"
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
#include "Rim3dOverlayInfoConfig.h"
|
||||
#include "RimCellEdgeColors.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseCellColors.h"
|
||||
#include "RimEclipsePropertyFilterCollection.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimReservoirCellResultsStorage.h"
|
||||
#include "RimSimWellInViewCollection.h"
|
||||
|
||||
#include <QTcpSocket>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Convert internal ResInsight representation of cells with negative depth to positive depth.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static inline void convertVec3dToPositiveDepth( cvf::Vec3d* vec )
|
||||
{
|
||||
double& z = vec->z();
|
||||
z *= -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Retrieve a cell corner where the depth is represented as negative converted to positive depth.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static inline double getCellCornerWithPositiveDepth( const cvf::Vec3d* cornerVerts, size_t cornerIndexMapping, int coordIdx )
|
||||
{
|
||||
if ( coordIdx == 2 )
|
||||
{
|
||||
// Z-value aka depth
|
||||
return -1 * cornerVerts[cornerIndexMapping][coordIdx];
|
||||
}
|
||||
else
|
||||
{
|
||||
return cornerVerts[cornerIndexMapping][coordIdx];
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetCellCenters : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetCellCenters" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args );
|
||||
size_t argGridIndex = args[2].toUInt();
|
||||
|
||||
if ( !rimCase || !rimCase->eclipseCaseData() || ( argGridIndex >= rimCase->eclipseCaseData()->gridCount() ) )
|
||||
{
|
||||
// No data available
|
||||
socketStream << (quint64)0 << (quint64)0 << (quint64)0 << (quint64)0 << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
RigGridBase* rigGrid = rimCase->eclipseCaseData()->grid( argGridIndex );
|
||||
|
||||
quint64 cellCount = (quint64)rigGrid->cellCount();
|
||||
quint64 cellCountI = (quint64)rigGrid->cellCountI();
|
||||
quint64 cellCountJ = (quint64)rigGrid->cellCountJ();
|
||||
quint64 cellCountK = (quint64)rigGrid->cellCountK();
|
||||
|
||||
socketStream << cellCount;
|
||||
socketStream << cellCountI;
|
||||
socketStream << cellCountJ;
|
||||
socketStream << cellCountK;
|
||||
|
||||
size_t doubleValueCount = cellCount * 3;
|
||||
quint64 byteCount = doubleValueCount * sizeof( double );
|
||||
socketStream << byteCount;
|
||||
|
||||
// This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is
|
||||
// defined by the ordering of the receiving NDArray
|
||||
//
|
||||
// See riGetCellCenters
|
||||
//
|
||||
// dim_vector dv;
|
||||
// dv.resize(4);
|
||||
// dv(0) = cellCountI;
|
||||
// dv(1) = cellCountJ;
|
||||
// dv(2) = cellCountK;
|
||||
// dv(3) = 3;
|
||||
|
||||
size_t blockByteCount = cellCount * sizeof( double );
|
||||
std::vector<double> doubleValues( blockByteCount );
|
||||
|
||||
for ( int coordIdx = 0; coordIdx < 3; coordIdx++ )
|
||||
{
|
||||
quint64 valueIndex = 0;
|
||||
|
||||
for ( size_t k = 0; k < cellCountK; k++ )
|
||||
{
|
||||
for ( size_t j = 0; j < cellCountJ; j++ )
|
||||
{
|
||||
for ( size_t i = 0; i < cellCountI; i++ )
|
||||
{
|
||||
size_t gridLocalCellIndex = rigGrid->cellIndexFromIJK( i, j, k );
|
||||
cvf::Vec3d center = rigGrid->cell( gridLocalCellIndex ).center();
|
||||
|
||||
convertVec3dToPositiveDepth( ¢er );
|
||||
|
||||
doubleValues[valueIndex++] = center[coordIdx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CVF_ASSERT( valueIndex == cellCount );
|
||||
|
||||
RiaSocketTools::writeBlockData( server, server->currentClient(), (const char*)doubleValues.data(), blockByteCount );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetCellCenters_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetCellCenters>( RiaGetCellCenters::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetActiveCellCenters : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetActiveCellCenters" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args );
|
||||
|
||||
QString porosityModelName;
|
||||
porosityModelName = args[2];
|
||||
|
||||
RiaDefines::PorosityModelType porosityModelEnum = RiaDefines::PorosityModelType::MATRIX_MODEL;
|
||||
if ( porosityModelName.toUpper() == "FRACTURE" )
|
||||
{
|
||||
porosityModelEnum = RiaDefines::PorosityModelType::FRACTURE_MODEL;
|
||||
}
|
||||
|
||||
if ( !rimCase || !rimCase->eclipseCaseData() )
|
||||
{
|
||||
// No data available
|
||||
socketStream << (quint64)0 << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
RigActiveCellInfo* actCellInfo = rimCase->eclipseCaseData()->activeCellInfo( porosityModelEnum );
|
||||
RigMainGrid* mainGrid = rimCase->eclipseCaseData()->mainGrid();
|
||||
|
||||
size_t activeCellCount = actCellInfo->reservoirActiveCellCount();
|
||||
size_t doubleValueCount = activeCellCount * 3;
|
||||
|
||||
socketStream << (quint64)activeCellCount;
|
||||
quint64 byteCount = doubleValueCount * sizeof( double );
|
||||
socketStream << byteCount;
|
||||
|
||||
// This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is
|
||||
// defined by the ordering of the receiving NDArray
|
||||
//
|
||||
// See riGetActiveCellCenters
|
||||
//
|
||||
// dim_vector dv;
|
||||
// dv.resize(2);
|
||||
// dv(0) = coordCount;
|
||||
// dv(1) = 3;
|
||||
|
||||
size_t blockByteCount = activeCellCount * sizeof( double );
|
||||
std::vector<double> doubleValues( blockByteCount );
|
||||
|
||||
for ( int coordIdx = 0; coordIdx < 3; coordIdx++ )
|
||||
{
|
||||
quint64 valueIndex = 0;
|
||||
|
||||
for ( size_t reservoirCellIndex = 0; reservoirCellIndex < mainGrid->globalCellArray().size();
|
||||
reservoirCellIndex++ )
|
||||
{
|
||||
if ( !actCellInfo->isActive( reservoirCellIndex ) ) continue;
|
||||
|
||||
cvf::Vec3d center = mainGrid->globalCellArray()[reservoirCellIndex].center();
|
||||
|
||||
convertVec3dToPositiveDepth( ¢er );
|
||||
|
||||
doubleValues[valueIndex++] = center[coordIdx];
|
||||
}
|
||||
|
||||
CVF_ASSERT( valueIndex == activeCellCount );
|
||||
RiaSocketTools::writeBlockData( server, server->currentClient(), (const char*)doubleValues.data(), blockByteCount );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetActiveCellCenters_init = RiaSocketCommandFactory::instance()->registerCreator<RiaGetActiveCellCenters>(
|
||||
RiaGetActiveCellCenters::commandName() );
|
||||
|
||||
// NB: Match this mapping with the mapping in RifReaderEclipseOutput.cpp
|
||||
static const size_t cellCornerMappingEclipse[8] = { 0, 1, 3, 2, 4, 5, 7, 6 };
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetCellCorners : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetCellCorners" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args );
|
||||
size_t argGridIndex = args[2].toUInt();
|
||||
|
||||
if ( !rimCase || !rimCase->eclipseCaseData() || ( argGridIndex >= rimCase->eclipseCaseData()->gridCount() ) )
|
||||
{
|
||||
// No data available
|
||||
socketStream << (quint64)0 << (quint64)0 << (quint64)0 << (quint64)0 << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
RigGridBase* rigGrid = rimCase->eclipseCaseData()->grid( argGridIndex );
|
||||
|
||||
quint64 cellCount = (quint64)rigGrid->cellCount();
|
||||
quint64 cellCountI = (quint64)rigGrid->cellCountI();
|
||||
quint64 cellCountJ = (quint64)rigGrid->cellCountJ();
|
||||
quint64 cellCountK = (quint64)rigGrid->cellCountK();
|
||||
|
||||
size_t doubleValueCount = cellCount * 3 * 8;
|
||||
quint64 byteCount = doubleValueCount * sizeof( double );
|
||||
|
||||
socketStream << cellCount;
|
||||
socketStream << cellCountI;
|
||||
socketStream << cellCountJ;
|
||||
socketStream << cellCountK;
|
||||
socketStream << byteCount;
|
||||
|
||||
// This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is
|
||||
// defined by the ordering of the receiving NDArray
|
||||
//
|
||||
// See riGetCellCorners
|
||||
//
|
||||
// dim_vector dv;
|
||||
// dv.resize(5);
|
||||
// dv(0) = cellCountI;
|
||||
// dv(1) = cellCountJ;
|
||||
// dv(2) = cellCountK;
|
||||
// dv(3) = 8;
|
||||
// dv(4) = 3;
|
||||
|
||||
cvf::Vec3d cornerVerts[8];
|
||||
size_t blockByteCount = cellCount * sizeof( double );
|
||||
std::vector<double> doubleValues( blockByteCount );
|
||||
|
||||
for ( int coordIdx = 0; coordIdx < 3; coordIdx++ )
|
||||
{
|
||||
for ( size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++ )
|
||||
{
|
||||
size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx];
|
||||
|
||||
quint64 valueIndex = 0;
|
||||
|
||||
for ( size_t k = 0; k < cellCountK; k++ )
|
||||
{
|
||||
for ( size_t j = 0; j < cellCountJ; j++ )
|
||||
{
|
||||
for ( size_t i = 0; i < cellCountI; i++ )
|
||||
{
|
||||
size_t gridLocalCellIndex = rigGrid->cellIndexFromIJK( i, j, k );
|
||||
rigGrid->cellCornerVertices( gridLocalCellIndex, cornerVerts );
|
||||
|
||||
doubleValues[valueIndex++] =
|
||||
getCellCornerWithPositiveDepth( cornerVerts, cornerIndexMapping, coordIdx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CVF_ASSERT( valueIndex == cellCount );
|
||||
|
||||
RiaSocketTools::writeBlockData( server,
|
||||
server->currentClient(),
|
||||
(const char*)doubleValues.data(),
|
||||
blockByteCount );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetCellCorners_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetCellCorners>( RiaGetCellCorners::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetActiveCellCorners : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetActiveCellCorners" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args );
|
||||
|
||||
QString porosityModelName;
|
||||
porosityModelName = args[2];
|
||||
|
||||
RiaDefines::PorosityModelType porosityModelEnum = RiaDefines::PorosityModelType::MATRIX_MODEL;
|
||||
if ( porosityModelName.toUpper() == "FRACTURE" )
|
||||
{
|
||||
porosityModelEnum = RiaDefines::PorosityModelType::FRACTURE_MODEL;
|
||||
}
|
||||
|
||||
if ( !rimCase || !rimCase->eclipseCaseData() )
|
||||
{
|
||||
// No data available
|
||||
socketStream << (quint64)0 << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
RigActiveCellInfo* actCellInfo = rimCase->eclipseCaseData()->activeCellInfo( porosityModelEnum );
|
||||
RigMainGrid* mainGrid = rimCase->eclipseCaseData()->mainGrid();
|
||||
|
||||
size_t activeCellCount = actCellInfo->reservoirActiveCellCount();
|
||||
size_t doubleValueCount = activeCellCount * 3 * 8;
|
||||
|
||||
socketStream << (quint64)activeCellCount;
|
||||
quint64 byteCount = doubleValueCount * sizeof( double );
|
||||
socketStream << byteCount;
|
||||
|
||||
// This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is
|
||||
// defined by the ordering of the receiving NDArray
|
||||
//
|
||||
// See riGetCellCorners
|
||||
//
|
||||
// dim_vector dv;
|
||||
// dv.resize(3);
|
||||
// dv(0) = coordCount;
|
||||
// dv(1) = 8;
|
||||
// dv(2) = 3;
|
||||
|
||||
cvf::Vec3d cornerVerts[8];
|
||||
size_t blockByteCount = activeCellCount * sizeof( double );
|
||||
std::vector<double> doubleValues( blockByteCount );
|
||||
|
||||
for ( int coordIdx = 0; coordIdx < 3; coordIdx++ )
|
||||
{
|
||||
for ( size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++ )
|
||||
{
|
||||
size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx];
|
||||
|
||||
quint64 valueIndex = 0;
|
||||
|
||||
for ( size_t reservoirCellIndex = 0; reservoirCellIndex < mainGrid->globalCellArray().size();
|
||||
reservoirCellIndex++ )
|
||||
{
|
||||
if ( !actCellInfo->isActive( reservoirCellIndex ) ) continue;
|
||||
|
||||
mainGrid->cellCornerVertices( reservoirCellIndex, cornerVerts );
|
||||
|
||||
doubleValues[valueIndex++] =
|
||||
getCellCornerWithPositiveDepth( cornerVerts, cornerIndexMapping, coordIdx );
|
||||
}
|
||||
|
||||
CVF_ASSERT( valueIndex == activeCellCount );
|
||||
|
||||
RiaSocketTools::writeBlockData( server,
|
||||
server->currentClient(),
|
||||
(const char*)doubleValues.data(),
|
||||
blockByteCount );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetActiveCellCorners_init = RiaSocketCommandFactory::instance()->registerCreator<RiaGetActiveCellCorners>(
|
||||
RiaGetActiveCellCorners::commandName() );
|
||||
611
ApplicationLibCode/SocketInterface/RiaNNCCommands.cpp
Normal file
611
ApplicationLibCode/SocketInterface/RiaNNCCommands.cpp
Normal file
@@ -0,0 +1,611 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil ASA
|
||||
//
|
||||
// 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 "RiaSocketCommand.h"
|
||||
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaSocketDataTransfer.h"
|
||||
#include "RiaSocketServer.h"
|
||||
#include "RiaSocketTools.h"
|
||||
|
||||
#include "RigActiveCellInfo.h"
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
#include "Rim3dOverlayInfoConfig.h"
|
||||
#include "RimCellEdgeColors.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseCellColors.h"
|
||||
#include "RimEclipseInputCase.h"
|
||||
#include "RimEclipseInputProperty.h"
|
||||
#include "RimEclipseInputPropertyCollection.h"
|
||||
#include "RimEclipsePropertyFilterCollection.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimIntersectionCollection.h"
|
||||
#include "RimReservoirCellResultsStorage.h"
|
||||
#include "RimSimWellInViewCollection.h"
|
||||
|
||||
#include <QTcpSocket>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetNNCConnections : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetNNCConnections" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args );
|
||||
// Write data back to octave: columnCount, GridNr I J K GridNr I J K
|
||||
if ( !( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() ) )
|
||||
{
|
||||
// No data available
|
||||
socketStream << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
RigMainGrid* mainGrid = rimCase->eclipseCaseData()->mainGrid();
|
||||
|
||||
size_t connectionCount = mainGrid->nncData()->connections().size();
|
||||
|
||||
socketStream << (quint64)connectionCount;
|
||||
|
||||
for ( size_t i = 0; i < mainGrid->nncData()->connections().size(); ++i )
|
||||
{
|
||||
RigConnection connection = mainGrid->nncData()->connections()[i];
|
||||
|
||||
const RigCell& cell1 = mainGrid->globalCellArray()[connection.c1GlobIdx()];
|
||||
const RigCell& cell2 = mainGrid->globalCellArray()[connection.c2GlobIdx()];
|
||||
|
||||
sendCellInfo( socketStream, cell1 );
|
||||
sendCellInfo( socketStream, cell2 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void sendCellInfo( QDataStream& socketStream, const RigCell& cell )
|
||||
{
|
||||
RigGridBase* hostGrid = cell.hostGrid();
|
||||
size_t gridLocalCellIndex = cell.gridLocalCellIndex();
|
||||
size_t i, j, k;
|
||||
hostGrid->ijkFromCellIndex( gridLocalCellIndex, &i, &j, &k );
|
||||
|
||||
socketStream << (qint32)hostGrid->gridIndex();
|
||||
socketStream << ( qint32 )( i + 1 ) << ( qint32 )( j + 1 ) << ( qint32 )( k + 1 );
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetNNCConnections_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetNNCConnections>( RiaGetNNCConnections::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetDynamicNNCValues : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetDynamicNNCValues" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args );
|
||||
// Write data back to octave: connectionCount, timeStepCount, property values
|
||||
if ( !( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() ) )
|
||||
{
|
||||
// No data available
|
||||
socketStream << (quint64)0 << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
QString propertyName = args[2];
|
||||
|
||||
RigMainGrid* mainGrid = rimCase->eclipseCaseData()->mainGrid();
|
||||
const std::vector<std::vector<double>>* nncValues =
|
||||
mainGrid->nncData()->dynamicConnectionScalarResultByName( propertyName );
|
||||
|
||||
if ( nncValues == nullptr )
|
||||
{
|
||||
socketStream << (quint64)0 << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<size_t> requestedTimeSteps;
|
||||
if ( args.size() > 3 )
|
||||
{
|
||||
bool timeStepReadError = false;
|
||||
for ( int argIdx = 3; 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->showErrorMessage(
|
||||
RiaSocketServer::tr( "ResInsight SocketServer: riGetDynamicNNCValues : \n" ) +
|
||||
RiaSocketServer::tr( "An error occurred while interpreting the requested time steps." ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( size_t timeStep = 0; timeStep < nncValues->size(); ++timeStep )
|
||||
{
|
||||
requestedTimeSteps.push_back( timeStep );
|
||||
}
|
||||
}
|
||||
|
||||
// then the connection count and time step count.
|
||||
size_t connectionCount = mainGrid->nncData()->connections().size();
|
||||
size_t timeStepCount = requestedTimeSteps.size();
|
||||
|
||||
socketStream << (quint64)connectionCount;
|
||||
socketStream << (quint64)timeStepCount;
|
||||
|
||||
for ( size_t timeStep : requestedTimeSteps )
|
||||
{
|
||||
const std::vector<double>& timeStepValues = nncValues->at( timeStep );
|
||||
RiaSocketTools::writeBlockData( server,
|
||||
server->currentClient(),
|
||||
(const char*)timeStepValues.data(),
|
||||
sizeof( double ) * timeStepValues.size() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetDynamicNNCValues_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetDynamicNNCValues>( RiaGetDynamicNNCValues::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetStaticNNCValues : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetStaticNNCValues" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args );
|
||||
QString propertyName = args[2];
|
||||
|
||||
// Write data back to octave: connectionCount, property values
|
||||
if ( !( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() ) )
|
||||
{
|
||||
// No data available
|
||||
socketStream << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
RigMainGrid* mainGrid = rimCase->eclipseCaseData()->mainGrid();
|
||||
const std::vector<double>* nncValues = mainGrid->nncData()->staticConnectionScalarResultByName( propertyName );
|
||||
|
||||
if ( nncValues == nullptr )
|
||||
{
|
||||
socketStream << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// connection count
|
||||
size_t connectionCount = mainGrid->nncData()->connections().size();
|
||||
socketStream << (quint64)connectionCount;
|
||||
|
||||
RiaSocketTools::writeBlockData( server,
|
||||
server->currentClient(),
|
||||
(const char*)nncValues->data(),
|
||||
sizeof( double ) * nncValues->size() );
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetStaticNNCValues_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetStaticNNCValues>( RiaGetStaticNNCValues::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetNNCPropertyNames : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetNNCPropertyNames" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args );
|
||||
|
||||
if ( !( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() ) )
|
||||
{
|
||||
// No data available
|
||||
socketStream << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
RigNNCData* nncData = rimCase->eclipseCaseData()->mainGrid()->nncData();
|
||||
|
||||
std::vector<QString> propertyTypes;
|
||||
std::vector<QString> propertyNames;
|
||||
|
||||
std::vector<RigNNCData::NNCResultType> resultTypes;
|
||||
std::vector<QString> resultTypeNames;
|
||||
|
||||
resultTypes.push_back( RigNNCData::NNC_DYNAMIC );
|
||||
resultTypeNames.push_back( "DynamicNative" );
|
||||
resultTypes.push_back( RigNNCData::NNC_STATIC );
|
||||
resultTypeNames.push_back( "StaticNative" );
|
||||
resultTypes.push_back( RigNNCData::NNC_GENERATED );
|
||||
resultTypeNames.push_back( "Generated" );
|
||||
|
||||
for ( size_t rtIdx = 0; rtIdx < resultTypes.size(); ++rtIdx )
|
||||
{
|
||||
std::vector<QString> availableParameters = nncData->availableProperties( resultTypes[rtIdx] );
|
||||
|
||||
for ( const QString& parameter : availableParameters )
|
||||
{
|
||||
propertyNames.push_back( parameter );
|
||||
propertyTypes.push_back( resultTypeNames[rtIdx] );
|
||||
}
|
||||
}
|
||||
|
||||
qint64 byteCount = 0;
|
||||
|
||||
for ( size_t ptIdx = 0; ptIdx < propertyNames.size(); ++ptIdx )
|
||||
{
|
||||
byteCount += propertyNames[ptIdx].size() * sizeof( QChar );
|
||||
byteCount += propertyTypes[ptIdx].size() * sizeof( QChar );
|
||||
}
|
||||
|
||||
// Byte count
|
||||
socketStream << byteCount;
|
||||
|
||||
// Parameter count
|
||||
socketStream << (quint64)propertyNames.size();
|
||||
|
||||
for ( size_t ptIdx = 0; ptIdx < propertyNames.size(); ++ptIdx )
|
||||
{
|
||||
socketStream << propertyNames[ptIdx];
|
||||
socketStream << propertyTypes[ptIdx];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetNNCPropertyNames_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetNNCPropertyNames>( RiaGetNNCPropertyNames::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaSetNNCProperty : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
RiaSetNNCProperty()
|
||||
: m_currentReservoir( nullptr )
|
||||
, m_currentEclResultAddress()
|
||||
, m_timeStepCountToRead( 0 )
|
||||
, m_bytesPerTimeStepToRead( 0 )
|
||||
, m_currentTimeStepNumberToRead( 0 )
|
||||
, m_invalidConnectionCountDetected( false )
|
||||
, m_porosityModelEnum( RiaDefines::PorosityModelType::MATRIX_MODEL )
|
||||
{
|
||||
}
|
||||
|
||||
static QString commandName() { return QString( "SetNNCProperty" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args );
|
||||
|
||||
QString propertyName = args[2];
|
||||
|
||||
// Find the requested data, or create a set if we are setting data and it is not found
|
||||
if ( !( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() ) )
|
||||
{
|
||||
QString caseId = args[1];
|
||||
server->showErrorMessage( RiaSocketServer::tr( "ResInsight SocketServer: \n" ) +
|
||||
RiaSocketServer::tr( "Could not find case with id %1" ).arg( caseId ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
RigNNCData* nncData = rimCase->eclipseCaseData()->mainGrid()->nncData();
|
||||
|
||||
auto nncResults = nncData->generatedConnectionScalarResultByName( propertyName );
|
||||
|
||||
if ( nncResults == nullptr )
|
||||
{
|
||||
nncData->makeGeneratedConnectionScalarResult( propertyName, m_timeStepCountToRead );
|
||||
}
|
||||
|
||||
if ( rimCase && rimCase->results( m_porosityModelEnum ) )
|
||||
{
|
||||
bool ok = createIJKCellResults( rimCase->results( m_porosityModelEnum ), propertyName );
|
||||
if ( !ok )
|
||||
{
|
||||
server->showErrorMessage(
|
||||
RiaSocketServer::tr( "ResInsight SocketServer: \n" ) +
|
||||
RiaSocketServer::tr( "Could not find the property named: \"%2\"" ).arg( propertyName ) );
|
||||
return true;
|
||||
}
|
||||
RigEclipseResultAddress resAddr( QString( "%1IJK" ).arg( propertyName ) );
|
||||
rimCase->results( m_porosityModelEnum )->ensureKnownResultLoaded( resAddr );
|
||||
nncData->setEclResultAddress( propertyName, resAddr );
|
||||
}
|
||||
|
||||
// Create a list of all the requested time steps
|
||||
m_requestedTimesteps.clear();
|
||||
|
||||
if ( args.size() <= 4 )
|
||||
{
|
||||
// Select all
|
||||
for ( size_t tsIdx = 0; tsIdx < m_timeStepCountToRead; ++tsIdx )
|
||||
{
|
||||
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->showErrorMessage(
|
||||
RiaSocketServer::tr( "ResInsight SocketServer: riSetNNCProperty : \n" ) +
|
||||
RiaSocketServer::tr( "An error occurred while interpreting the requested time steps." ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !m_requestedTimesteps.size() )
|
||||
{
|
||||
server->showErrorMessage( RiaSocketServer::tr( "ResInsight SocketServer: \n" ) +
|
||||
RiaSocketServer::tr( "No time steps specified" ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
m_currentReservoir = rimCase;
|
||||
m_currentPropertyName = propertyName;
|
||||
|
||||
if ( server->currentClient()->bytesAvailable() )
|
||||
{
|
||||
return this->interpretMore( server, server->currentClient() );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
static bool createIJKCellResults( RigCaseCellResultsData* results, QString propertyName )
|
||||
{
|
||||
bool ok;
|
||||
ok = scalarResultExistsOrCreate( results, QString( "%1IJK" ).arg( propertyName ) );
|
||||
if ( !ok ) return false;
|
||||
ok = scalarResultExistsOrCreate( results, QString( "%1I" ).arg( propertyName ) );
|
||||
if ( !ok ) return false;
|
||||
ok = scalarResultExistsOrCreate( results, QString( "%1J" ).arg( propertyName ) );
|
||||
if ( !ok ) return false;
|
||||
ok = scalarResultExistsOrCreate( results, QString( "%1K" ).arg( propertyName ) );
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool scalarResultExistsOrCreate( RigCaseCellResultsData* results, QString propertyName )
|
||||
{
|
||||
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::GENERATED, propertyName );
|
||||
|
||||
if ( !results->ensureKnownResultLoaded( resAddr ) )
|
||||
{
|
||||
results->createResultEntry( resAddr, true );
|
||||
}
|
||||
|
||||
std::vector<std::vector<double>>* scalarResultFrames = results->modifiableCellScalarResultTimesteps( resAddr );
|
||||
size_t timeStepCount = results->maxTimeStepCount();
|
||||
scalarResultFrames->resize( timeStepCount );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
bool interpretMore( RiaSocketServer* server, QTcpSocket* currentClient ) override
|
||||
{
|
||||
if ( m_invalidConnectionCountDetected ) return true;
|
||||
|
||||
// If nothing should be read, or we already have read everything, do nothing
|
||||
if ( ( m_timeStepCountToRead == 0 ) || ( m_currentTimeStepNumberToRead >= m_timeStepCountToRead ) ) return true;
|
||||
|
||||
if ( !currentClient->bytesAvailable() ) return false;
|
||||
|
||||
if ( m_timeStepCountToRead != m_requestedTimesteps.size() )
|
||||
{
|
||||
CVF_ASSERT( false );
|
||||
}
|
||||
|
||||
// Check if a complete timestep is available, return and whait for readyRead() if not
|
||||
if ( currentClient->bytesAvailable() < (int)m_bytesPerTimeStepToRead ) return false;
|
||||
|
||||
RigNNCData* nncData = m_currentReservoir->eclipseCaseData()->mainGrid()->nncData();
|
||||
|
||||
size_t connectionCountFromOctave = m_bytesPerTimeStepToRead / sizeof( double );
|
||||
size_t connectionCount = nncData->connections().size();
|
||||
std::vector<std::vector<double>>* resultsToAdd =
|
||||
nncData->generatedConnectionScalarResultByName( m_currentPropertyName );
|
||||
|
||||
if ( connectionCountFromOctave != connectionCount )
|
||||
{
|
||||
server->showErrorMessage( RiaSocketServer::tr( "ResInsight SocketServer: \n" ) +
|
||||
RiaSocketServer::tr( "The number of connections in the data coming from octave "
|
||||
"does not match the case: '%1'\n" )
|
||||
.arg( m_currentReservoir->caseUserDescription() ) +
|
||||
RiaSocketServer::tr( " Octave: %1\n" ).arg( connectionCountFromOctave ) +
|
||||
RiaSocketServer::tr( " %1: Connection count: %2" )
|
||||
.arg( m_currentReservoir->caseUserDescription() )
|
||||
.arg( connectionCount ) );
|
||||
|
||||
connectionCountFromOctave = 0;
|
||||
m_invalidConnectionCountDetected = true;
|
||||
currentClient->abort();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
for ( size_t tIdx = 0; tIdx < m_timeStepCountToRead; ++tIdx )
|
||||
{
|
||||
size_t tsId = m_requestedTimesteps[tIdx];
|
||||
resultsToAdd->at( tsId ).resize( connectionCount, HUGE_VAL );
|
||||
}
|
||||
|
||||
double* internalMatrixData = nullptr;
|
||||
|
||||
QDataStream socketStream( currentClient );
|
||||
socketStream.setVersion( riOctavePlugin::qtDataStreamVersion );
|
||||
|
||||
// Read available complete time step data
|
||||
while ( ( currentClient->bytesAvailable() >= (int)m_bytesPerTimeStepToRead ) &&
|
||||
( m_currentTimeStepNumberToRead < m_timeStepCountToRead ) )
|
||||
{
|
||||
internalMatrixData = resultsToAdd->at( m_requestedTimesteps[m_currentTimeStepNumberToRead] ).data();
|
||||
|
||||
QStringList errorMessages;
|
||||
if ( !RiaSocketDataTransfer::readBlockDataFromSocket( currentClient,
|
||||
(char*)( internalMatrixData ),
|
||||
m_bytesPerTimeStepToRead,
|
||||
errorMessages ) )
|
||||
{
|
||||
for ( int i = 0; i < errorMessages.size(); i++ )
|
||||
{
|
||||
server->showErrorMessage( errorMessages[i] );
|
||||
}
|
||||
|
||||
currentClient->abort();
|
||||
return true;
|
||||
}
|
||||
++m_currentTimeStepNumberToRead;
|
||||
}
|
||||
|
||||
// If we have read all the data, refresh the views
|
||||
|
||||
if ( m_currentTimeStepNumberToRead == m_timeStepCountToRead )
|
||||
{
|
||||
if ( m_currentReservoir != nullptr )
|
||||
{
|
||||
// Create a new input property if we have an input reservoir
|
||||
RimEclipseInputCase* inputRes = dynamic_cast<RimEclipseInputCase*>( m_currentReservoir );
|
||||
if ( inputRes )
|
||||
{
|
||||
RimEclipseInputProperty* inputProperty =
|
||||
inputRes->inputPropertyCollection()->findInputProperty( m_currentPropertyName );
|
||||
if ( !inputProperty )
|
||||
{
|
||||
inputProperty = new RimEclipseInputProperty;
|
||||
inputProperty->resultName = m_currentPropertyName;
|
||||
inputProperty->eclipseKeyword = "";
|
||||
inputProperty->fileName = QString( "" );
|
||||
inputRes->inputPropertyCollection()->inputProperties.push_back( inputProperty );
|
||||
inputRes->inputPropertyCollection()->updateConnectedEditors();
|
||||
}
|
||||
inputProperty->resolvedState = RimEclipseInputProperty::RESOLVED_NOT_SAVED;
|
||||
}
|
||||
|
||||
if ( m_currentEclResultAddress.isValid() && // Will never be valid because it is never set. What is
|
||||
// correct behaviour ?
|
||||
m_currentReservoir->eclipseCaseData() &&
|
||||
m_currentReservoir->eclipseCaseData()->results( m_porosityModelEnum ) )
|
||||
{
|
||||
m_currentReservoir->eclipseCaseData()
|
||||
->results( m_porosityModelEnum )
|
||||
->recalculateStatistics( m_currentEclResultAddress );
|
||||
}
|
||||
|
||||
for ( size_t i = 0; i < m_currentReservoir->reservoirViews.size(); ++i )
|
||||
{
|
||||
if ( m_currentReservoir->reservoirViews[i] )
|
||||
{
|
||||
// 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();
|
||||
m_currentReservoir->reservoirViews[i]
|
||||
->intersectionCollection()
|
||||
->scheduleCreateDisplayModelAndRedraw2dIntersectionViews();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
RimEclipseCase* m_currentReservoir;
|
||||
RigEclipseResultAddress m_currentEclResultAddress;
|
||||
QString m_currentPropertyName;
|
||||
std::vector<size_t> m_requestedTimesteps;
|
||||
RiaDefines::PorosityModelType m_porosityModelEnum;
|
||||
|
||||
quint64 m_timeStepCountToRead;
|
||||
quint64 m_bytesPerTimeStepToRead;
|
||||
size_t m_currentTimeStepNumberToRead;
|
||||
|
||||
bool m_invalidConnectionCountDetected;
|
||||
};
|
||||
|
||||
static bool RiaSetNNCProperty_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaSetNNCProperty>( RiaSetNNCProperty::commandName() );
|
||||
305
ApplicationLibCode/SocketInterface/RiaProjectInfoCommands.cpp
Normal file
305
ApplicationLibCode/SocketInterface/RiaProjectInfoCommands.cpp
Normal file
@@ -0,0 +1,305 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011- Statoil ASA
|
||||
// Copyright (C) 2013- Ceetron Solutions AS
|
||||
// Copyright (C) 2011-2012 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 "RiaSocketCommand.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaSocketServer.h"
|
||||
#include "RiaSocketTools.h"
|
||||
|
||||
#include "Rim3dOverlayInfoConfig.h"
|
||||
#include "RimCaseCollection.h"
|
||||
#include "RimCellEdgeColors.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseCaseCollection.h"
|
||||
#include "RimEclipseCellColors.h"
|
||||
#include "RimEclipsePropertyFilterCollection.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimIdenticalGridCaseGroup.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimReservoirCellResultsStorage.h"
|
||||
#include "RimScriptCollection.h"
|
||||
#include "RimSimWellInViewCollection.h"
|
||||
|
||||
#include "RiuMainWindow.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void getCaseInfoFromCases( std::vector<RimCase*>& cases,
|
||||
std::vector<qint64>& caseIds,
|
||||
std::vector<QString>& caseNames,
|
||||
std::vector<QString>& caseTypes,
|
||||
std::vector<qint64>& caseGroupIds )
|
||||
{
|
||||
for ( size_t i = 0; i < cases.size(); i++ )
|
||||
{
|
||||
RimCase* rimCase = cases[i];
|
||||
|
||||
qint64 caseId = -1;
|
||||
QString caseName;
|
||||
QString caseType;
|
||||
qint64 caseGroupId = -1;
|
||||
RiaSocketTools::getCaseInfoFromCase( rimCase, caseId, caseName, caseType, caseGroupId );
|
||||
|
||||
caseIds.push_back( rimCase->caseId );
|
||||
caseNames.push_back( rimCase->caseUserDescription );
|
||||
caseTypes.push_back( caseType );
|
||||
caseGroupIds.push_back( caseGroupId );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetCurrentCase : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetCurrentCase" ); }
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
qint64 caseId = RiaApplication::instance()->currentScriptCaseId();
|
||||
QString caseName;
|
||||
QString caseType;
|
||||
qint64 caseGroupId = -1;
|
||||
|
||||
RimEclipseCase* rimCase = server->findReservoir( caseId );
|
||||
|
||||
if ( rimCase )
|
||||
{
|
||||
RiaSocketTools::getCaseInfoFromCase( rimCase, caseId, caseName, caseType, caseGroupId );
|
||||
}
|
||||
|
||||
quint64 byteCount = 2 * sizeof( qint64 );
|
||||
byteCount += caseName.size() * sizeof( QChar );
|
||||
byteCount += caseType.size() * sizeof( QChar );
|
||||
|
||||
socketStream << byteCount;
|
||||
|
||||
socketStream << caseId;
|
||||
socketStream << caseName;
|
||||
socketStream << caseType;
|
||||
socketStream << caseGroupId;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetCurrentCase_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetCurrentCase>( RiaGetCurrentCase::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetSelectedCases : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetSelectedCases" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
{
|
||||
std::vector<RimCase*> cases;
|
||||
caf::SelectionManager::instance()->objectsByType( &cases );
|
||||
|
||||
std::vector<qint64> caseIds;
|
||||
std::vector<QString> caseNames;
|
||||
std::vector<QString> caseTypes;
|
||||
std::vector<qint64> caseGroupIds;
|
||||
|
||||
getCaseInfoFromCases( cases, caseIds, caseNames, caseTypes, caseGroupIds );
|
||||
|
||||
quint64 byteCount = sizeof( quint64 );
|
||||
quint64 selectionCount = caseIds.size();
|
||||
|
||||
for ( size_t i = 0; i < selectionCount; i++ )
|
||||
{
|
||||
byteCount += 2 * sizeof( qint64 );
|
||||
byteCount += caseNames[i].size() * sizeof( QChar );
|
||||
byteCount += caseTypes[i].size() * sizeof( QChar );
|
||||
}
|
||||
|
||||
socketStream << byteCount;
|
||||
socketStream << selectionCount;
|
||||
|
||||
for ( size_t i = 0; i < selectionCount; i++ )
|
||||
{
|
||||
socketStream << caseIds[i];
|
||||
socketStream << caseNames[i];
|
||||
socketStream << caseTypes[i];
|
||||
socketStream << caseGroupIds[i];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetSelectedCases_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetSelectedCases>( RiaGetSelectedCases::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetCaseGroups : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetCaseGroups" ); }
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
RimProject* proj = RimProject::current();
|
||||
RimEclipseCaseCollection* analysisModels =
|
||||
( proj && proj->activeOilField() ) ? proj->activeOilField()->analysisModels() : nullptr;
|
||||
if ( analysisModels )
|
||||
{
|
||||
std::vector<QString> groupNames;
|
||||
std::vector<qint64> groupIds;
|
||||
|
||||
size_t caseGroupCount = analysisModels->caseGroups().size();
|
||||
quint64 byteCount = 0;
|
||||
|
||||
for ( size_t i = 0; i < caseGroupCount; i++ )
|
||||
{
|
||||
RimIdenticalGridCaseGroup* cg = analysisModels->caseGroups()[i];
|
||||
|
||||
QString caseGroupName = cg->name;
|
||||
qint64 caseGroupId = cg->groupId;
|
||||
|
||||
byteCount += caseGroupName.size() * sizeof( QChar );
|
||||
byteCount += sizeof( qint64 );
|
||||
|
||||
groupNames.push_back( caseGroupName );
|
||||
groupIds.push_back( caseGroupId );
|
||||
}
|
||||
|
||||
socketStream << (quint64)byteCount;
|
||||
socketStream << (quint64)caseGroupCount;
|
||||
|
||||
for ( size_t i = 0; i < caseGroupCount; i++ )
|
||||
{
|
||||
socketStream << groupNames[i];
|
||||
socketStream << groupIds[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ERROR
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetCaseGroups_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetCaseGroups>( RiaGetCaseGroups::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetCases : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetCases" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
int argCaseGroupId = -1;
|
||||
|
||||
if ( args.size() == 2 )
|
||||
{
|
||||
argCaseGroupId = args[1].toInt();
|
||||
}
|
||||
|
||||
RimProject* proj = RimProject::current();
|
||||
RimEclipseCaseCollection* analysisModels =
|
||||
( proj && proj->activeOilField() ) ? proj->activeOilField()->analysisModels() : nullptr;
|
||||
if ( analysisModels )
|
||||
{
|
||||
std::vector<RimCase*> cases;
|
||||
if ( argCaseGroupId == -1 )
|
||||
{
|
||||
proj->allCases( cases );
|
||||
}
|
||||
else
|
||||
{
|
||||
RimIdenticalGridCaseGroup* caseGroup = nullptr;
|
||||
for ( size_t i = 0; i < analysisModels->caseGroups().size(); i++ )
|
||||
{
|
||||
RimIdenticalGridCaseGroup* cg = analysisModels->caseGroups()[i];
|
||||
|
||||
if ( argCaseGroupId == cg->groupId() )
|
||||
{
|
||||
caseGroup = cg;
|
||||
}
|
||||
}
|
||||
|
||||
if ( caseGroup )
|
||||
{
|
||||
for ( size_t i = 0; i < caseGroup->statisticsCaseCollection()->reservoirs.size(); i++ )
|
||||
{
|
||||
cases.push_back( caseGroup->statisticsCaseCollection()->reservoirs[i] );
|
||||
}
|
||||
|
||||
for ( size_t i = 0; i < caseGroup->caseCollection()->reservoirs.size(); i++ )
|
||||
{
|
||||
cases.push_back( caseGroup->caseCollection()->reservoirs[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<qint64> caseIds;
|
||||
std::vector<QString> caseNames;
|
||||
std::vector<QString> caseTypes;
|
||||
std::vector<qint64> caseGroupIds;
|
||||
|
||||
getCaseInfoFromCases( cases, caseIds, caseNames, caseTypes, caseGroupIds );
|
||||
|
||||
quint64 byteCount = sizeof( quint64 );
|
||||
quint64 caseCount = caseIds.size();
|
||||
|
||||
for ( size_t i = 0; i < caseCount; i++ )
|
||||
{
|
||||
byteCount += 2 * sizeof( qint64 );
|
||||
byteCount += caseNames[i].size() * sizeof( QChar );
|
||||
byteCount += caseTypes[i].size() * sizeof( QChar );
|
||||
}
|
||||
|
||||
socketStream << byteCount;
|
||||
socketStream << caseCount;
|
||||
|
||||
for ( size_t i = 0; i < caseCount; i++ )
|
||||
{
|
||||
socketStream << caseIds[i];
|
||||
socketStream << caseNames[i];
|
||||
socketStream << caseTypes[i];
|
||||
socketStream << caseGroupIds[i];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetCases_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetCases>( RiaGetCases::commandName() );
|
||||
1402
ApplicationLibCode/SocketInterface/RiaPropertyDataCommands.cpp
Normal file
1402
ApplicationLibCode/SocketInterface/RiaPropertyDataCommands.cpp
Normal file
File diff suppressed because it is too large
Load Diff
54
ApplicationLibCode/SocketInterface/RiaSocketCommand.h
Normal file
54
ApplicationLibCode/SocketInterface/RiaSocketCommand.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/// The base class for classes interpreting commands sent via socket.
|
||||
/// Works in close connection with RiaSocketServer
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class RiaSocketServer;
|
||||
|
||||
class QTcpSocket;
|
||||
class QDataStream;
|
||||
class QByteArray;
|
||||
|
||||
#include <QList>
|
||||
|
||||
class RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
virtual ~RiaSocketCommand() {}
|
||||
|
||||
/// This method is supposed to interpret the commands received from the calling socket connection and
|
||||
/// read the data currently available.
|
||||
/// If it read all the data and completed the command, it is supposed to return true. If it did not read all the
|
||||
/// data, it is supposed to return false. The socket server will then assume that the command is not completely
|
||||
/// interpreted, and will continue to call interpretMore() until that method returns true.
|
||||
|
||||
virtual bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) = 0;
|
||||
|
||||
/// This method is supposed to read whatever more data that is available on the socket connection, and return true
|
||||
/// if it was able to read all the data. If not all the data was available, it must return false, so that the
|
||||
/// RiaSocketServer will call this method again when more data becomes available.
|
||||
virtual bool interpretMore( RiaSocketServer* server, QTcpSocket* currentClient ) { return true; }
|
||||
};
|
||||
|
||||
#include "cafFactory.h"
|
||||
typedef caf::Factory<RiaSocketCommand, QString> RiaSocketCommandFactory;
|
||||
110
ApplicationLibCode/SocketInterface/RiaSocketDataTransfer.cpp
Normal file
110
ApplicationLibCode/SocketInterface/RiaSocketDataTransfer.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA
|
||||
// Copyright (C) Ceetron Solutions 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 "RiaSocketDataTransfer.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaSocketDataTransfer::writeBlockDataToSocket( QTcpSocket* socket,
|
||||
const char* data,
|
||||
quint64 bytesToWrite,
|
||||
QStringList& errorMessages )
|
||||
{
|
||||
quint64 bytesWritten = 0;
|
||||
|
||||
quint64 maxBlockSize = maximumValueCountInBlock() * sizeof( double );
|
||||
|
||||
while ( bytesWritten < bytesToWrite )
|
||||
{
|
||||
quint64 byteCountToWrite = qMin( bytesToWrite - bytesWritten, maxBlockSize );
|
||||
|
||||
qint64 actuallyBytesWritten = socket->write( data + bytesWritten, byteCountToWrite );
|
||||
if ( actuallyBytesWritten < 0 )
|
||||
{
|
||||
errorMessages.push_back( "Error detected when writing data, error string from socket" );
|
||||
errorMessages.push_back( socket->errorString() );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bytesWritten += actuallyBytesWritten;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaSocketDataTransfer::readBlockDataFromSocket( QTcpSocket* socket, char* data, quint64 bytesToRead, QStringList& errorMessages )
|
||||
{
|
||||
quint64 bytesRead = 0;
|
||||
|
||||
quint64 maxBlockSize = maximumValueCountInBlock() * sizeof( double );
|
||||
|
||||
while ( bytesRead < bytesToRead )
|
||||
{
|
||||
if ( socket->bytesAvailable() )
|
||||
{
|
||||
quint64 byteCountToRead = bytesToRead - bytesRead;
|
||||
byteCountToRead = qMin( byteCountToRead, maxBlockSize );
|
||||
|
||||
qint64 actuallyBytesRead = socket->read( data + bytesRead, byteCountToRead );
|
||||
if ( actuallyBytesRead < 0 )
|
||||
{
|
||||
errorMessages.push_back( "Error detected when reading data, error string from socket" );
|
||||
errorMessages.push_back( socket->errorString() );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bytesRead += actuallyBytesRead;
|
||||
|
||||
#ifdef octave_oct_h
|
||||
// octave_stdout << "Byte read " << bytesRead << " of a total of "<< bytesToRead << "\n";
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !socket->waitForReadyRead() )
|
||||
{
|
||||
errorMessages.push_back( "Waited for data for %1 milli seconds." );
|
||||
errorMessages.push_back( socket->errorString() );
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow Octave process to end a long running Octave function
|
||||
#ifdef octave_oct_h
|
||||
OCTAVE_QUIT;
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RiaSocketDataTransfer::maximumValueCountInBlock()
|
||||
{
|
||||
return 20000;
|
||||
}
|
||||
40
ApplicationLibCode/SocketInterface/RiaSocketDataTransfer.h
Normal file
40
ApplicationLibCode/SocketInterface/RiaSocketDataTransfer.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA
|
||||
// Copyright (C) Ceetron Solutions 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QStringList>
|
||||
#include <QTcpSocket>
|
||||
|
||||
//==================================================================================================
|
||||
/// Utility class used for transfer of data using QTcpSocket
|
||||
///
|
||||
/// As the compile configuration for octave plugins is quite complex,
|
||||
// the octave plugins includes the cpp-file to be able to compile only one file per plugin
|
||||
//==================================================================================================
|
||||
class RiaSocketDataTransfer
|
||||
{
|
||||
public:
|
||||
static size_t maximumValueCountInBlock();
|
||||
|
||||
public:
|
||||
static bool
|
||||
writeBlockDataToSocket( QTcpSocket* socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages );
|
||||
static bool readBlockDataFromSocket( QTcpSocket* socket, char* data, quint64 bytesToRead, QStringList& errorMessages );
|
||||
};
|
||||
357
ApplicationLibCode/SocketInterface/RiaSocketServer.cpp
Normal file
357
ApplicationLibCode/SocketInterface/RiaSocketServer.cpp
Normal file
@@ -0,0 +1,357 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011- Statoil ASA
|
||||
// Copyright (C) 2013- Ceetron Solutions AS
|
||||
// Copyright (C) 2011-2012 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 "RiaSocketServer.h"
|
||||
#include "RiaSocketCommand.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "RimCase.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimProject.h"
|
||||
|
||||
#include "RiuMainWindow.h"
|
||||
#include "RiuViewer.h"
|
||||
|
||||
#include "cafFactory.h"
|
||||
|
||||
#include <QtNetwork>
|
||||
#include <QtWidgets/QMdiSubWindow>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaSocketServer::RiaSocketServer( QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_tcpServer( nullptr )
|
||||
, m_currentClient( nullptr )
|
||||
, m_currentCommandSize( 0 )
|
||||
, m_currentCommand( nullptr )
|
||||
{
|
||||
m_tcpServer = new QTcpServer( this );
|
||||
|
||||
m_nextPendingConnectionTimer = new QTimer( this );
|
||||
m_nextPendingConnectionTimer->setInterval( 100 );
|
||||
m_nextPendingConnectionTimer->setSingleShot( true );
|
||||
|
||||
if ( !m_tcpServer->listen( QHostAddress::LocalHost, 40001 ) )
|
||||
{
|
||||
QString txt = "Disabled communication with Octave due to another ResInsight process running.";
|
||||
|
||||
RiaLogging::warning( txt );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
connect( m_nextPendingConnectionTimer, SIGNAL( timeout() ), this, SLOT( slotNewClientConnection() ) );
|
||||
connect( m_tcpServer, SIGNAL( newConnection() ), this, SLOT( slotNewClientConnection() ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaSocketServer::~RiaSocketServer()
|
||||
{
|
||||
assert( m_currentCommand == nullptr );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
unsigned short RiaSocketServer::serverPort()
|
||||
{
|
||||
if ( m_tcpServer )
|
||||
return m_tcpServer->serverPort();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaSocketServer::slotNewClientConnection()
|
||||
{
|
||||
// If we are currently handling a connection, just ignore the new one until the current one is disconnected.
|
||||
|
||||
if ( m_currentClient && ( m_currentClient->state() != QAbstractSocket::UnconnectedState ) )
|
||||
{
|
||||
// PMonLog("Starting Timer");
|
||||
m_nextPendingConnectionTimer->start(); // Reset and start again
|
||||
return;
|
||||
}
|
||||
|
||||
// Read pending data from socket
|
||||
|
||||
if ( m_currentClient && m_currentCommand )
|
||||
{
|
||||
bool isFinshed = m_currentCommand->interpretMore( this, m_currentClient );
|
||||
|
||||
if ( !isFinshed )
|
||||
{
|
||||
QString txt;
|
||||
txt = "ResInsight SocketServer : The command did not finish up correctly at the presence of a new one.";
|
||||
|
||||
RiaLogging::error( txt );
|
||||
}
|
||||
}
|
||||
|
||||
handleNextPendingConnection();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Find the requested reservoir by caseId
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEclipseCase* RiaSocketServer::findReservoir( int caseId )
|
||||
{
|
||||
int currCaseId = caseId;
|
||||
if ( caseId < 0 )
|
||||
{
|
||||
currCaseId = RiaApplication::instance()->currentScriptCaseId();
|
||||
}
|
||||
|
||||
if ( currCaseId < 0 )
|
||||
{
|
||||
RimEclipseView* eclipseView = dynamic_cast<RimEclipseView*>( RiaApplication::instance()->activeReservoirView() );
|
||||
if ( eclipseView )
|
||||
{
|
||||
return eclipseView->eclipseCase();
|
||||
}
|
||||
|
||||
// If the active mdi window is different from an Eclipse view, search through available mdi windows to find the
|
||||
// last activated Eclipse view. The sub windows are returned with the most recent activated window at the back.
|
||||
QList<QMdiSubWindow*> subWindows = RiuMainWindow::instance()->subWindowList( QMdiArea::ActivationHistoryOrder );
|
||||
for ( int i = subWindows.size() - 1; i > -1; i-- )
|
||||
{
|
||||
RiuViewer* viewer = subWindows[i]->widget()->findChild<RiuViewer*>();
|
||||
if ( viewer )
|
||||
{
|
||||
RimEclipseView* riv = dynamic_cast<RimEclipseView*>( viewer->ownerReservoirView() );
|
||||
if ( riv )
|
||||
{
|
||||
return riv->eclipseCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RimProject* project = RimProject::current();
|
||||
if ( !project ) return nullptr;
|
||||
|
||||
std::vector<RimCase*> cases;
|
||||
project->allCases( cases );
|
||||
|
||||
for ( size_t i = 0; i < cases.size(); i++ )
|
||||
{
|
||||
if ( cases[i]->caseId == currCaseId )
|
||||
{
|
||||
return dynamic_cast<RimEclipseCase*>( cases[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Reads the command name size, the command string and creates a new command object based on the string read.
|
||||
/// Tries to interpret the command as well.
|
||||
/// Returns whether the command actually was completely finished in one go.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaSocketServer::readCommandFromOctave()
|
||||
{
|
||||
QDataStream socketStream( m_currentClient );
|
||||
socketStream.setVersion( riOctavePlugin::qtDataStreamVersion );
|
||||
|
||||
// If we have not read the currentCommandSize
|
||||
// read the size of the command if all the data is available
|
||||
|
||||
if ( m_currentCommandSize == 0 )
|
||||
{
|
||||
if ( m_currentClient->bytesAvailable() < (int)sizeof( qint64 ) ) return false;
|
||||
|
||||
socketStream >> m_currentCommandSize;
|
||||
}
|
||||
|
||||
// Check if the complete command is available, return and whait for readyRead() if not
|
||||
if ( m_currentClient->bytesAvailable() < m_currentCommandSize ) return false;
|
||||
|
||||
// Now we can read the command name
|
||||
|
||||
QByteArray command = m_currentClient->read( m_currentCommandSize );
|
||||
QTextStream commandStream( command );
|
||||
|
||||
QList<QByteArray> args;
|
||||
while ( !commandStream.atEnd() )
|
||||
{
|
||||
QByteArray arg;
|
||||
commandStream >> arg;
|
||||
args.push_back( arg );
|
||||
}
|
||||
|
||||
CVF_ASSERT( args.size() > 0 );
|
||||
|
||||
// Create the actual RiaSocketCommand object that will interpret the socket data
|
||||
|
||||
m_currentCommand = RiaSocketCommandFactory::instance()->create( args[0] );
|
||||
|
||||
if ( m_currentCommand )
|
||||
{
|
||||
bool finished = m_currentCommand->interpretCommand( this, args, socketStream );
|
||||
return finished;
|
||||
}
|
||||
else
|
||||
{
|
||||
QString txt;
|
||||
txt = QString( "ResInsight SocketServer: Unknown command: %1" ).arg( args[0].data() );
|
||||
|
||||
RiaLogging::error( txt );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaSocketServer::slotCurrentClientDisconnected()
|
||||
{
|
||||
if ( m_currentCommand )
|
||||
{
|
||||
// Make sure we read what can be read.
|
||||
bool isFinished = m_currentCommand->interpretMore( this, m_currentClient );
|
||||
|
||||
if ( !isFinished )
|
||||
{
|
||||
QString txt;
|
||||
txt = QString( "ResInsight SocketServer: The command was interrupted and did not finish because the "
|
||||
"connection to octave disconnected." );
|
||||
|
||||
RiaLogging::error( txt );
|
||||
}
|
||||
}
|
||||
|
||||
handleNextPendingConnection();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaSocketServer::slotReadyRead()
|
||||
{
|
||||
if ( m_currentCommand )
|
||||
{
|
||||
bool isFinished = m_currentCommand->interpretMore( this, m_currentClient );
|
||||
|
||||
if ( isFinished )
|
||||
{
|
||||
handleNextPendingConnection();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isFinished = readCommandFromOctave();
|
||||
if ( isFinished )
|
||||
{
|
||||
handleNextPendingConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaSocketServer::showErrorMessage( const QString& message ) const
|
||||
{
|
||||
RiaLogging::error( message );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaSocketServer::terminateCurrentConnection()
|
||||
{
|
||||
if ( m_currentClient )
|
||||
{
|
||||
m_currentClient->disconnect( SIGNAL( disconnected() ) );
|
||||
m_currentClient->disconnect( SIGNAL( readyRead() ) );
|
||||
m_currentClient->deleteLater();
|
||||
m_currentClient = nullptr;
|
||||
}
|
||||
|
||||
// Clean up more state:
|
||||
|
||||
if ( m_currentCommand )
|
||||
{
|
||||
delete m_currentCommand;
|
||||
m_currentCommand = nullptr;
|
||||
}
|
||||
|
||||
m_currentCommandSize = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaSocketServer::handleNextPendingConnection()
|
||||
{
|
||||
if ( m_currentClient && ( m_currentClient->state() != QAbstractSocket::UnconnectedState ) )
|
||||
{
|
||||
// PMonLog("Starting Timer");
|
||||
m_nextPendingConnectionTimer->start(); // Reset and start again
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop timer
|
||||
if ( m_nextPendingConnectionTimer->isActive() )
|
||||
{
|
||||
// PMonLog("Stopping Timer");
|
||||
m_nextPendingConnectionTimer->stop();
|
||||
}
|
||||
|
||||
terminateCurrentConnection();
|
||||
|
||||
QTcpSocket* clientToHandle = m_tcpServer->nextPendingConnection();
|
||||
if ( clientToHandle )
|
||||
{
|
||||
CVF_ASSERT( m_currentClient == nullptr );
|
||||
CVF_ASSERT( m_currentCommand == nullptr );
|
||||
|
||||
m_currentClient = clientToHandle;
|
||||
m_currentCommandSize = 0;
|
||||
|
||||
connect( m_currentClient, SIGNAL( disconnected() ), this, SLOT( slotCurrentClientDisconnected() ) );
|
||||
connect( m_currentClient, SIGNAL( readyRead() ), this, SLOT( slotReadyRead() ) );
|
||||
|
||||
if ( m_currentClient->bytesAvailable() )
|
||||
{
|
||||
bool isFinished = this->readCommandFromOctave();
|
||||
if ( isFinished )
|
||||
{
|
||||
// Call ourselves recursively until there are none left, or until it can not be processed in one go.
|
||||
this->handleNextPendingConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
81
ApplicationLibCode/SocketInterface/RiaSocketServer.h
Normal file
81
ApplicationLibCode/SocketInterface/RiaSocketServer.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011- Statoil ASA
|
||||
// Copyright (C) 2013- Ceetron Solutions AS
|
||||
// Copyright (C) 2011-2012 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaSocketServerDefines.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QObject>
|
||||
#include <vector>
|
||||
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QTcpServer;
|
||||
class QTcpSocket;
|
||||
class QNetworkSession;
|
||||
class QTimer;
|
||||
class RimEclipseCase;
|
||||
class RiaSocketCommand;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaSocketServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum ReadState
|
||||
{
|
||||
ReadingCommand,
|
||||
ReadingPropertyData
|
||||
};
|
||||
|
||||
public:
|
||||
explicit RiaSocketServer( QObject* parent = nullptr );
|
||||
~RiaSocketServer() override;
|
||||
|
||||
unsigned short serverPort();
|
||||
RimEclipseCase* findReservoir( int caseId );
|
||||
QTcpSocket* currentClient() { return m_currentClient; }
|
||||
|
||||
void showErrorMessage( const QString& message ) const;
|
||||
|
||||
private slots:
|
||||
void slotNewClientConnection();
|
||||
void slotCurrentClientDisconnected();
|
||||
void slotReadyRead();
|
||||
|
||||
private:
|
||||
void handleNextPendingConnection();
|
||||
void terminateCurrentConnection();
|
||||
bool readCommandFromOctave();
|
||||
|
||||
private:
|
||||
QTcpServer* m_tcpServer;
|
||||
|
||||
QTcpSocket* m_currentClient;
|
||||
qint64 m_currentCommandSize; ///< The size in bytes of the command we are currently reading.
|
||||
|
||||
RiaSocketCommand* m_currentCommand;
|
||||
|
||||
QTimer* m_nextPendingConnectionTimer;
|
||||
};
|
||||
24
ApplicationLibCode/SocketInterface/RiaSocketServerDefines.h
Normal file
24
ApplicationLibCode/SocketInterface/RiaSocketServerDefines.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- Equinor ASA
|
||||
//
|
||||
// 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 <QDataStream>
|
||||
|
||||
namespace riOctavePlugin
|
||||
{
|
||||
const int qtDataStreamVersion = QDataStream::Qt_4_0;
|
||||
}
|
||||
137
ApplicationLibCode/SocketInterface/RiaSocketTools.cpp
Normal file
137
ApplicationLibCode/SocketInterface/RiaSocketTools.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011- Statoil ASA
|
||||
// Copyright (C) 2013- Ceetron Solutions AS
|
||||
// Copyright (C) 2011-2012 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 "RiaSocketTools.h"
|
||||
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaSocketDataTransfer.h"
|
||||
#include "RiaSocketServer.h"
|
||||
|
||||
#include "Rim3dOverlayInfoConfig.h"
|
||||
#include "RimCaseCollection.h"
|
||||
#include "RimCellEdgeColors.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseCellColors.h"
|
||||
#include "RimEclipseInputCase.h"
|
||||
#include "RimEclipseInputPropertyCollection.h"
|
||||
#include "RimEclipsePropertyFilterCollection.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimIdenticalGridCaseGroup.h"
|
||||
#include "RimReservoirCellResultsStorage.h"
|
||||
#include "RimSimWellInViewCollection.h"
|
||||
|
||||
#include "cvfTimer.h"
|
||||
|
||||
#include <QTcpSocket>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEclipseCase* RiaSocketTools::findCaseFromArgs( RiaSocketServer* server, const QList<QByteArray>& args )
|
||||
{
|
||||
RimEclipseCase* rimCase = nullptr;
|
||||
int caseId = -1;
|
||||
|
||||
if ( args.size() > 1 )
|
||||
{
|
||||
caseId = args[1].toInt();
|
||||
}
|
||||
rimCase = server->findReservoir( caseId );
|
||||
|
||||
if ( rimCase == nullptr )
|
||||
{
|
||||
// TODO: Display error message a different place to avoid socket comm to be halted.
|
||||
// server->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not find
|
||||
// the Case with CaseId : \"%1\"").arg(caseId));
|
||||
}
|
||||
|
||||
return rimCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaSocketTools::getCaseInfoFromCase( RimCase* rimCase, qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId )
|
||||
{
|
||||
CVF_ASSERT( rimCase );
|
||||
|
||||
caseId = rimCase->caseId;
|
||||
caseName = rimCase->caseUserDescription;
|
||||
|
||||
RimEclipseCase* eclCase = dynamic_cast<RimEclipseCase*>( rimCase );
|
||||
RimCaseCollection* caseCollection = nullptr;
|
||||
if ( eclCase )
|
||||
{
|
||||
caseCollection = eclCase->parentCaseCollection();
|
||||
}
|
||||
|
||||
if ( caseCollection )
|
||||
{
|
||||
caseGroupId = caseCollection->parentCaseGroup()->groupId;
|
||||
|
||||
if ( RimIdenticalGridCaseGroup::isStatisticsCaseCollection( caseCollection ) )
|
||||
{
|
||||
caseType = "StatisticsCase";
|
||||
}
|
||||
else
|
||||
{
|
||||
caseType = "SourceCase";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
caseGroupId = -1;
|
||||
|
||||
if ( dynamic_cast<RimEclipseInputCase*>( rimCase ) )
|
||||
{
|
||||
caseType = "InputCase";
|
||||
}
|
||||
else if ( eclCase )
|
||||
{
|
||||
caseType = "ResultCase";
|
||||
}
|
||||
else
|
||||
{
|
||||
caseType = "GeoMechCase";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaSocketTools::writeBlockData( RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite )
|
||||
{
|
||||
cvf::Timer timer;
|
||||
|
||||
QStringList errorMessages;
|
||||
bool writeSucceded = RiaSocketDataTransfer::writeBlockDataToSocket( socket, data, bytesToWrite, errorMessages );
|
||||
|
||||
if ( server )
|
||||
{
|
||||
for ( int i = 0; i < errorMessages.size(); i++ )
|
||||
{
|
||||
server->showErrorMessage( errorMessages[i] );
|
||||
}
|
||||
}
|
||||
|
||||
return writeSucceded;
|
||||
}
|
||||
41
ApplicationLibCode/SocketInterface/RiaSocketTools.h
Normal file
41
ApplicationLibCode/SocketInterface/RiaSocketTools.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011- Statoil ASA
|
||||
// Copyright (C) 2013- Ceetron Solutions AS
|
||||
// Copyright (C) 2011-2012 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
class RimCase;
|
||||
class RiaSocketServer;
|
||||
class RimEclipseCase;
|
||||
class QTcpSocket;
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
|
||||
#define PMonLog( MessageString ) RiuMainWindow::instance()->processMonitor()->addStringToLog( MessageString );
|
||||
|
||||
class RiaSocketTools
|
||||
{
|
||||
public:
|
||||
static RimEclipseCase* findCaseFromArgs( RiaSocketServer* server, const QList<QByteArray>& args );
|
||||
static void
|
||||
getCaseInfoFromCase( RimCase* rimCase, qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId );
|
||||
|
||||
static bool writeBlockData( RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite );
|
||||
};
|
||||
342
ApplicationLibCode/SocketInterface/RiaWellDataCommands.cpp
Normal file
342
ApplicationLibCode/SocketInterface/RiaWellDataCommands.cpp
Normal file
@@ -0,0 +1,342 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011- Statoil ASA
|
||||
// Copyright (C) 2013- Ceetron Solutions AS
|
||||
// Copyright (C) 2011-2012 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 "RiaSocketCommand.h"
|
||||
#include "RiaSocketServer.h"
|
||||
#include "RiaSocketTools.h"
|
||||
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigGridBase.h"
|
||||
#include "RigSimWellData.h"
|
||||
|
||||
#include "RimEclipseCase.h"
|
||||
|
||||
#include "cvfCollection.h"
|
||||
|
||||
#include <QTcpSocket>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetWellNames : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetWellNames" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
int caseId = args[1].toInt();
|
||||
RimEclipseCase* rimCase = server->findReservoir( caseId );
|
||||
if ( !rimCase )
|
||||
{
|
||||
server->showErrorMessage( RiaSocketServer::tr( "ResInsight SocketServer: \n" ) +
|
||||
RiaSocketServer::tr( "Could not find the case with ID : \"%1\"" ).arg( caseId ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<QString> wellNames;
|
||||
|
||||
const cvf::Collection<RigSimWellData>& wells = rimCase->eclipseCaseData()->wellResults();
|
||||
|
||||
for ( size_t wIdx = 0; wIdx < wells.size(); ++wIdx )
|
||||
{
|
||||
wellNames.push_back( wells[wIdx]->m_wellName );
|
||||
}
|
||||
|
||||
quint64 byteCount = sizeof( quint64 );
|
||||
quint64 wellCount = wellNames.size();
|
||||
|
||||
for ( size_t wIdx = 0; wIdx < wellCount; wIdx++ )
|
||||
{
|
||||
byteCount += wellNames[wIdx].size() * sizeof( QChar );
|
||||
}
|
||||
|
||||
socketStream << byteCount;
|
||||
socketStream << wellCount;
|
||||
|
||||
for ( size_t wIdx = 0; wIdx < wellCount; wIdx++ )
|
||||
{
|
||||
socketStream << wellNames[wIdx];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetWellNames_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetWellNames>( RiaGetWellNames::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetWellStatus : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetWellStatus" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
int caseId = args[1].toInt();
|
||||
QString wellName = args[2];
|
||||
|
||||
RimEclipseCase* rimCase = server->findReservoir( caseId );
|
||||
if ( !rimCase )
|
||||
{
|
||||
server->showErrorMessage( RiaSocketServer::tr( "ResInsight SocketServer: \n" ) +
|
||||
RiaSocketServer::tr( "Could not find the case with ID : \"%1\"" ).arg( caseId ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create a list of all the requested time steps
|
||||
|
||||
std::vector<size_t> requestedTimesteps;
|
||||
// First find the well result for the correct well
|
||||
|
||||
const cvf::Collection<RigSimWellData>& allWellRes = rimCase->eclipseCaseData()->wellResults();
|
||||
cvf::ref<RigSimWellData> currentWellResult;
|
||||
for ( size_t tsIdx = 0; tsIdx < allWellRes.size(); ++tsIdx )
|
||||
{
|
||||
if ( allWellRes[tsIdx]->m_wellName == wellName )
|
||||
{
|
||||
currentWellResult = allWellRes[tsIdx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( currentWellResult.isNull() )
|
||||
{
|
||||
server->showErrorMessage( RiaSocketServer::tr( "ResInsight SocketServer: \n" ) +
|
||||
RiaSocketServer::tr( "Could not find the well with name : \"%1\"" ).arg( wellName ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( args.size() <= 3 )
|
||||
{
|
||||
// Select all timesteps.
|
||||
|
||||
for ( size_t tsIdx = 0; tsIdx < currentWellResult->m_resultTimeStepIndexToWellTimeStepIndex.size(); ++tsIdx )
|
||||
{
|
||||
requestedTimesteps.push_back( tsIdx );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool timeStepReadError = false;
|
||||
for ( int argIdx = 3; 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->showErrorMessage(
|
||||
RiaSocketServer::tr( "ResInsight SocketServer: riGetGridProperty : \n" ) +
|
||||
RiaSocketServer::tr( "An error occurred while interpreting the requested timesteps." ) );
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<QString> wellTypes;
|
||||
std::vector<qint32> wellStatuses;
|
||||
|
||||
for ( size_t tsIdx = 0; tsIdx < requestedTimesteps.size(); ++tsIdx )
|
||||
{
|
||||
QString wellType = "NotDefined";
|
||||
qint32 wellStatus = 0;
|
||||
if ( currentWellResult->hasWellResult( tsIdx ) )
|
||||
{
|
||||
switch ( currentWellResult->wellResultFrame( tsIdx ).m_productionType )
|
||||
{
|
||||
case RigWellResultFrame::PRODUCER:
|
||||
wellType = "Producer";
|
||||
break;
|
||||
case RigWellResultFrame::OIL_INJECTOR:
|
||||
wellType = "OilInjector";
|
||||
break;
|
||||
case RigWellResultFrame::WATER_INJECTOR:
|
||||
wellType = "WaterInjector";
|
||||
break;
|
||||
case RigWellResultFrame::GAS_INJECTOR:
|
||||
wellType = "GasInjector";
|
||||
break;
|
||||
}
|
||||
|
||||
wellStatus = currentWellResult->wellResultFrame( tsIdx ).m_isOpen ? 1 : 0;
|
||||
}
|
||||
|
||||
wellTypes.push_back( wellType );
|
||||
wellStatuses.push_back( wellStatus );
|
||||
}
|
||||
|
||||
quint64 byteCount = sizeof( quint64 );
|
||||
quint64 timeStepCount = wellTypes.size();
|
||||
|
||||
for ( size_t tsIdx = 0; tsIdx < timeStepCount; tsIdx++ )
|
||||
{
|
||||
byteCount += wellTypes[tsIdx].size() * sizeof( QChar );
|
||||
byteCount += sizeof( qint32 );
|
||||
}
|
||||
|
||||
socketStream << byteCount;
|
||||
socketStream << timeStepCount;
|
||||
|
||||
for ( size_t tsIdx = 0; tsIdx < timeStepCount; tsIdx++ )
|
||||
{
|
||||
socketStream << wellTypes[tsIdx];
|
||||
socketStream << wellStatuses[tsIdx];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetWellStatus_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetWellStatus>( RiaGetWellStatus::commandName() );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaGetWellCells : public RiaSocketCommand
|
||||
{
|
||||
public:
|
||||
static QString commandName() { return QString( "GetWellCells" ); }
|
||||
|
||||
bool interpretCommand( RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream ) override
|
||||
{
|
||||
int caseId = args[1].toInt();
|
||||
QString wellName = args[2];
|
||||
size_t timeStepIdx = args[3].toInt() - 1; // Interpret timeStepIdx from octave as 1-based
|
||||
|
||||
RimEclipseCase* rimCase = server->findReservoir( caseId );
|
||||
if ( !rimCase )
|
||||
{
|
||||
server->showErrorMessage( RiaSocketServer::tr( "ResInsight SocketServer: \n" ) +
|
||||
RiaSocketServer::tr( "Could not find the case with ID : \"%1\"" ).arg( caseId ) );
|
||||
|
||||
socketStream << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
const cvf::Collection<RigSimWellData>& allWellRes = rimCase->eclipseCaseData()->wellResults();
|
||||
cvf::ref<RigSimWellData> currentWellResult;
|
||||
for ( size_t cIdx = 0; cIdx < allWellRes.size(); ++cIdx )
|
||||
{
|
||||
if ( allWellRes[cIdx]->m_wellName == wellName )
|
||||
{
|
||||
currentWellResult = allWellRes[cIdx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( currentWellResult.isNull() )
|
||||
{
|
||||
server->showErrorMessage( RiaSocketServer::tr( "ResInsight SocketServer: \n" ) +
|
||||
RiaSocketServer::tr( "Could not find the well with name : \"%1\"" ).arg( wellName ) );
|
||||
|
||||
socketStream << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( !currentWellResult->hasWellResult( timeStepIdx ) )
|
||||
{
|
||||
socketStream << (quint64)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<qint32> cellIs;
|
||||
std::vector<qint32> cellJs;
|
||||
std::vector<qint32> cellKs;
|
||||
std::vector<qint32> gridIndices;
|
||||
std::vector<qint32> cellStatuses;
|
||||
std::vector<qint32> branchIds;
|
||||
std::vector<qint32> segmentIds;
|
||||
|
||||
// Fetch results
|
||||
const RigWellResultFrame& wellResFrame = currentWellResult->wellResultFrame( timeStepIdx );
|
||||
std::vector<RigGridBase*> grids;
|
||||
rimCase->eclipseCaseData()->allGrids( &grids );
|
||||
|
||||
for ( size_t bIdx = 0; bIdx < wellResFrame.m_wellResultBranches.size(); ++bIdx )
|
||||
{
|
||||
const std::vector<RigWellResultPoint>& branchResPoints =
|
||||
wellResFrame.m_wellResultBranches[bIdx].m_branchResultPoints;
|
||||
for ( size_t rpIdx = 0; rpIdx < branchResPoints.size(); ++rpIdx )
|
||||
{
|
||||
const RigWellResultPoint& resPoint = branchResPoints[rpIdx];
|
||||
|
||||
if ( resPoint.isCell() )
|
||||
{
|
||||
size_t i;
|
||||
size_t j;
|
||||
size_t k;
|
||||
size_t gridIdx = resPoint.m_gridIndex;
|
||||
grids[gridIdx]->ijkFromCellIndex( resPoint.m_gridCellIndex, &i, &j, &k );
|
||||
bool isOpen = resPoint.m_isOpen;
|
||||
int branchId = resPoint.m_ertBranchId;
|
||||
int segmentId = resPoint.m_ertSegmentId;
|
||||
|
||||
cellIs.push_back( static_cast<qint32>( i + 1 ) ); // NB: 1-based index in Octave
|
||||
cellJs.push_back( static_cast<qint32>( j + 1 ) ); // NB: 1-based index in Octave
|
||||
cellKs.push_back( static_cast<qint32>( k + 1 ) ); // NB: 1-based index in Octave
|
||||
gridIndices.push_back( static_cast<qint32>( gridIdx ) );
|
||||
cellStatuses.push_back( static_cast<qint32>( isOpen ) );
|
||||
branchIds.push_back( branchId );
|
||||
segmentIds.push_back( segmentId );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
quint64 byteCount = sizeof( quint64 );
|
||||
quint64 cellCount = cellIs.size();
|
||||
|
||||
byteCount += cellCount * ( 7 * sizeof( qint32 ) );
|
||||
|
||||
socketStream << byteCount;
|
||||
socketStream << cellCount;
|
||||
|
||||
for ( size_t cIdx = 0; cIdx < cellCount; cIdx++ )
|
||||
{
|
||||
socketStream << cellIs[cIdx];
|
||||
socketStream << cellJs[cIdx];
|
||||
socketStream << cellKs[cIdx];
|
||||
socketStream << gridIndices[cIdx];
|
||||
socketStream << cellStatuses[cIdx];
|
||||
socketStream << branchIds[cIdx];
|
||||
socketStream << segmentIds[cIdx];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool RiaGetWellCells_init =
|
||||
RiaSocketCommandFactory::instance()->registerCreator<RiaGetWellCells>( RiaGetWellCells::commandName() );
|
||||
Reference in New Issue
Block a user