Octave Interface: Added riGetWellCells

p4#: 22310
This commit is contained in:
Jacob Støren 2013-09-04 12:57:36 +02:00
parent c396299810
commit e72318f348
6 changed files with 401 additions and 4 deletions

View File

@ -85,6 +85,11 @@ void RigSingleWellResultsData::computeMappingFromResultTimeIndicesToWellTimeIndi
//--------------------------------------------------------------------------------------------------
bool RigSingleWellResultsData::hasWellResult(size_t resultTimeStepIndex) const
{
if (resultTimeStepIndex >= m_resultTimeStepIndexToWellTimeStepIndex.size())
{
return false;
}
size_t wellTimeStepIndex = m_resultTimeStepIndexToWellTimeStepIndex[resultTimeStepIndex];
return wellTimeStepIndex != cvf::UNDEFINED_SIZE_T;

View File

@ -228,3 +228,121 @@ public:
};
static bool RiaGetWellStatus_init = RiaSocketCommandFactory::instance()->registerCreator<RiaGetWellStatus>(RiaGetWellStatus::commandName());
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaGetWellCells : public RiaSocketCommand
{
public:
static QString commandName () { return QString("GetWellCells"); }
virtual bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream)
{
int caseId = args[1].toInt();
QString wellName = args[2];
size_t timeStepIdx = args[3].toInt() - 1; // Interpret timeStepIdx from octave as 1-based
RimCase* rimCase = server->findReservoir(caseId);
if (!rimCase)
{
server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not find the case with ID : \"%1\"").arg(caseId));
socketStream << (quint64)0;
return true;
}
const cvf::Collection<RigSingleWellResultsData>& allWellRes = rimCase->reservoirData()->wellResults();
cvf::ref<RigSingleWellResultsData> currentWellResult;
for (size_t cIdx = 0; cIdx < allWellRes.size(); ++cIdx)
{
if (allWellRes[cIdx]->m_wellName == wellName)
{
currentWellResult = allWellRes[cIdx];
break;
}
}
if (currentWellResult.isNull())
{
server->errorMessageDialog()->showMessage(
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->reservoirData()->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) );
cellJs .push_back( static_cast<qint32>(j) );
cellKs .push_back( static_cast<qint32>(k) );
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());

View File

@ -22,6 +22,7 @@ set(CPP_SOURCES
riGetPropertyNames.cpp
riGetWellNames.cpp
riGetWellStatus.cpp
riGetWellCells.cpp
)
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
@ -86,7 +87,7 @@ else()
-I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} ${RPATH_COMMAND}
-L${OCTAVE_QT_LIBRARY_DIR} -lQtCore${QT_LIBRARY_POSTFIX} -lQtNetwork${QT_LIBRARY_POSTFIX} -o "${octFileName}" "${srcFileName}"
DEPENDS "${srcFileName}"
COMMENT "Generating ${octFileName}"
COMMENT "===> Generating ${octFileName}"
)
else()
add_custom_command(
@ -133,6 +134,7 @@ else()
"${CMAKE_CURRENT_BINARY_DIR}/riGetPropertyNames.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetWellNames.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetWellStatus.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetWellCells.oct"
SOURCES ${CPP_SOURCES}
)

View File

