mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-20 11:48:35 -06:00
#4477 Add python methods to get NNC values (dynamic, static and generated).
Equivalent to GetDynamicNNCValues and GetStaticNNCValues in Octave. Also adds support for generated values which is currently not in Octave.
This commit is contained in:
parent
1a05430123
commit
34d3785709
@ -9,6 +9,7 @@ service NNCProperties
|
||||
{
|
||||
rpc GetAvailableNNCProperties(CaseRequest) returns (AvailableNNCProperties) {}
|
||||
rpc GetNNCConnections(CaseRequest) returns (stream NNCConnections) {}
|
||||
rpc GetNNCValues(NNCValuesRequest) returns (stream NNCValues) {}
|
||||
}
|
||||
|
||||
enum NNCPropertyType
|
||||
@ -41,3 +42,16 @@ message NNCConnections
|
||||
{
|
||||
repeated NNCConnection connections = 1;
|
||||
}
|
||||
|
||||
message NNCValuesRequest
|
||||
{
|
||||
int32 case_id = 1;
|
||||
string property_name = 2;
|
||||
NNCPropertyType property_type = 3;
|
||||
int32 time_step = 4;
|
||||
}
|
||||
|
||||
message NNCValues
|
||||
{
|
||||
repeated double values = 1;
|
||||
}
|
||||
|
@ -1013,3 +1013,81 @@ class Case(PdmObject):
|
||||
for value in chunk.connections:
|
||||
connections.append(value)
|
||||
return connections
|
||||
|
||||
def __nnc_connections_values_async(self, property_name, property_type, time_step):
|
||||
request = NNCProperties_pb2.NNCValuesRequest(case_id=self.case_id,
|
||||
property_name=property_name,
|
||||
property_type=property_type,
|
||||
time_step=time_step)
|
||||
return self.__nnc_properties_stub.GetNNCValues(request)
|
||||
|
||||
def __nnc_values_generator_to_list(self, generator):
|
||||
"""Converts a NNC values generator to a list."""
|
||||
vals = []
|
||||
for chunk in generator:
|
||||
for value in chunk.values:
|
||||
vals.append(value)
|
||||
return vals
|
||||
|
||||
def nnc_connections_static_values_async(self, property_name):
|
||||
"""Get the static NNC values. Async, so returns an iterator.
|
||||
Returns:
|
||||
An iterator to a chunk object containing an list of doubles.
|
||||
Loop through the chunks and then the values within the chunk to get values
|
||||
for all the connections. The order of the list matches the list from
|
||||
nnc_connections, i.e. the nth object of nnc_connections() refers to nth
|
||||
value in this list.
|
||||
"""
|
||||
return self.__nnc_connections_values_async(property_name, NNCProperties_pb2.NNC_STATIC, 0)
|
||||
|
||||
def nnc_connections_static_values(self, property_name):
|
||||
"""Get the static NNC values.
|
||||
Returns:
|
||||
A list of doubles. The order of the list matches the list from
|
||||
nnc_connections, i.e. the nth object of nnc_connections() refers to nth
|
||||
value in this list.
|
||||
"""
|
||||
generator = self.nnc_connections_static_values_async(property_name)
|
||||
return self.__nnc_values_generator_to_list(generator)
|
||||
|
||||
def nnc_connections_dynamic_values_async(self, property_name, time_step):
|
||||
"""Get the dynamic NNC values. Async, so returns an iterator.
|
||||
Returns:
|
||||
An iterator to a chunk object containing an list of doubles.
|
||||
Loop through the chunks and then the values within the chunk to get values
|
||||
for all the connections. The order of the list matches the list from
|
||||
nnc_connections, i.e. the nth object of nnc_connections() refers to nth
|
||||
value in this list.
|
||||
"""
|
||||
return self.__nnc_connections_values_async(property_name, NNCProperties_pb2.NNC_DYNAMIC, time_step)
|
||||
|
||||
def nnc_connections_dynamic_values(self, property_name, time_step):
|
||||
"""Get the dynamic NNC values.
|
||||
Returns:
|
||||
A list of doubles. The order of the list matches the list from
|
||||
nnc_connections, i.e. the nth object of nnc_connections() refers to nth
|
||||
value in this list.
|
||||
"""
|
||||
generator = self.nnc_connections_dynamic_values_async(property_name, time_step)
|
||||
return self.__nnc_values_generator_to_list(generator)
|
||||
|
||||
def nnc_connections_generated_values_async(self, property_name, time_step):
|
||||
"""Get the generated NNC values. Async, so returns an iterator.
|
||||
Returns:
|
||||
An iterator to a chunk object containing an list of doubles.
|
||||
Loop through the chunks and then the values within the chunk to get values
|
||||
for all the connections. The order of the list matches the list from
|
||||
nnc_connections, i.e. the nth object of nnc_connections() refers to nth
|
||||
value in this list.
|
||||
"""
|
||||
return self.__nnc_connections_values_async(property_name, NNCProperties_pb2.NNC_GENERATED, time_step)
|
||||
|
||||
def nnc_connections_generated_values(self, property_name, time_step):
|
||||
"""Get the generated NNC values.
|
||||
Returns:
|
||||
A list of doubles. The order of the list matches the list from
|
||||
nnc_connections, i.e. the nth object of nnc_connections() refers to nth
|
||||
value in this list.
|
||||
"""
|
||||
generator = self.nnc_connections_generated_values_async(property_name, time_step)
|
||||
return self.__nnc_values_generator_to_list(generator)
|
||||
|
@ -23,7 +23,7 @@ def test_10kSync(rips_instance, initialize_test):
|
||||
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)
|
||||
assert(NNCProperties_pb2.NNCPropertyType.NNC_GENERATED == properties[2].property_type)
|
||||
|
||||
nnc_connections = case.nnc_connections()
|
||||
assert(len(nnc_connections) == 84759)
|
||||
@ -33,3 +33,28 @@ def test_10kSync(rips_instance, initialize_test):
|
||||
assert(connection.cell1.j == 40)
|
||||
assert(connection.cell1.k == 14)
|
||||
assert(connection.cell_grid_index1 == 0)
|
||||
|
||||
tran_vals = case.nnc_connections_static_values("TRAN")
|
||||
assert(len(tran_vals) == len(nnc_connections))
|
||||
|
||||
for t in tran_vals:
|
||||
assert(isinstance(t, float))
|
||||
|
||||
allen_vals = case.nnc_connections_generated_values("Formation Allen", 0)
|
||||
assert(len(allen_vals) == len(nnc_connections))
|
||||
|
||||
for a in allen_vals:
|
||||
assert(isinstance(a, float))
|
||||
|
||||
def test_non_existing_dynamic_values(rips_instance, initialize_test):
|
||||
casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
case = rips_instance.project.load_case(path=casePath)
|
||||
|
||||
with pytest.raises(grpc.RpcError):
|
||||
case.nnc_connections_dynamic_values("x", 0)
|
||||
|
||||
def test_invalid_time_steps(rips_instance, initialize_test):
|
||||
casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
case = rips_instance.project.load_case(path=casePath)
|
||||
with pytest.raises(grpc.RpcError):
|
||||
case.nnc_connections_generated_values("Formation Allen", 9999)
|
||||
|
@ -121,6 +121,105 @@ grpc::Status RiaGrpcNNCPropertiesService::GetNNCConnections( grpc::ServerContext
|
||||
return stateHandler->assignReply( reply );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaNNCValuesStateHandler::RiaNNCValuesStateHandler()
|
||||
: m_request( nullptr )
|
||||
, m_eclipseCase( nullptr )
|
||||
, m_currentIdx( 0u )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaNNCValuesStateHandler::init( const rips::NNCValuesRequest* request )
|
||||
{
|
||||
CAF_ASSERT( request );
|
||||
m_request = request;
|
||||
|
||||
RimCase* rimCase = RiaGrpcServiceInterface::findCase( m_request->case_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;
|
||||
}
|
||||
|
||||
const std::vector<double>* getScalarResultByName( const RigNNCData* nncData,
|
||||
RigNNCData::NNCResultType resultType,
|
||||
const QString& propertyName,
|
||||
size_t timeStep )
|
||||
{
|
||||
if ( resultType == RigNNCData::NNC_STATIC )
|
||||
{
|
||||
return nncData->staticConnectionScalarResultByName( propertyName );
|
||||
}
|
||||
|
||||
if ( resultType == RigNNCData::NNC_DYNAMIC )
|
||||
{
|
||||
return nncData->dynamicConnectionScalarResultByName( propertyName, timeStep );
|
||||
}
|
||||
|
||||
if ( resultType == RigNNCData::NNC_GENERATED )
|
||||
{
|
||||
return nncData->generatedConnectionScalarResultByName( propertyName, timeStep );
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaNNCValuesStateHandler::assignReply( rips::NNCValues* reply )
|
||||
{
|
||||
RigMainGrid* mainGrid = m_eclipseCase->eclipseCaseData()->mainGrid();
|
||||
std::vector<RigConnection> connections = mainGrid->nncData()->connections();
|
||||
|
||||
QString propertyName = QString::fromStdString( m_request->property_name() );
|
||||
RigNNCData::NNCResultType propertyType = static_cast<RigNNCData::NNCResultType>( m_request->property_type() );
|
||||
size_t timeStep = m_request->time_step();
|
||||
|
||||
const std::vector<double>* nncValues =
|
||||
getScalarResultByName( mainGrid->nncData(), propertyType, propertyName, timeStep );
|
||||
if ( !nncValues )
|
||||
{
|
||||
return Status( grpc::NOT_FOUND, "No values found" );
|
||||
}
|
||||
|
||||
size_t connectionCount = connections.size();
|
||||
const size_t packageSize = RiaGrpcServiceInterface::numberOfDataUnitsInPackage( sizeof( double ) );
|
||||
size_t indexInPackage = 0u;
|
||||
reply->mutable_values()->Reserve( (int)packageSize );
|
||||
for ( ; indexInPackage < packageSize && m_currentIdx < connectionCount; ++indexInPackage )
|
||||
{
|
||||
reply->add_values( nncValues->at( m_currentIdx ) );
|
||||
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::GetNNCValues( grpc::ServerContext* context,
|
||||
const rips::NNCValuesRequest* request,
|
||||
rips::NNCValues* reply,
|
||||
RiaNNCValuesStateHandler* stateHandler )
|
||||
{
|
||||
return stateHandler->assignReply( reply );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -172,7 +271,15 @@ std::vector<RiaGrpcCallbackInterface*> RiaGrpcNNCPropertiesService::createCallba
|
||||
RiaNNCConnectionsStateHandler>( this,
|
||||
&Self::GetNNCConnections,
|
||||
&Self::RequestGetNNCConnections,
|
||||
new RiaNNCConnectionsStateHandler )};
|
||||
new RiaNNCConnectionsStateHandler ),
|
||||
new RiaGrpcServerToClientStreamCallback<Self,
|
||||
NNCValuesRequest,
|
||||
rips::NNCValues,
|
||||
RiaNNCValuesStateHandler>( this,
|
||||
&Self::GetNNCValues,
|
||||
&Self::RequestGetNNCValues,
|
||||
new RiaNNCValuesStateHandler )};
|
||||
|
||||
return callbacks;
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,26 @@ protected:
|
||||
size_t m_currentIdx;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// State handler for streaming of NNC values
|
||||
//
|
||||
//==================================================================================================
|
||||
class RiaNNCValuesStateHandler
|
||||
{
|
||||
typedef grpc::Status Status;
|
||||
|
||||
public:
|
||||
RiaNNCValuesStateHandler();
|
||||
grpc::Status init( const rips::NNCValuesRequest* request );
|
||||
grpc::Status assignReply( rips::NNCValues* reply );
|
||||
|
||||
protected:
|
||||
const rips::NNCValuesRequest* m_request;
|
||||
RimEclipseCase* m_eclipseCase;
|
||||
size_t m_currentIdx;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// gRPC-service answering requests about NNC property information for a given case and time step
|
||||
@ -60,6 +80,10 @@ public:
|
||||
const rips::CaseRequest* request,
|
||||
rips::NNCConnections* reply,
|
||||
RiaNNCConnectionsStateHandler* stateHandler );
|
||||
grpc::Status GetNNCValues( grpc::ServerContext* context,
|
||||
const rips::NNCValuesRequest* request,
|
||||
rips::NNCValues* reply,
|
||||
RiaNNCValuesStateHandler* stateHandler );
|
||||
|
||||
std::vector<RiaGrpcCallbackInterface*> createCallbacks() override;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user