mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#4430 Implement GetAvailableProperties() and GetActiveCellResults()
This commit is contained in:
parent
c4a4ceef29
commit
86e202aed0
@ -24,7 +24,7 @@ CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/ApplicationCode/Adm/RiaVersionInfo.h.cmake
|
||||
${CMAKE_BINARY_DIR}/Generated/RiaVersionInfo.h
|
||||
)
|
||||
CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/ApplicationCode/Adm/RiaVersionInfo.py.cmake
|
||||
${CMAKE_BINARY_DIR}/Python/generated/RiaVersionInfo.py
|
||||
${CMAKE_SOURCE_DIR}/Python/generated/RiaVersionInfo.py
|
||||
)
|
||||
|
||||
if (MSVC AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 19.11))
|
||||
|
@ -9,6 +9,7 @@ set ( SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcProjectInfoService.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCommandService.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcResInfoService.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcPropertiesService.h
|
||||
)
|
||||
|
||||
set ( SOURCE_GROUP_SOURCE_FILES
|
||||
@ -18,6 +19,7 @@ set ( SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcProjectInfoService.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCommandService.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcResInfoService.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcPropertiesService.cpp
|
||||
)
|
||||
|
||||
add_definitions(-DENABLE_GRPC)
|
||||
@ -74,6 +76,7 @@ set(PROTO_FILES
|
||||
"ProjectInfo"
|
||||
"Commands"
|
||||
"ResInfo"
|
||||
"Properties"
|
||||
)
|
||||
|
||||
set(GRPC_PYTHON_SOURCE_PATH "${CMAKE_SOURCE_DIR}/Python")
|
||||
@ -139,6 +142,7 @@ endforeach(proto_file)
|
||||
if (PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
|
||||
list(APPEND GRPC_PYTHON_SOURCES
|
||||
${GRPC_PYTHON_GENERATED_SOURCES}
|
||||
"generated/RiaVersionInfo.py"
|
||||
"api/__init__.py"
|
||||
"api/ResInsight.py"
|
||||
"examples/CommandExample.py"
|
||||
|
69
ApplicationCode/GrpcInterface/GrpcProtos/Properties.proto
Normal file
69
ApplicationCode/GrpcInterface/GrpcProtos/Properties.proto
Normal file
@ -0,0 +1,69 @@
|
||||
syntax = "proto3";
|
||||
|
||||
import "Empty.proto";
|
||||
import "CaseInfo.proto";
|
||||
import "GridInfo.proto";
|
||||
|
||||
package rips;
|
||||
|
||||
service Properties
|
||||
{
|
||||
rpc GetAvailableProperties(PropertiesRequest) returns (AvailableProperties) {}
|
||||
rpc GetActiveCellResults(ResultRequest) returns (stream ResultReplyArray) {}
|
||||
rpc GetGridResults(ResultRequest) returns (stream ResultReplyArray) {}
|
||||
rpc SetActiveCellResults(stream ResultRequestArray) returns (Empty) {}
|
||||
rpc SetGridResults(stream ResultRequestArray) returns (Empty) {}
|
||||
}
|
||||
|
||||
enum PropertyType
|
||||
{
|
||||
DYNAMIC_NATIVE = 0;
|
||||
STATIC_NATIVE = 1;
|
||||
SOURSIMRL = 2;
|
||||
GENERATED = 3;
|
||||
INPUT_PROPERTY = 4;
|
||||
FORMATION_NAMES = 5;
|
||||
FLOW_DIAGNOSTICS = 6;
|
||||
INJECTION_FLOODING = 7;
|
||||
REMOVED = 8;
|
||||
UNDEFINED = 999;
|
||||
}
|
||||
|
||||
message PropertiesRequest
|
||||
{
|
||||
Case request_case = 1;
|
||||
PropertyType property_type = 2;
|
||||
PorosityModelType porosity_model = 3;
|
||||
}
|
||||
|
||||
message AvailableProperties
|
||||
{
|
||||
repeated string property_names = 1;
|
||||
}
|
||||
|
||||
message ResultRequest
|
||||
{
|
||||
Case request_case = 1;
|
||||
PropertyType property_type = 2;
|
||||
string property_name = 3;
|
||||
int32 time_step = 4;
|
||||
int32 grid_index = 5;
|
||||
PorosityModelType porosity_model = 6;
|
||||
}
|
||||
|
||||
message TimeStep
|
||||
{
|
||||
int32 index = 1;
|
||||
}
|
||||
|
||||
message ResultRequestArray
|
||||
{
|
||||
repeated double values = 1;
|
||||
Case request_case = 2;
|
||||
TimeStep time_step = 3;
|
||||
}
|
||||
|
||||
message ResultReplyArray
|
||||
{
|
||||
repeated double values = 1;
|
||||
}
|
@ -41,9 +41,8 @@ class RimEclipseCase;
|
||||
//==================================================================================================
|
||||
class RiaActiveCellInfoStateHandler
|
||||
{
|
||||
public:
|
||||
typedef grpc::Status Status;
|
||||
|
||||
public:
|
||||
RiaActiveCellInfoStateHandler();
|
||||
|
||||
Status init(const rips::ActiveCellInfoRequest* request);
|
||||
|
145
ApplicationCode/GrpcInterface/RiaGrpcPropertiesService.cpp
Normal file
145
ApplicationCode/GrpcInterface/RiaGrpcPropertiesService.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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 "RiaGrpcPropertiesService.h"
|
||||
|
||||
#include "RiaGrpcGridInfoService.h"
|
||||
#include "RiaGrpcCallbacks.h"
|
||||
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigEclipseResultAddress.h"
|
||||
|
||||
#include "RimEclipseCase.h"
|
||||
|
||||
using namespace rips;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaActiveCellResultsStateHandler::RiaActiveCellResultsStateHandler()
|
||||
: m_request(nullptr)
|
||||
, m_resultValues(nullptr)
|
||||
, m_currentCellIdx(0u)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaActiveCellResultsStateHandler::init(const ResultRequest* request)
|
||||
{
|
||||
int caseId = request->request_case().id();
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(RiaGrpcServiceInterface::findCase(caseId));
|
||||
if (eclipseCase)
|
||||
{
|
||||
auto porosityModel = static_cast<RiaDefines::PorosityModelType>(request->porosity_model());
|
||||
auto resultData = eclipseCase->eclipseCaseData()->results(porosityModel);
|
||||
auto resultType = static_cast<RiaDefines::ResultCatType>(request->property_type());
|
||||
size_t timeStep = static_cast<size_t>(request->time_step());
|
||||
RigEclipseResultAddress resAddr(resultType, QString::fromStdString(request->property_name()));
|
||||
|
||||
if (resultData->hasResultEntry(resAddr))
|
||||
{
|
||||
if (timeStep < (int)resultData->timeStepCount(resAddr))
|
||||
{
|
||||
m_resultValues = &resultData->cellScalarResults(resAddr, timeStep);
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
return grpc::Status(grpc::NOT_FOUND, "No such time step");
|
||||
}
|
||||
return grpc::Status(grpc::NOT_FOUND, "No such result");
|
||||
}
|
||||
return grpc::Status(grpc::NOT_FOUND, "Couldn't find an Eclipse case matching the case Id");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaActiveCellResultsStateHandler::assignReply(ResultReplyArray* reply)
|
||||
{
|
||||
if (m_resultValues)
|
||||
{
|
||||
const size_t packageSize = RiaGrpcServiceInterface::numberOfMessagesForByteCount(sizeof(rips::ResultReplyArray));
|
||||
size_t packageIndex = 0u;
|
||||
reply->mutable_values()->Reserve((int)packageSize);
|
||||
for (; packageIndex < packageSize && m_currentCellIdx < m_resultValues->size(); ++packageIndex, ++m_currentCellIdx)
|
||||
{
|
||||
reply->add_values(m_resultValues->at(m_currentCellIdx));
|
||||
}
|
||||
if (packageIndex > 0u)
|
||||
{
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
return grpc::Status(grpc::OUT_OF_RANGE, "We've reached the end. This is not an error but means transmission is finished");
|
||||
}
|
||||
return grpc::Status(grpc::NOT_FOUND, "No result values found");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaGrpcPropertiesService::GetAvailableProperties(grpc::ServerContext* context,
|
||||
const PropertiesRequest* request,
|
||||
AvailableProperties* reply)
|
||||
{
|
||||
int caseId = request->request_case().id();
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(RiaGrpcServiceInterface::findCase(caseId));
|
||||
if (eclipseCase)
|
||||
{
|
||||
auto porosityModel = static_cast<RiaDefines::PorosityModelType>(request->porosity_model());
|
||||
auto resultData = eclipseCase->eclipseCaseData()->results(porosityModel);
|
||||
auto resultType = static_cast<RiaDefines::ResultCatType>(request->property_type());
|
||||
QStringList resultNames = resultData->resultNames(resultType);
|
||||
if (!resultNames.empty())
|
||||
{
|
||||
for (QString resultName : resultNames)
|
||||
{
|
||||
reply->add_property_names(resultName.toStdString());
|
||||
}
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
return grpc::Status(grpc::NOT_FOUND, "Could not find any results matching result type");
|
||||
}
|
||||
return grpc::Status(grpc::NOT_FOUND, "No such case");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaGrpcPropertiesService::GetActiveCellResults(grpc::ServerContext* context,
|
||||
const ResultRequest* request,
|
||||
ResultReplyArray* reply,
|
||||
RiaActiveCellResultsStateHandler* stateHandler)
|
||||
{
|
||||
return stateHandler->assignReply(reply);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RiaAbstractGrpcCallback*> RiaGrpcPropertiesService::createCallbacks()
|
||||
{
|
||||
typedef RiaGrpcPropertiesService Self;
|
||||
|
||||
return { new RiaGrpcCallback<Self, PropertiesRequest, AvailableProperties>(this, &Self::GetAvailableProperties, &Self::RequestGetAvailableProperties),
|
||||
new RiaGrpcStreamCallback<Self, ResultRequest, ResultReplyArray, RiaActiveCellResultsStateHandler>(
|
||||
this, &Self::GetActiveCellResults, &Self::RequestGetActiveCellResults, new RiaActiveCellResultsStateHandler)
|
||||
};
|
||||
}
|
||||
|
||||
static bool RiaGrpcPropertiesService_init = RiaGrpcServiceFactory::instance()->registerCreator<RiaGrpcPropertiesService>(typeid(RiaGrpcPropertiesService).hash_code());
|
59
ApplicationCode/GrpcInterface/RiaGrpcPropertiesService.h
Normal file
59
ApplicationCode/GrpcInterface/RiaGrpcPropertiesService.h
Normal file
@ -0,0 +1,59 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- 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.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
#include "RiaGrpcServiceInterface.h"
|
||||
|
||||
#include "Properties.grpc.pb.h"
|
||||
|
||||
#include <grpcpp/grpcpp.h>
|
||||
#include <vector>
|
||||
|
||||
class RiaActiveCellResultsStateHandler
|
||||
{
|
||||
typedef grpc::Status Status;
|
||||
public:
|
||||
RiaActiveCellResultsStateHandler();
|
||||
|
||||
Status init(const rips::ResultRequest* request);
|
||||
Status assignReply(rips::ResultReplyArray* reply);
|
||||
|
||||
private:
|
||||
const rips::ResultRequest* m_request;
|
||||
const std::vector<double>* m_resultValues;
|
||||
size_t m_currentCellIdx;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// gRPC-service answering requests about property information for a given case and time step
|
||||
//
|
||||
//==================================================================================================
|
||||
class RiaGrpcPropertiesService final : public rips::Properties::AsyncService, public RiaGrpcServiceInterface
|
||||
{
|
||||
public:
|
||||
grpc::Status GetAvailableProperties(grpc::ServerContext* context,
|
||||
const rips::PropertiesRequest* request,
|
||||
rips::AvailableProperties* reply) override;
|
||||
grpc::Status GetActiveCellResults(grpc::ServerContext* context,
|
||||
const rips::ResultRequest* request,
|
||||
rips::ResultReplyArray* reply,
|
||||
RiaActiveCellResultsStateHandler* stateHandler);
|
||||
|
||||
std::vector<RiaAbstractGrpcCallback*> createCallbacks() override;
|
||||
};
|
||||
|
@ -7,7 +7,7 @@ import socket
|
||||
|
||||
sys.path.insert(1, os.path.join(sys.path[0], '../generated'))
|
||||
|
||||
import Empty_pb2
|
||||
from Empty_pb2 import Empty
|
||||
import CaseInfo_pb2
|
||||
import CaseInfo_pb2_grpc
|
||||
import Commands_pb2
|
||||
@ -18,15 +18,15 @@ import ProjectInfo_pb2
|
||||
import ProjectInfo_pb2_grpc
|
||||
import ResInfo_pb2
|
||||
import ResInfo_pb2_grpc
|
||||
import Properties_pb2
|
||||
import Properties_pb2_grpc
|
||||
import RiaVersionInfo
|
||||
|
||||
MAX_MESSAGE_LENGTH = 128 * 1024 * 1024
|
||||
|
||||
class ResInfo:
|
||||
def __init__(self, channel):
|
||||
self.resInfo = ResInfo_pb2_grpc.ResInfoStub(channel)
|
||||
def versionMessage(self):
|
||||
return self.resInfo.GetVersion(Empty_pb2.Empty())
|
||||
return self.resInfo.GetVersion(Empty())
|
||||
def majorVersion(self):
|
||||
return self.versionMessage().major_version
|
||||
def minorVersion(self):
|
||||
@ -62,7 +62,7 @@ class CommandExecutor:
|
||||
return self.execute(Commands_pb2.CommandParams(loadCase=Commands_pb2.FilePathRequest(path=path)))
|
||||
|
||||
def closeProject(self):
|
||||
return self.execute(Commands_pb2.CommandParams(closeProject=Empty_pb2.Empty()))
|
||||
return self.execute(Commands_pb2.CommandParams(closeProject=Empty()))
|
||||
|
||||
class GridInfo:
|
||||
def __init__(self, channel):
|
||||
@ -81,18 +81,38 @@ class ProjectInfo:
|
||||
def __init__(self, channel):
|
||||
self.projectInfo = ProjectInfo_pb2_grpc.ProjectInfoStub(channel)
|
||||
def selectedCases(self):
|
||||
selected = self.projectInfo.SelectedCases(Empty_pb2.Empty())
|
||||
selected = self.projectInfo.SelectedCases(Empty())
|
||||
if selected is not None:
|
||||
return selected.case_info
|
||||
else:
|
||||
return None
|
||||
def allCases(self):
|
||||
cases = self.projectInfo.AllCases(Empty_pb2.Empty())
|
||||
cases = self.projectInfo.AllCases(Empty())
|
||||
if cases is not None:
|
||||
return allCases.case_info
|
||||
else:
|
||||
return None
|
||||
|
||||
class Properties:
|
||||
def __init__(self, channel):
|
||||
self.properties = Properties_pb2_grpc.PropertiesStub(channel)
|
||||
def availableProperties(self, caseId, propertyType, porosityModel = 'MATRIX_MODEL'):
|
||||
propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType)
|
||||
porosityModelEnum = GridInfo_pb2.PorosityModelType.Value(porosityModel)
|
||||
request = Properties_pb2.PropertiesRequest (request_case = CaseInfo_pb2.Case(id=caseId),
|
||||
property_type = propertyTypeEnum,
|
||||
porosity_model = porosityModelEnum)
|
||||
return self.properties.GetAvailableProperties(request).property_names
|
||||
def activeCellResults(self, caseId, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'):
|
||||
propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType)
|
||||
porosityModelEnum = GridInfo_pb2.PorosityModelType.Value(porosityModel)
|
||||
request = Properties_pb2.ResultRequest(request_case = CaseInfo_pb2.Case(id=caseId),
|
||||
property_type = propertyTypeEnum,
|
||||
property_name = propertyName,
|
||||
time_step = timeStep,
|
||||
porosity_model = porosityModelEnum)
|
||||
return self.properties.GetActiveCellResults(request)
|
||||
|
||||
class Instance:
|
||||
@staticmethod
|
||||
def is_port_in_use(port):
|
||||
@ -137,7 +157,7 @@ class Instance:
|
||||
|
||||
def __init__(self, port = 50051):
|
||||
location = "localhost:" + str(port)
|
||||
self.channel = grpc.insecure_channel(location, options=[('grpc.max_receive_message_length', MAX_MESSAGE_LENGTH)])
|
||||
self.channel = grpc.insecure_channel(location)
|
||||
|
||||
# Main version check package
|
||||
self.resInfo = ResInfo(self.channel)
|
||||
@ -156,4 +176,5 @@ class Instance:
|
||||
self.commands = CommandExecutor(self.channel)
|
||||
self.gridInfo = GridInfo(self.channel)
|
||||
self.projectInfo = ProjectInfo(self.channel)
|
||||
self.properties = Properties(self.channel)
|
||||
|
@ -1,45 +1,19 @@
|
||||
from ResInsight import ResInsight
|
||||
import grpc
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(1, os.path.join(sys.path[0], '../api'))
|
||||
import ResInsight
|
||||
|
||||
def run():
|
||||
# NOTE(gRPC Python Team): .close() is possible on a channel and should be
|
||||
# used in circumstances in which the with statement does not fit the needs
|
||||
# of the code.
|
||||
logging.basicConfig()
|
||||
resInsight = ResInsight.Instance.find()
|
||||
#gridCount = resInsight.gridInfo.getGridCount(caseId=0)
|
||||
#gridDimensions = resInsight.gridInfo.getAllGridDimensions(caseId=0)
|
||||
|
||||
try:
|
||||
port = 50051
|
||||
if len(sys.argv) > 1:
|
||||
port = sys.argv[1]
|
||||
resInsight = ResInsight("localhost:" + port)
|
||||
timeStepsInfo = resInsight.grid.numberOfTimeSteps(ResInsight.Case(id=0))
|
||||
print ("Number of time steps: " + str(timeStepsInfo.value))
|
||||
resultsAllTimeSteps = []
|
||||
for timeStep in range(0, timeStepsInfo.value - 1):
|
||||
results = resInsight.grid.results(ResInsight.ResultRequest(ResInsight.Case(id=0), ResInsight.ResultAddress(0, "SOIL"), timeStep))
|
||||
print ("Got " + str(len(results.value)) + " values")
|
||||
resultsAllTimeSteps.append(results.value)
|
||||
resultChunks = resInsight.properties.activeCellResults(0, 'DYNAMIC_NATIVE', 'SOIL', 2)
|
||||
|
||||
print("Have stored results array containing " + str(len(resultsAllTimeSteps)) + " time steps")
|
||||
|
||||
print("Looking for first cell with a decent SOIL value")
|
||||
indexFirstProperCell = 0
|
||||
for i in range(0, len(resultsAllTimeSteps[0])):
|
||||
result = resultsAllTimeSteps[0][i]
|
||||
if indexFirstProperCell == 0 and result > 0.01:
|
||||
indexFirstProperCell = i
|
||||
|
||||
for resultsForTimeStep in resultsAllTimeSteps:
|
||||
print ("Result for cell " + str(indexFirstProperCell) + ": " + str(resultsForTimeStep[indexFirstProperCell]))
|
||||
|
||||
except grpc.RpcError as e:
|
||||
if e.code() == grpc.StatusCode.NOT_FOUND:
|
||||
print("Case id not found")
|
||||
else:
|
||||
logging.error('Other error: %s', e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
results = []
|
||||
for resultChunk in resultChunks:
|
||||
for value in resultChunk.values:
|
||||
results.append(value)
|
||||
print("Number of active cells: " + str(len(results)))
|
||||
print("15th active cell: ")
|
||||
for result in results:
|
||||
print(result)
|
||||
|
Loading…
Reference in New Issue
Block a user