@ -0,0 +1,264 @@
#include <QtNetwork>
#include <octave/oct.h>
#include <octave/oct-map.h>
#include "riSettings.h"
void getWellCells( std::vector<int>& cellIs,
std::vector<int>& cellJs,
std::vector<int>& cellKs,
std::vector<int>& gridIndices,
std::vector<int>& cellStatuses,
std::vector<int>& branchIds,
std::vector<int>& segmentIds,
const QString &hostName, quint16 port,
const qint64& caseId, const QString& wellName, int requestedTimeStep)
{
QString serverName = hostName;
quint16 serverPort = port;
QTcpSocket socket;
socket.connectToHost(serverName, serverPort);
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
{
error((("Connection: ") + socket.errorString()).toLatin1().data());
return;
}
// Create command and send it:
QString command;
command += QString("GetWellCells") + " " + QString::number(caseId) + " " + wellName + " " + QString::number(requestedTimeStep) ;
QByteArray cmdBytes = command.toLatin1();
QDataStream socketStream(&socket);
socketStream.setVersion(riOctavePlugin::qtDataStreamVersion);
socketStream << (qint64)(cmdBytes.size());
socket.write(cmdBytes);
// Get response. First wait for the header
while (socket.bytesAvailable() < (int)(sizeof(quint64)))
{
if (!socket.waitForReadyRead(riOctavePlugin::shortTimeOutMilliSecs))
{
error((("Waiting for header: ") + socket.errorString()).toLatin1().data());
return;
}
}
quint64 byteCount;
socketStream >> byteCount;
if (byteCount == 0)
{
return;
}
while (socket.bytesAvailable() < (int)(byteCount))
{
if (!socket.waitForReadyRead(riOctavePlugin::shortTimeOutMilliSecs))
{
error((("Waiting for data: ") + socket.errorString()).toLatin1().data());
return;
}
OCTAVE_QUIT;
}
quint64 cellCount;
socketStream >> cellCount;
octave_stdout << "riGetWellCells2: Num cells = " << cellCount << std::endl;
cellIs .reserve(cellCount);
cellJs .reserve(cellCount);
cellKs .reserve(cellCount);
gridIndices .reserve(cellCount);
cellStatuses .reserve(cellCount);
branchIds .reserve(cellCount);
segmentIds .reserve(cellCount);
qint32 i, j, k, gIdx, cStat, bId, sId;
for (size_t cIdx = 0; cIdx < cellCount; cIdx++)
{
socketStream >> i;
socketStream >> j;
socketStream >> k;
socketStream >> gIdx;
socketStream >> cStat;
socketStream >> bId;
socketStream >> sId;
cellIs.push_back (i);
cellJs.push_back (j);
cellKs.push_back (k);
gridIndices.push_back (gIdx);
cellStatuses.push_back(cStat);
branchIds.push_back (bId);
segmentIds.push_back (sId);
}
return;
}
DEFUN_DLD (riGetWellCells, args, nargout,
"Usage:\n"
"\n"
" riGetWellCells ([CaseId], WellName, TimeStep) \n"
"\n"
"This function returns the cells defined in the specified well for the time step requested \n"
"as a vector of Structures. \n"
"The Structure is defined as:\n"
"WellCellInfo { \n"
" I, J, K = int # Index to the cell in the grid\n"
" GridIndex = int # the index of the grid. Main grid has index 0.\n"
" CellStatus = int # is either 0 or 1, meaning the cell is closed or open respectively.\n"
"}\n"
"If the CaseId is not defined, ResInsights Current Case is used.\n"
)
{
if (nargout != 1)
{
error("riGetWellCells: Wrong number of output arguments, this function requires one output argument.\n");
print_usage();
return octave_value();
}
int nargin = args.length ();
if (nargin < 2)
{
error("riGetWellCells: Too few arguments, this function needs at least the well name and a timestep as input.\n");
print_usage();
return octave_value();
}
if (nargin > 3)
{
error("riGetWellCells: Too many arguments, this function takes at most three arguments.\n");
print_usage();
return octave_value();
}
std::vector<int> argIndices;
argIndices.push_back(0); // caseId
argIndices.push_back(1); // WellName
argIndices.push_back(2); // TimeStep
// Check if we do not have a CaseId:
if (args(argIndices[0]).is_string()) // Check if first argument is a text. If it is, the caseId is missing
{
argIndices[0] = -1;
for (size_t aIdx = 1; aIdx < argIndices.size(); ++aIdx)
--argIndices[aIdx];
}
if (!args(argIndices[1]).is_string()) // Check if the WellName argument is actually a string
{
error("riGetWellCells: Missing Well Name. this function needs at least the well name and a timestep as input.\n");
print_usage();
return octave_value();
}
if (!args(argIndices[2]).is_numeric_type()) // Check if the TimeStep argument is actually a number
{
error("riGetWellCells: The last argument must be a timestep index.\n");
print_usage();
return octave_value();
}
// Setup the argument list
int caseId = -1;
std::string wellName = "UNDEFINED";
int requestedTimeStep = -1;
if (argIndices[0] >= 0) caseId = args(argIndices[0]).int_value();
if (argIndices[1] >= 0) wellName = args(argIndices[1]).char_matrix_value().row_as_string(0);
if (argIndices[2] >= 0) requestedTimeStep = args(argIndices[2]).int_value();
if (wellName == "UNDEFINED")
{
error("riGetWellCells: The argument must be a text containing the well name.\n");
print_usage();
return octave_value();
}
if (requestedTimeStep == -1)
{
error("riGetWellCells: The last argument must be a timestep index (1 - timestepCount).\n");
print_usage();
return octave_value();
}
std::vector<int> cellIs, cellJs, cellKs;
std::vector<int> gridIndices;
std::vector<int> cellStatuses;
std::vector<int> branchIds;
std::vector<int> segmentIds;
getWellCells( cellIs, cellJs, cellKs,
gridIndices,
cellStatuses,
branchIds,
segmentIds,
"127.0.0.1", 40001,
caseId, QString::fromStdString(wellName), requestedTimeStep);
size_t cellCount = cellIs.size();
if (cellJs.size() != cellCount
|| cellKs.size() != cellCount
|| gridIndices.size() != cellCount
|| cellStatuses.size() != cellCount
|| branchIds.size() != cellCount
|| segmentIds.size() != cellCount )
{
error("riGetWellCells: Inconsistent data received from ResInsight.\n");
return octave_value();
}
// Create cells with N items for each field in the data structure
Cell cellIscv (cellCount, 1);
Cell cellJscv (cellCount, 1);
Cell cellKscv (cellCount, 1);
Cell gridIndicescv (cellCount, 1);
Cell cellStatusescv (cellCount, 1);
Cell branchIdscv (cellCount, 1);
Cell segmentIdscv (cellCount, 1);
for (size_t i = 0; i < cellCount; i++)
{
cellIscv (i) = cellIs [i];
cellJscv (i) = cellJs [i];
cellKscv (i) = cellKs [i];
gridIndicescv (i) = gridIndices [i];
cellStatusescv (i) = cellStatuses[i];
branchIdscv (i) = branchIds [i];
segmentIdscv (i) = segmentIds [i];
}
// Build a map between the field name and field cell values
Octave_map m;
m.assign(riOctavePlugin::wellCellInfo_I, cellIscv );
m.assign(riOctavePlugin::wellCellInfo_J, cellJscv );
m.assign(riOctavePlugin::wellCellInfo_K, cellKscv );
m.assign(riOctavePlugin::wellCellInfo_GridIndex , gridIndicescv );
m.assign(riOctavePlugin::wellCellInfo_CellStatus, cellStatusescv);
m.assign(riOctavePlugin::wellCellInfo_BranchId, branchIdscv );
m.assign(riOctavePlugin::wellCellInfo_SegmentId, segmentIdscv );
return octave_value(m);
}

