#4477 Add python methods to get NNC connection and available properties

Equivalent to GetNNCPropertyNames and GetNNCConnections in Octave.
This commit is contained in:
Kristian Bendiksen 2020-02-21 10:24:58 +01:00 committed by Gaute Lindkvist
parent 795c29bfb3
commit 1a05430123
6 changed files with 360 additions and 0 deletions

View File

@ -13,6 +13,7 @@ set ( SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCommandService.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcAppService.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcPropertiesService.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcNNCPropertiesService.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcPdmObjectService.h
)
@ -27,6 +28,7 @@ set ( SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCommandService.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcAppService.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcPropertiesService.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcNNCPropertiesService.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcPdmObjectService.cpp
)
@ -88,6 +90,7 @@ set(PROTO_FILES
"SimulationWell"
"Project"
"Commands"
"NNCProperties"
"App"
"Properties"
"Grid"

View File

@ -0,0 +1,43 @@
syntax = "proto3";
import "Case.proto";
import "Definitions.proto";
package rips;
service NNCProperties
{
rpc GetAvailableNNCProperties(CaseRequest) returns (AvailableNNCProperties) {}
rpc GetNNCConnections(CaseRequest) returns (stream NNCConnections) {}
}
enum NNCPropertyType
{
NNC_DYNAMIC = 0;
NNC_STATIC = 1;
NNC_GENERATED = 2;
}
message AvailableNNCProperty
{
string name = 1;
NNCPropertyType property_type = 2;
}
message AvailableNNCProperties
{
repeated AvailableNNCProperty properties = 1;
}
message NNCConnection
{
int32 cell_grid_index1 = 1;
int32 cell_grid_index2 = 2;
Vec3i cell1 = 3;
Vec3i cell2 = 4;
}
message NNCConnections
{
repeated NNCConnection connections = 1;
}

View File

@ -17,6 +17,9 @@ import rips.generated.PdmObject_pb2 as PdmObject_pb2
import rips.generated.Properties_pb2 as Properties_pb2
import rips.generated.Properties_pb2_grpc as Properties_pb2_grpc
import rips.generated.NNCProperties_pb2 as NNCProperties_pb2
import rips.generated.NNCProperties_pb2_grpc as NNCProperties_pb2_grpc
from rips.grid import Grid
from rips.pdmobject import PdmObject
from rips.view import View
@ -50,6 +53,8 @@ class Case(PdmObject):
info = self.__case_stub.GetCaseInfo(self.__request)
self.__properties_stub = Properties_pb2_grpc.PropertiesStub(
self.__channel)
self.__nnc_properties_stub = NNCProperties_pb2_grpc.NNCPropertiesStub(
self.__channel)
PdmObject.__init__(self, self.__case_stub.GetPdmObject(self.__request),
self.__channel, project)
@ -980,3 +985,31 @@ class Case(PdmObject):
for each entry.
"""
return self.__case_stub.GetCoarseningInfoArray(self.__request).data
def available_nnc_properties(self):
"""Get a list of available NNC properties
"""
return self.__nnc_properties_stub.GetAvailableNNCProperties(self.__request).properties
def nnc_connections_async(self):
"""Get the NNC connections. Async, so returns an iterator.
Returns:
An iterator to a chunk object containing an array NNCConnection objects.
Loop through the chunks and then the connection within the chunk to get all connections.
"""
return self.__nnc_properties_stub.GetNNCConnections(self.__request)
def nnc_connections(self):
"""Get the NNC connection. Synchronous, so returns a list.
Returns:
A list of NNCConnection objects.
"""
connections = []
generator = self.nnc_connections_async()
for chunk in generator:
for value in chunk.connections:
connections.append(value)
return connections

View File

@ -0,0 +1,35 @@
import sys
import os
import grpc
import pytest
import rips.generated.NNCProperties_pb2 as NNCProperties_pb2
sys.path.insert(1, os.path.join(sys.path[0], '../../'))
import rips
import dataroot
def test_10kSync(rips_instance, initialize_test):
casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
case = rips_instance.project.load_case(path=casePath)
properties = case.available_nnc_properties()
assert(len(properties) == 3)
assert("TRAN" == properties[0].name)
assert(NNCProperties_pb2.NNCPropertyType.NNC_STATIC == properties[0].property_type)
assert("Binary Formation Allen" == properties[1].name)
assert(NNCProperties_pb2.NNCPropertyType.NNC_GENERATED == properties[1].property_type)
assert("Formation Allen" == properties[2].name)
assert(NNCProperties_pb2.NNCPropertyType.NNC_GENERATED == properties[2].property_type)
nnc_connections = case.nnc_connections()
assert(len(nnc_connections) == 84759)
connection = nnc_connections[0]
assert(connection.cell1.i == 33)
assert(connection.cell1.j == 40)
assert(connection.cell1.k == 14)
assert(connection.cell_grid_index1 == 0)

View File

@ -0,0 +1,181 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- 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 "RiaGrpcNNCPropertiesService.h"
#include "RiaGrpcCallbacks.h"
#include "RiaGrpcCaseService.h"
#include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h"
#include "RigEclipseResultAddress.h"
#include "RigEclipseResultInfo.h"
#include "RigMainGrid.h"
#include "RimEclipseCase.h"
using namespace rips;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaNNCConnectionsStateHandler::RiaNNCConnectionsStateHandler()
: m_request( nullptr )
, m_eclipseCase( nullptr )
, m_currentIdx( 0u )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaNNCConnectionsStateHandler::init( const rips::CaseRequest* request )
{
CAF_ASSERT( request );
m_request = request;
RimCase* rimCase = RiaGrpcServiceInterface::findCase( m_request->id() );
m_eclipseCase = dynamic_cast<RimEclipseCase*>( rimCase );
if ( !( m_eclipseCase && m_eclipseCase->eclipseCaseData() && m_eclipseCase->eclipseCaseData()->mainGrid() ) )
{
return grpc::Status( grpc::NOT_FOUND, "Eclipse Case not found" );
}
return grpc::Status::OK;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
rips::Vec3i* createConnectionVec3i( const RigCell& cell )
{
RigGridBase* hostGrid = cell.hostGrid();
size_t gridLocalCellIndex = cell.gridLocalCellIndex();
size_t i, j, k;
hostGrid->ijkFromCellIndex( gridLocalCellIndex, &i, &j, &k );
rips::Vec3i* vec = new rips::Vec3i;
vec->set_i( i );
vec->set_j( j );
vec->set_k( k );
return vec;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaNNCConnectionsStateHandler::assignReply( rips::NNCConnections* reply )
{
RigMainGrid* mainGrid = m_eclipseCase->eclipseCaseData()->mainGrid();
std::vector<RigConnection> connections = mainGrid->nncData()->connections();
size_t connectionCount = connections.size();
const size_t packageSize = RiaGrpcServiceInterface::numberOfDataUnitsInPackage( sizeof( rips::NNCConnection ) );
size_t indexInPackage = 0u;
reply->mutable_connections()->Reserve( (int)packageSize );
for ( ; indexInPackage < packageSize && m_currentIdx < connectionCount; ++indexInPackage )
{
RigConnection& connection = connections[m_currentIdx];
const RigCell& cell1 = mainGrid->globalCellArray()[connection.m_c1GlobIdx];
const RigCell& cell2 = mainGrid->globalCellArray()[connection.m_c2GlobIdx];
NNCConnection* nncConnection = reply->add_connections();
nncConnection->set_allocated_cell1( createConnectionVec3i( cell1 ) );
nncConnection->set_allocated_cell2( createConnectionVec3i( cell2 ) );
nncConnection->set_cell_grid_index1( cell1.hostGrid()->gridIndex() );
nncConnection->set_cell_grid_index2( cell2.hostGrid()->gridIndex() );
m_currentIdx++;
}
if ( indexInPackage > 0u )
{
return Status::OK;
}
return Status( grpc::OUT_OF_RANGE, "We've reached the end. This is not an error but means transmission is finished" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcNNCPropertiesService::GetNNCConnections( grpc::ServerContext* context,
const rips::CaseRequest* request,
rips::NNCConnections* reply,
RiaNNCConnectionsStateHandler* stateHandler )
{
return stateHandler->assignReply( reply );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcNNCPropertiesService::GetAvailableNNCProperties( grpc::ServerContext* context,
const CaseRequest* request,
AvailableNNCProperties* reply )
{
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>( RiaGrpcServiceInterface::findCase( request->id() ) );
if ( eclipseCase && eclipseCase->eclipseCaseData() && eclipseCase->eclipseCaseData()->mainGrid() )
{
RigNNCData* nncData = eclipseCase->eclipseCaseData()->mainGrid()->nncData();
std::vector<RigNNCData::NNCResultType> resultTypes;
resultTypes.push_back( RigNNCData::NNC_DYNAMIC );
resultTypes.push_back( RigNNCData::NNC_STATIC );
resultTypes.push_back( RigNNCData::NNC_GENERATED );
for ( size_t rtIdx = 0; rtIdx < resultTypes.size(); ++rtIdx )
{
std::vector<QString> availableParameters = nncData->availableProperties( resultTypes[rtIdx] );
for ( const QString& parameter : availableParameters )
{
AvailableNNCProperty* property = reply->add_properties();
property->set_name( parameter.toStdString() );
property->set_property_type( static_cast<NNCPropertyType>( resultTypes[rtIdx] ) );
}
}
return grpc::Status::OK;
}
return grpc::Status( grpc::NOT_FOUND, "No such case" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RiaGrpcCallbackInterface*> RiaGrpcNNCPropertiesService::createCallbacks()
{
typedef RiaGrpcNNCPropertiesService Self;
std::vector<RiaGrpcCallbackInterface*> callbacks;
callbacks = {new RiaGrpcUnaryCallback<Self, CaseRequest, AvailableNNCProperties>( this,
&Self::GetAvailableNNCProperties,
&Self::RequestGetAvailableNNCProperties ),
new RiaGrpcServerToClientStreamCallback<Self,
CaseRequest,
rips::NNCConnections,
RiaNNCConnectionsStateHandler>( this,
&Self::GetNNCConnections,
&Self::RequestGetNNCConnections,
new RiaNNCConnectionsStateHandler )};
return callbacks;
}
static bool RiaGrpcNNCPropertiesService_init =
RiaGrpcServiceFactory::instance()->registerCreator<RiaGrpcNNCPropertiesService>(
typeid( RiaGrpcNNCPropertiesService ).hash_code() );

View File

@ -0,0 +1,65 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- 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 "NNCProperties.grpc.pb.h"
#include <grpcpp/grpcpp.h>
#include <vector>
class RimEclipseCase;
//==================================================================================================
//
// State handler for streaming of NNC connections
//
//==================================================================================================
class RiaNNCConnectionsStateHandler
{
typedef grpc::Status Status;
public:
RiaNNCConnectionsStateHandler();
grpc::Status init( const rips::CaseRequest* request );
grpc::Status assignReply( rips::NNCConnections* reply );
protected:
const rips::CaseRequest* m_request;
RimEclipseCase* m_eclipseCase;
size_t m_currentIdx;
};
//==================================================================================================
//
// gRPC-service answering requests about NNC property information for a given case and time step
//
//==================================================================================================
class RiaGrpcNNCPropertiesService final : public rips::NNCProperties::AsyncService, public RiaGrpcServiceInterface
{
public:
grpc::Status GetAvailableNNCProperties( grpc::ServerContext* context,
const rips::CaseRequest* request,
rips::AvailableNNCProperties* reply ) override;
grpc::Status GetNNCConnections( grpc::ServerContext* context,
const rips::CaseRequest* request,
rips::NNCConnections* reply,
RiaNNCConnectionsStateHandler* stateHandler );
std::vector<RiaGrpcCallbackInterface*> createCallbacks() override;
};