View File

@ -177,6 +177,7 @@ DEFUN_DLD (riGetWellStatus, args, nargout,
if (wellType.size() != wellStatus.size() )
{
error("riGetWellStatus: Inconsistent data received from ResInsight.\n");
return octave_value();
}
else
{
@ -196,12 +197,10 @@ DEFUN_DLD (riGetWellStatus, args, nargout,
Octave_map m;
m.assign(riOctavePlugin::wellStatus_WellType, cellValuesB);
m.assign(riOctavePlugin::wellStatus_WellStatus, cellValuesC);
m.assign(riOctavePlugin::wellStatus_WellStatus, cellValuesC);
return octave_value(m);
}
}

View File

@ -42,6 +42,15 @@ namespace riOctavePlugin
char caseGroupInfo_CaseGroupId[] = "CaseGroupId";
char caseGroupInfo_CaseGroupName[] = "CaseName";
// Octave data structure : WellCellInfo
char wellCellInfo_I[] = "I";
char wellCellInfo_J[] = "J";
char wellCellInfo_K[] = "K";
char wellCellInfo_GridIndex [] = "GridIndex";
char wellCellInfo_CellStatus[] = "CellStatus";
char wellCellInfo_BranchId[] = "BranchId";
char wellCellInfo_SegmentId[] = "SegmentId";
// Octave data structure : TimeStepDate
char timeStepDate_Year[] = "Year";
char timeStepDate_Month[] = "Month";