Merge pull request #5563 from OPM/python-cell-geometry-methods-4549

Closes #4549 and #4430.
This commit is contained in:
Kristian Bendiksen
2020-02-21 12:57:25 +01:00
committed by GitHub
19 changed files with 1183 additions and 28 deletions

View File

@@ -2,6 +2,7 @@ cmake_minimum_required (VERSION 2.8.12)
set ( SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcServer.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcHelper.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCallbacks.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCallbacks.inl
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcServiceInterface.h
@@ -17,6 +18,7 @@ set ( SOURCE_GROUP_HEADER_FILES
set ( SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcServer.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcHelper.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcServiceInterface.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCaseService.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcSimulationWellService.cpp

View File

@@ -10,8 +10,11 @@ service Case
rpc GetGridCount(CaseRequest) returns(GridCount) {}
rpc GetCellCount(CellInfoRequest) returns (CellCount) {}
rpc GetCellInfoForActiveCells(CellInfoRequest) returns (stream CellInfoArray) {}
rpc GetCellCenterForActiveCells(CellInfoRequest) returns (stream CellCenters) {}
rpc GetCellCornersForActiveCells(CellInfoRequest) returns (stream CellCornersArray) {}
rpc GetCoarseningInfoArray(CaseRequest) returns (CoarseningInfoArray) {}
rpc GetTimeSteps(CaseRequest) returns (TimeStepDates) {}
rpc GetSelectedCells(CaseRequest) returns (stream SelectedCells) {}
rpc GetDaysSinceStart(CaseRequest) returns (DaysSinceStart) {}
rpc GetCaseInfo(CaseRequest) returns (CaseInfo) {}
rpc GetPdmObject(CaseRequest) returns (PdmObject) {}
@@ -123,3 +126,15 @@ message DaysSinceStart
{
repeated double day_decimals = 1;
}
message SelectedCell
{
int32 grid_index = 1;
Vec3i ijk = 2;
}
message SelectedCells
{
repeated SelectedCell cells = 1;
}

View File

@@ -17,3 +17,30 @@ message Vec3i {
int32 k = 3;
}
message Vec3d
{
double x = 1;
double y = 2;
double z = 3;
}
message CellCenters
{
repeated Vec3d centers = 1;
}
message CellCorners {
Vec3d c0 = 1;
Vec3d c1 = 2;
Vec3d c2 = 3;
Vec3d c3 = 4;
Vec3d c4 = 5;
Vec3d c5 = 6;
Vec3d c6 = 7;
Vec3d c7 = 8;
}
message CellCornersArray
{
repeated CellCorners cells = 1;
}

View File

@@ -7,7 +7,8 @@ import "Case.proto";
service Grid
{
rpc GetCellCenters(GridRequest) returns(CellCenters) {}
rpc GetCellCenters(GridRequest) returns(stream CellCenters) {}
rpc GetCellCorners(GridRequest) returns(stream CellCornersArray) {}
rpc GetDimensions(GridRequest) returns (GridDimensions) {}
}
@@ -17,19 +18,8 @@ message GridRequest
int32 grid_index = 2;
}
message Vec3d
{
double x = 1;
double y = 2;
double z = 3;
}
message CellCenters
{
repeated Vec3d centers = 1;
}
message GridDimensions
{
Vec3i dimensions = 1;
}

View File

@@ -9,6 +9,7 @@ service Properties
{
rpc GetAvailableProperties(AvailablePropertiesRequest) returns (AvailableProperties) {}
rpc GetActiveCellProperty(PropertyRequest) returns (stream PropertyChunk) {}
rpc GetSelectedCellProperty(PropertyRequest) returns (stream PropertyChunk) {}
rpc GetGridProperty(PropertyRequest) returns (stream PropertyChunk) {}
rpc SetActiveCellProperty(stream PropertyInputChunk) returns (ClientToServerStreamReply) {}
rpc SetGridProperty(stream PropertyInputChunk) returns (ClientToServerStreamReply) {}

View File

@@ -1,6 +1,6 @@
###################################################################################
# This example will connect to ResInsight, retrieve a list of cases and print info
#
#
###################################################################################
# Import the ResInsight Processing Server Module
@@ -19,11 +19,16 @@ if resinsight is not None:
print("Case type: " + case.type)
print("Case grid path: " + case.grid_path())
print("Case reservoir bounding box:", case.reservoir_boundingbox())
timesteps = case.time_steps()
for t in timesteps:
print("Year: " + str(t.year))
print("Month: " + str(t.month))
coarsening_info = case.coarsening_info()
if coarsening_info:
print("Coarsening information:")
for c in coarsening_info:
print("[{}, {}, {}] - [{}, {}, {}]".format(c.min.x, c.min.y, c.min.z,
c.max.x, c.max.y, c.max.z))

View File

@@ -0,0 +1,50 @@
############################################################################
# This example prints center and corners for the currently selected cells
# in ResInsight
############################################################################
import rips
resinsight = rips.Instance.find()
if resinsight is not None:
cases = resinsight.project.cases()
print ("Got " + str(len(cases)) + " cases: ")
for case in cases:
print(case.name)
cells = case.selected_cells()
print("Found " + str(len(cells)) + " selected cells")
time_step_info = case.time_steps()
for (idx, cell) in enumerate(cells):
print("Selected cell: [{}, {}, {}] grid: {}".format(cell.ijk.i+1, cell.ijk.j+1, cell.ijk.k+1, cell.grid_index))
# Get the grid and dimensions
grid = case.grids()[cell.grid_index]
dimensions = grid.dimensions()
# Map ijk to cell index
cell_index = dimensions.i * dimensions.j * cell.ijk.k + dimensions.i * cell.ijk.j + cell.ijk.i
# Print the cell center
cell_centers = grid.cell_centers()
cell_center = cell_centers[cell_index]
print("Cell center: [{}, {}, {}]".format(cell_center.x, cell_center.y, cell_center.z))
# Print the cell corners
cell_corners = grid.cell_corners()[cell_index]
print("Cell corners:")
print("c0:\n" + str(cell_corners.c0))
print("c1:\n" + str(cell_corners.c1))
print("c2:\n" + str(cell_corners.c2))
print("c3:\n" + str(cell_corners.c3))
print("c4:\n" + str(cell_corners.c4))
print("c5:\n" + str(cell_corners.c5))
print("c6:\n" + str(cell_corners.c6))
print("c7:\n" + str(cell_corners.c7))
for (tidx, timestep) in enumerate(time_step_info):
# Read the full SOIL result for time step
soil_results = case.selected_cell_property('DYNAMIC_NATIVE', 'SOIL', tidx)
print("SOIL: {} ({}.{}.{})".format(soil_results[idx], timestep.year, timestep.month, timestep.day))

View File

@@ -585,6 +585,61 @@ class Case(PdmObject):
all_values.append(value)
return all_values
def selected_cell_property_async(self,
property_type,
property_name,
time_step,
porosity_model="MATRIX_MODEL"):
"""Get a cell property for all selected cells. Async, so returns an iterator
Arguments:
property_type(str): string enum. See available()
property_name(str): name of an Eclipse property
time_step(int): the time step for which to get the property for
porosity_model(str): string enum. See available()
Returns:
An iterator to a chunk object containing an array of double values
Loop through the chunks and then the values within the chunk to get all values.
"""
property_type_enum = Properties_pb2.PropertyType.Value(property_type)
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
request = Properties_pb2.PropertyRequest(
case_request=self.__request,
property_type=property_type_enum,
property_name=property_name,
time_step=time_step,
porosity_model=porosity_model_enum,
)
for chunk in self.__properties_stub.GetSelectedCellProperty(request):
yield chunk
def selected_cell_property(self,
property_type,
property_name,
time_step,
porosity_model="MATRIX_MODEL"):
"""Get a cell property for all selected cells. Sync, so returns a list
Arguments:
property_type(str): string enum. See available()
property_name(str): name of an Eclipse property
time_step(int): the time step for which to get the property for
porosity_model(str): string enum. See available()
Returns:
A list containing double values
Loop through the chunks and then the values within the chunk to get all values.
"""
all_values = []
generator = self.selected_cell_property_async(property_type,
property_name, time_step,
porosity_model)
for chunk in generator:
for value in chunk.values:
all_values.append(value)
return all_values
def grid_property_async(
self,
property_type,
@@ -820,3 +875,108 @@ class Case(PdmObject):
for pdm_object in pdm_objects:
wells.append(SimulationWell(pdm_object.get_value("WellName"), self.case_id, pdm_object))
return wells
def active_cell_centers_async(
self,
porosity_model="MATRIX_MODEL",
):
"""Get a cell centers for all active cells. Async, so returns an iterator
Arguments:
porosity_model(str): string enum. See available()
Returns:
An iterator to a chunk object containing an array of Vec3d values.
Loop through the chunks and then the values within the chunk to get all values.
"""
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
request = Case_pb2.CellInfoRequest(case_request=self.__request,
porosity_model=porosity_model_enum)
return self.__case_stub.GetCellCenterForActiveCells(request)
def active_cell_centers(
self,
porosity_model="MATRIX_MODEL",
):
"""Get a cell centers for all active cells. Synchronous, so returns a list.
Arguments:
porosity_model(str): string enum. See available()
Returns:
A list of Vec3d
"""
cell_centers = []
generator = self.active_cell_centers_async(porosity_model)
for chunk in generator:
for value in chunk.centers:
cell_centers.append(value)
return cell_centers
def active_cell_corners_async(
self,
porosity_model="MATRIX_MODEL",
):
"""Get a cell corners for all active cells. Async, so returns an iterator
Arguments:
porosity_model(str): string enum. See available()
Returns:
An iterator to a chunk object containing an array of CellCorners (which is eight Vec3d values).
Loop through the chunks and then the values within the chunk to get all values.
"""
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
request = Case_pb2.CellInfoRequest(case_request=self.__request,
porosity_model=porosity_model_enum)
return self.__case_stub.GetCellCornersForActiveCells(request)
def active_cell_corners(
self,
porosity_model="MATRIX_MODEL",
):
"""Get a cell corners for all active cells. Synchronous, so returns a list.
Arguments:
porosity_model(str): string enum. See available()
Returns:
A list of CellCorners
"""
cell_corners = []
generator = self.active_cell_corners_async(porosity_model)
for chunk in generator:
for value in chunk.cells:
cell_corners.append(value)
return cell_corners
def selected_cells_async(self):
"""Get the selected cells. Async, so returns an iterator.
Returns:
An iterator to a chunk object containing an array of cells.
Loop through the chunks and then the cells within the chunk to get all cells.
"""
return self.__case_stub.GetSelectedCells(self.__request)
def selected_cells(self):
"""Get the selected cells. Synchronous, so returns a list.
Returns:
A list of Cells.
"""
cells = []
generator = self.selected_cells_async()
for chunk in generator:
for value in chunk.cells:
cells.append(value)
return cells
def coarsening_info(self):
"""Get a coarsening information for all grids in the case.
Returns:
A list of CoarseningInfo objects with two Vec3i min and max objects
for each entry.
"""
return self.__case_stub.GetCoarseningInfoArray(self.__request).data

View File

@@ -13,7 +13,7 @@ import rips.generated.Grid_pb2_grpc as Grid_pb2_grpc
class Grid:
"""Grid Information. Not meant to be constructed separately
Create Grid objects using mathods on Case: Grid() and Grids()
Create Grid objects using methods on Case: Grid() and Grids()
"""
def __init__(self, index, case, channel):
self.__channel = channel
@@ -32,3 +32,57 @@ class Grid:
return self.__stub.GetDimensions(
Grid_pb2.GridRequest(case_request=case_request,
grid_index=self.index)).dimensions
def cell_centers_async(self):
"""The cells center for all cells in given grid async.
Returns:
Iterator to a list of Vec3d: class with double attributes x, y, x giving cell centers
"""
case_request = Case_pb2.CaseRequest(id=self.case.case_id)
chunks = self.__stub.GetCellCenters(
Grid_pb2.GridRequest(case_request=case_request,
grid_index=self.index))
for chunk in chunks:
yield chunk
def cell_centers(self):
"""The cell center for all cells in given grid
Returns:
List of Vec3d: class with double attributes x, y, x giving cell centers
"""
centers = []
chunks = self.cell_centers_async()
for chunk in chunks:
for center in chunk.centers:
centers.append(center)
return centers
def cell_corners_async(self):
"""The cell corners for all cells in given grid, async.
Returns:
iterator to a list of CellCorners: a class with Vec3d for each corner (c0, c1.., c7)
"""
case_request = Case_pb2.CaseRequest(id=self.case.case_id)
chunks = self.__stub.GetCellCorners(
Grid_pb2.GridRequest(case_request=case_request,
grid_index=self.index))
for chunk in chunks:
yield chunk
def cell_corners(self):
"""The cell corners for all cells in given grid
Returns:
list of CellCorners: a class with Vec3d for each corner (c0, c1.., c7)
"""
corners = []
chunks = self.cell_corners_async()
for chunk in chunks:
for center in chunk.cells:
corners.append(center)
return corners

View File

@@ -56,6 +56,17 @@ def test_MultipleCases(rips_instance, initialize_test):
for i, case_name in enumerate(case_names):
assert(case_name == cases[i].name)
def get_cell_index_with_ijk(cell_info, i, j, k):
for (idx, cell) in enumerate(cell_info):
if cell.local_ijk.i == i and cell.local_ijk.j == j and cell.local_ijk.k == k:
return idx
return -1
def check_corner(actual, expected):
assert(math.isclose(actual.x, expected[0], abs_tol=0.1))
assert(math.isclose(actual.y, expected[1], abs_tol=0.1))
assert(math.isclose(actual.z, expected[2], abs_tol=0.1))
def test_10k(rips_instance, initialize_test):
case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
case = rips_instance.project.load_case(path=case_path)
@@ -67,6 +78,44 @@ def test_10k(rips_instance, initialize_test):
assert(len(time_steps) == 9)
days_since_start = case.days_since_start()
assert(len(days_since_start) == 9)
cell_info = case.cell_info_for_active_cells()
assert(len(cell_info) == cell_count_info.active_cell_count)
# Check an active cell (found in resinsight ui)
cell_index = get_cell_index_with_ijk(cell_info, 23, 44, 19)
assert(cell_index != -1)
cell_centers = case.active_cell_centers()
assert(len(cell_centers) == cell_count_info.active_cell_count)
# Check the cell center for the specific cell
assert(math.isclose(3627.17, cell_centers[cell_index].x, abs_tol=0.1))
assert(math.isclose(5209.75, cell_centers[cell_index].y, abs_tol=0.1))
assert(math.isclose(4179.6, cell_centers[cell_index].z, abs_tol=0.1))
cell_corners = case.active_cell_corners()
assert(len(cell_corners) == cell_count_info.active_cell_count)
# Expected values from ResInsight UI
expected_corners = [[ 3565.22, 5179.02, 4177.18],
[ 3655.67, 5145.34, 4176.63],
[ 3690.07, 5240.69, 4180.02],
[ 3599.87, 5275.16, 4179.32],
[ 3564.13, 5178.61, 4179.75],
[ 3654.78, 5144.79, 4179.23],
[ 3688.99, 5239.88, 4182.7],
[ 3598.62, 5274.48, 4181.96]]
check_corner(cell_corners[cell_index].c0, expected_corners[0])
check_corner(cell_corners[cell_index].c1, expected_corners[1])
check_corner(cell_corners[cell_index].c2, expected_corners[2])
check_corner(cell_corners[cell_index].c3, expected_corners[3])
check_corner(cell_corners[cell_index].c4, expected_corners[4])
check_corner(cell_corners[cell_index].c5, expected_corners[5])
check_corner(cell_corners[cell_index].c6, expected_corners[6])
check_corner(cell_corners[cell_index].c7, expected_corners[7])
# No coarsening info for this case
coarsening_info = case.coarsening_info()
assert(len(coarsening_info) == 0)
def test_PdmObject(rips_instance, initialize_test):
case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
@@ -127,3 +176,14 @@ def test_exportFlowCharacteristics(rips_instance, initialize_test):
file_name = tmpdirname + "/exportFlowChar.txt"
case.export_flow_characteristics(time_steps=8, producers=[], injectors = "I01", file_name = file_name)
def test_selected_cells(rips_instance, initialize_test):
case = rips_instance.project.load_case(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID")
assert(case.name == "TEST10K_FLT_LGR_NNC")
selected_cells = case.selected_cells()
assert(len(selected_cells) == 0)
time_step_info = case.time_steps()
for (tidx, timestep) in enumerate(time_step_info):
# Try to read for SOIL the time step (will be empty since nothing is selected)
soil_results = case.selected_cell_property('DYNAMIC_NATIVE', 'SOIL', tidx)
assert(len(soil_results) == 0)

View File

@@ -1,11 +1,17 @@
import sys
import os
import math
sys.path.insert(1, os.path.join(sys.path[0], '../../'))
import rips
import dataroot
def check_corner(actual, expected):
assert(math.isclose(actual.x, expected[0], abs_tol=0.1))
assert(math.isclose(actual.y, expected[1], abs_tol=0.1))
assert(math.isclose(actual.z, expected[2], abs_tol=0.1))
def test_10k(rips_instance, initialize_test):
casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
case = rips_instance.project.load_case(path=casePath)
@@ -15,3 +21,33 @@ def test_10k(rips_instance, initialize_test):
assert(dimensions.i == 90)
assert(dimensions.j == 96)
assert(dimensions.k == 36)
cell_centers = grid.cell_centers()
assert(len(cell_centers) == (dimensions.i * dimensions.j * dimensions.k))
# Test a specific cell (results from ResInsight UI)
cell_index = 168143
assert(math.isclose(3627.17, cell_centers[cell_index].x, abs_tol=0.1))
assert(math.isclose(5209.75, cell_centers[cell_index].y, abs_tol=0.1))
assert(math.isclose(4179.6, cell_centers[cell_index].z, abs_tol=0.1))
cell_corners = grid.cell_corners()
assert(len(cell_corners) == (dimensions.i * dimensions.j * dimensions.k))
# Expected values from ResInsight UI
expected_corners = [[ 3565.22, 5179.02, 4177.18],
[ 3655.67, 5145.34, 4176.63],
[ 3690.07, 5240.69, 4180.02],
[ 3599.87, 5275.16, 4179.32],
[ 3564.13, 5178.61, 4179.75],
[ 3654.78, 5144.79, 4179.23],
[ 3688.99, 5239.88, 4182.7],
[ 3598.62, 5274.48, 4181.96]]
check_corner(cell_corners[cell_index].c0, expected_corners[0])
check_corner(cell_corners[cell_index].c1, expected_corners[1])
check_corner(cell_corners[cell_index].c2, expected_corners[2])
check_corner(cell_corners[cell_index].c3, expected_corners[3])
check_corner(cell_corners[cell_index].c4, expected_corners[4])
check_corner(cell_corners[cell_index].c5, expected_corners[5])
check_corner(cell_corners[cell_index].c6, expected_corners[6])
check_corner(cell_corners[cell_index].c7, expected_corners[7])

View File

@@ -16,7 +16,9 @@
//
//////////////////////////////////////////////////////////////////////////////////
#include "RiaGrpcCaseService.h"
#include "RiaGrpcCallbacks.h"
#include "RiaGrpcHelper.h"
#include "RiaSocketTools.h"
#include "RigActiveCellInfo.h"
@@ -26,9 +28,9 @@
#include "RigMainGrid.h"
#include "RimEclipseCase.h"
#include "RimGeoMechCase.h"
#include "RimEclipseResultDefinition.h"
#include <string.h> // memcpy
#include "Riu3dSelectionManager.h"
using namespace rips;
@@ -216,6 +218,144 @@ grpc::Status RiaActiveCellInfoStateHandler::assignReply( rips::CellInfoArray* re
return Status( grpc::OUT_OF_RANGE, "We've reached the end. This is not an error but means transmission is finished" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaActiveCellInfoStateHandler::assignNextActiveCellCenter( rips::Vec3d* cellCenter )
{
const std::vector<RigCell>& reservoirCells = m_eclipseCase->eclipseCaseData()->mainGrid()->globalCellArray();
while ( m_currentCellIdx < reservoirCells.size() )
{
size_t cellIdxToTry = m_currentCellIdx++;
if ( m_activeCellInfo->isActive( cellIdxToTry ) )
{
assignCellCenter( cellCenter, reservoirCells, cellIdxToTry );
return grpc::Status::OK;
}
}
return Status( grpc::OUT_OF_RANGE, "We've reached the end. This is not an error but means transmission is finished" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaActiveCellInfoStateHandler::assignCellCenter( rips::Vec3d* cellCenter,
const std::vector<RigCell>& reservoirCells,
size_t cellIdx )
{
cvf::Vec3d center = reservoirCells[cellIdx].center();
RiaGrpcHelper::convertVec3dToPositiveDepth( &center );
cellCenter->set_x( center.x() );
cellCenter->set_y( center.y() );
cellCenter->set_z( center.z() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaActiveCellInfoStateHandler::assignCellCentersReply( rips::CellCenters* reply )
{
const size_t packageSize = RiaGrpcServiceInterface::numberOfDataUnitsInPackage( sizeof( rips::Vec3d ) );
size_t indexInPackage = 0u;
reply->mutable_centers()->Reserve( (int)packageSize );
for ( ; indexInPackage < packageSize && m_currentCellIdx < m_activeCellInfo->reservoirCellCount(); ++indexInPackage )
{
rips::Vec3d singleCellCenter;
grpc::Status singleCellCenterStatus = assignNextActiveCellCenter( &singleCellCenter );
if ( singleCellCenterStatus.ok() )
{
rips::Vec3d* allocCellCenter = reply->add_centers();
*allocCellCenter = singleCellCenter;
}
else
{
break;
}
}
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" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Status RiaActiveCellInfoStateHandler::assignNextActiveCellCorners( rips::CellCorners* cellCorners )
{
const std::vector<RigCell>& reservoirCells = m_eclipseCase->eclipseCaseData()->mainGrid()->globalCellArray();
while ( m_currentCellIdx < reservoirCells.size() )
{
size_t cellIdxToTry = m_currentCellIdx++;
if ( m_activeCellInfo->isActive( cellIdxToTry ) )
{
assignCellCorners( cellCorners, reservoirCells, cellIdxToTry );
return grpc::Status::OK;
}
}
return Status( grpc::OUT_OF_RANGE, "We've reached the end. This is not an error but means transmission is finished" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaActiveCellInfoStateHandler::assignCellCorners( rips::CellCorners* corners,
const std::vector<RigCell>& reservoirCells,
size_t cellIdx )
{
cvf::Vec3d cornerVerts[8];
RigGridBase* grid = m_eclipseCase->eclipseCaseData()->mainGrid();
grid->cellCornerVertices( cellIdx, cornerVerts );
for ( cvf::Vec3d& corner : cornerVerts )
{
RiaGrpcHelper::convertVec3dToPositiveDepth( &corner );
}
RiaGrpcHelper::setCornerValues( corners->mutable_c0(), cornerVerts[0] );
RiaGrpcHelper::setCornerValues( corners->mutable_c1(), cornerVerts[1] );
RiaGrpcHelper::setCornerValues( corners->mutable_c2(), cornerVerts[2] );
RiaGrpcHelper::setCornerValues( corners->mutable_c3(), cornerVerts[3] );
RiaGrpcHelper::setCornerValues( corners->mutable_c4(), cornerVerts[4] );
RiaGrpcHelper::setCornerValues( corners->mutable_c5(), cornerVerts[5] );
RiaGrpcHelper::setCornerValues( corners->mutable_c6(), cornerVerts[6] );
RiaGrpcHelper::setCornerValues( corners->mutable_c7(), cornerVerts[7] );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Status RiaActiveCellInfoStateHandler::assignCellCornersReply( rips::CellCornersArray* reply )
{
const size_t packageSize = RiaGrpcServiceInterface::numberOfDataUnitsInPackage( sizeof( rips::CellCorners ) );
size_t indexInPackage = 0u;
reply->mutable_cells()->Reserve( (int)packageSize );
for ( ; indexInPackage < packageSize && m_currentCellIdx < m_activeCellInfo->reservoirCellCount(); ++indexInPackage )
{
rips::CellCorners singleCellCorners;
grpc::Status singleCellCornersStatus = assignNextActiveCellCorners( &singleCellCorners );
if ( singleCellCornersStatus.ok() )
{
rips::CellCorners* allocCellCorners = reply->add_cells();
*allocCellCorners = singleCellCorners;
}
else
{
break;
}
}
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" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -367,6 +507,157 @@ grpc::Status RiaGrpcCaseService::GetCellInfoForActiveCells( grpc::ServerContext*
return stateHandler->assignReply( reply );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcCaseService::GetCellCenterForActiveCells( grpc::ServerContext* context,
const rips::CellInfoRequest* request,
rips::CellCenters* reply,
RiaActiveCellInfoStateHandler* stateHandler )
{
return stateHandler->assignCellCentersReply( reply );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcCaseService::GetCellCornersForActiveCells( grpc::ServerContext* context,
const rips::CellInfoRequest* request,
rips::CellCornersArray* reply,
RiaActiveCellInfoStateHandler* stateHandler )
{
return stateHandler->assignCellCornersReply( reply );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaSelectedCellsStateHandler::RiaSelectedCellsStateHandler()
: m_request( nullptr )
, m_eclipseCase( nullptr )
, m_currentItem( 0u )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Status RiaSelectedCellsStateHandler::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 )
{
return grpc::Status( grpc::NOT_FOUND, "Eclipse Case not found" );
}
if ( !m_eclipseCase->eclipseCaseData() || !m_eclipseCase->eclipseCaseData()->mainGrid() )
{
return grpc::Status( grpc::NOT_FOUND, "Eclipse Case Data not found" );
}
return grpc::Status::OK;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Status RiaSelectedCellsStateHandler::assignNextSelectedCell( rips::SelectedCell* cell,
const std::vector<RiuEclipseSelectionItem*>& items )
{
while ( m_currentItem < items.size() )
{
size_t itemToTry = m_currentItem++;
const RiuEclipseSelectionItem* item = items[itemToTry];
CVF_ASSERT( item->type() == RiuSelectionItem::ECLIPSE_SELECTION_OBJECT );
assignSelectedCell( cell, item );
return grpc::Status::OK;
}
return Status( grpc::OUT_OF_RANGE, "We've reached the end. This is not an error but means transmission is finished" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaSelectedCellsStateHandler::assignSelectedCell( rips::SelectedCell* cell, const RiuEclipseSelectionItem* item )
{
CVF_ASSERT( item->type() == RiuSelectionItem::ECLIPSE_SELECTION_OBJECT );
size_t i = -1;
size_t j = -1;
size_t k = -1;
item->m_resultDefinition->eclipseCase()
->eclipseCaseData()
->grid( item->m_gridIndex )
->ijkFromCellIndex( item->m_gridLocalCellIndex, &i, &j, &k );
cell->set_grid_index( item->m_gridIndex );
rips::Vec3i* ijk = new rips::Vec3i;
ijk->set_i( (int)i );
ijk->set_j( (int)j );
ijk->set_k( (int)k );
cell->set_allocated_ijk( ijk );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaSelectedCellsStateHandler::assignReply( rips::SelectedCells* reply )
{
std::vector<RiuSelectionItem*> items;
Riu3dSelectionManager::instance()->selectedItems( items );
// Only eclipse cases are currently supported. Also filter by case.
std::vector<RiuEclipseSelectionItem*> eclipseItems;
for ( auto item : items )
{
RiuEclipseSelectionItem* eclipseItem = dynamic_cast<RiuEclipseSelectionItem*>( item );
if ( eclipseItem && eclipseItem->m_resultDefinition->eclipseCase()->caseId == m_request->id() )
{
eclipseItems.push_back( eclipseItem );
}
}
const size_t packageSize = RiaGrpcServiceInterface::numberOfDataUnitsInPackage( sizeof( rips::SelectedCell ) );
size_t indexInPackage = 0u;
reply->mutable_cells()->Reserve( (int)packageSize );
for ( ; indexInPackage < packageSize && m_currentItem < eclipseItems.size(); ++indexInPackage )
{
rips::SelectedCell singleSelectedCell;
grpc::Status singleSelectedCellStatus = assignNextSelectedCell( &singleSelectedCell, eclipseItems );
if ( singleSelectedCellStatus.ok() )
{
rips::SelectedCell* allocSelectedCell = reply->add_cells();
*allocSelectedCell = singleSelectedCell;
}
else
{
break;
}
}
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 RiaGrpcCaseService::GetSelectedCells( grpc::ServerContext* context,
const rips::CaseRequest* request,
rips::SelectedCells* reply,
RiaSelectedCellsStateHandler* stateHandler )
{
return stateHandler->assignReply( reply );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -389,6 +680,46 @@ grpc::Status RiaGrpcCaseService::GetReservoirBoundingBox( grpc::ServerContext*
return Status( grpc::NOT_FOUND, "Case not found" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcCaseService::GetCoarseningInfoArray( grpc::ServerContext* context,
const rips::CaseRequest* request,
rips::CoarseningInfoArray* reply )
{
RimEclipseCase* rimCase = dynamic_cast<RimEclipseCase*>( findCase( request->id() ) );
if ( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() )
{
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 );
rips::CoarseningInfo* coarseningInfo = reply->add_data();
rips::Vec3i* min = new rips::Vec3i;
min->set_i( (int)i1 );
min->set_j( (int)j1 );
min->set_k( (int)k1 );
coarseningInfo->set_allocated_min( min );
rips::Vec3i* max = new rips::Vec3i;
max->set_i( (int)i2 );
max->set_j( (int)j2 );
max->set_k( (int)k2 );
coarseningInfo->set_allocated_max( max );
}
}
return Status::OK;
}
return Status( grpc::NOT_FOUND, "Case not found" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -411,9 +742,34 @@ std::vector<RiaGrpcCallbackInterface*> RiaGrpcCaseService::createCallbacks()
&Self::GetCellInfoForActiveCells,
&Self::RequestGetCellInfoForActiveCells,
new RiaActiveCellInfoStateHandler ),
new RiaGrpcServerToClientStreamCallback<Self,
CellInfoRequest,
CellCenters,
RiaActiveCellInfoStateHandler>( this,
&Self::GetCellCenterForActiveCells,
&Self::RequestGetCellCenterForActiveCells,
new RiaActiveCellInfoStateHandler ),
new RiaGrpcServerToClientStreamCallback<Self,
CellInfoRequest,
CellCornersArray,
RiaActiveCellInfoStateHandler>( this,
&Self::GetCellCornersForActiveCells,
&Self::RequestGetCellCornersForActiveCells,
new RiaActiveCellInfoStateHandler ),
new RiaGrpcServerToClientStreamCallback<Self,
CaseRequest,
SelectedCells,
RiaSelectedCellsStateHandler>( this,
&Self::GetSelectedCells,
&Self::RequestGetSelectedCells,
new RiaSelectedCellsStateHandler ),
new RiaGrpcUnaryCallback<Self, CaseRequest, BoundingBox>( this,
&Self::GetReservoirBoundingBox,
&Self::RequestGetReservoirBoundingBox )};
&Self::RequestGetReservoirBoundingBox ),
new RiaGrpcUnaryCallback<Self, CaseRequest, CoarseningInfoArray>( this,
&Self::GetCoarseningInfoArray,
&Self::RequestGetCoarseningInfoArray )};
}
static bool RiaGrpcCaseService_init =

View File

@@ -34,6 +34,7 @@ class RiaGrpcCallbackInterface;
class RigCell;
class RigActiveCellInfo;
class RimEclipseCase;
class RiuEclipseSelectionItem;
//==================================================================================================
//
@@ -48,11 +49,24 @@ public:
RiaActiveCellInfoStateHandler();
Status init( const rips::CellInfoRequest* request );
RigActiveCellInfo* activeCellInfo() const;
const std::vector<RigCell>& reservoirCells() const;
// For cell info:
Status assignNextActiveCellInfoData( rips::CellInfo* cellInfo );
void assignCellInfoData( rips::CellInfo* cellInfo, const std::vector<RigCell>& reservoirCells, size_t cellIdx );
Status assignReply( rips::CellInfoArray* reply );
RigActiveCellInfo* activeCellInfo() const;
const std::vector<RigCell>& reservoirCells() const;
// For cell centers:
Status assignNextActiveCellCenter( rips::Vec3d* cellCenter );
void assignCellCenter( rips::Vec3d* cellCenter, const std::vector<RigCell>& reservoirCells, size_t cellIdx );
Status assignCellCentersReply( rips::CellCenters* reply );
// For cell corners:
Status assignNextActiveCellCorners( rips::CellCorners* cellCorners );
void assignCellCorners( rips::CellCorners* cellCorners, const std::vector<RigCell>& reservoirCells, size_t cellIdx );
Status assignCellCornersReply( rips::CellCornersArray* reply );
protected:
const rips::CellInfoRequest* m_request;
@@ -63,6 +77,29 @@ protected:
size_t m_currentCellIdx;
};
//==================================================================================================
//
// State handler for streaming of selected cells
//
//==================================================================================================
class RiaSelectedCellsStateHandler
{
typedef grpc::Status Status;
public:
RiaSelectedCellsStateHandler();
Status init( const rips::CaseRequest* request );
Status assignReply( rips::SelectedCells* reply );
void assignSelectedCell( rips::SelectedCell* cell, const RiuEclipseSelectionItem* item );
Status assignNextSelectedCell( rips::SelectedCell* cell, const std::vector<RiuEclipseSelectionItem*>& items );
protected:
const rips::CaseRequest* m_request;
RimEclipseCase* m_eclipseCase;
size_t m_currentItem;
};
//==================================================================================================
//
// gRPC-service answering requests about grid information for a given case
@@ -89,9 +126,24 @@ public:
const rips::CellInfoRequest* request,
rips::CellInfoArray* reply,
RiaActiveCellInfoStateHandler* stateHandler );
grpc::Status GetCellCenterForActiveCells( grpc::ServerContext* context,
const rips::CellInfoRequest* request,
rips::CellCenters* reply,
RiaActiveCellInfoStateHandler* stateHandler );
grpc::Status GetCellCornersForActiveCells( grpc::ServerContext* context,
const rips::CellInfoRequest* request,
rips::CellCornersArray* reply,
RiaActiveCellInfoStateHandler* stateHandler );
grpc::Status GetSelectedCells( grpc::ServerContext* context,
const rips::CaseRequest* request,
rips::SelectedCells* reply,
RiaSelectedCellsStateHandler* stateHandler );
grpc::Status GetReservoirBoundingBox( grpc::ServerContext* context,
const rips::CaseRequest* request,
rips::BoundingBox* reply );
grpc::Status GetCoarseningInfoArray( grpc::ServerContext* context,
const rips::CaseRequest* request,
rips::CoarseningInfoArray* reply );
std::vector<RiaGrpcCallbackInterface*> createCallbacks() override;
};

View File

@@ -18,7 +18,9 @@
#include "RiaGrpcGridService.h"
#include "RiaGrpcCallbacks.h"
#include "RiaGrpcHelper.h"
#include "RigCell.h"
#include "RigEclipseCaseData.h"
#include "RigMainGrid.h"
@@ -29,8 +31,111 @@ using namespace rips;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status
RiaGrpcGridService::GetDimensions( grpc::ServerContext* context, const GridRequest* request, GridDimensions* reply )
RiaCellCenterStateHandler::RiaCellCenterStateHandler()
: m_request( nullptr )
, m_eclipseCase( nullptr )
, m_grid( nullptr )
, m_currentCellIdx( 0u )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaCellCenterStateHandler::init( const rips::GridRequest* request )
{
CAF_ASSERT( request );
m_request = request;
RimCase* rimCase = RiaGrpcServiceInterface::findCase( m_request->case_request().id() );
m_eclipseCase = dynamic_cast<RimEclipseCase*>( rimCase );
if ( !m_eclipseCase )
{
return grpc::Status( grpc::NOT_FOUND, "Eclipse Case not found" );
}
size_t gridIndex = (size_t)request->grid_index();
if ( gridIndex >= m_eclipseCase->mainGrid()->gridCount() )
{
return grpc::Status( grpc::NOT_FOUND, "Grid not found" );
}
m_grid = m_eclipseCase->mainGrid()->gridByIndex( gridIndex );
return grpc::Status::OK;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaCellCenterStateHandler::assignReply( rips::CellCenters* reply )
{
const size_t packageSize = RiaGrpcServiceInterface::numberOfDataUnitsInPackage( sizeof( rips::Vec3d ) );
size_t indexInPackage = 0u;
reply->mutable_centers()->Reserve( (int)packageSize );
for ( ; indexInPackage < packageSize && m_currentCellIdx < m_grid->cellCount(); ++indexInPackage )
{
cvf::Vec3d center = m_grid->cell( m_currentCellIdx ).center();
RiaGrpcHelper::convertVec3dToPositiveDepth( &center );
Vec3d* cellCenter = reply->add_centers();
cellCenter->set_x( center.x() );
cellCenter->set_y( center.y() );
cellCenter->set_z( center.z() );
m_currentCellIdx++;
}
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 RiaCellCenterStateHandler::assignCornersReply( rips::CellCornersArray* reply )
{
const size_t packageSize = RiaGrpcServiceInterface::numberOfDataUnitsInPackage( sizeof( rips::CellCorners ) );
size_t indexInPackage = 0u;
reply->mutable_cells()->Reserve( (int)packageSize );
cvf::Vec3d cornerVerts[8];
for ( ; indexInPackage < packageSize && m_currentCellIdx < m_grid->cellCount(); ++indexInPackage )
{
m_grid->cellCornerVertices( m_currentCellIdx, cornerVerts );
for ( cvf::Vec3d& corner : cornerVerts )
{
RiaGrpcHelper::convertVec3dToPositiveDepth( &corner );
}
rips::CellCorners* corners = reply->add_cells();
RiaGrpcHelper::setCornerValues( corners->mutable_c0(), cornerVerts[0] );
RiaGrpcHelper::setCornerValues( corners->mutable_c1(), cornerVerts[1] );
RiaGrpcHelper::setCornerValues( corners->mutable_c2(), cornerVerts[2] );
RiaGrpcHelper::setCornerValues( corners->mutable_c3(), cornerVerts[3] );
RiaGrpcHelper::setCornerValues( corners->mutable_c4(), cornerVerts[4] );
RiaGrpcHelper::setCornerValues( corners->mutable_c5(), cornerVerts[5] );
RiaGrpcHelper::setCornerValues( corners->mutable_c6(), cornerVerts[6] );
RiaGrpcHelper::setCornerValues( corners->mutable_c7(), cornerVerts[7] );
m_currentCellIdx++;
}
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 RiaGrpcGridService::GetDimensions( grpc::ServerContext* context,
const rips::GridRequest* request,
rips::GridDimensions* reply )
{
RimCase* rimCase = findCase( request->case_request().id() );
@@ -55,6 +160,28 @@ grpc::Status
return grpc::Status( grpc::NOT_FOUND, "Eclipse Case not found" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcGridService::GetCellCenters( grpc::ServerContext* context,
const rips::GridRequest* request,
rips::CellCenters* reply,
RiaCellCenterStateHandler* stateHandler )
{
return stateHandler->assignReply( reply );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcGridService::GetCellCorners( grpc::ServerContext* context,
const rips::GridRequest* request,
rips::CellCornersArray* reply,
RiaCellCenterStateHandler* stateHandler )
{
return stateHandler->assignCornersReply( reply );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -62,9 +189,19 @@ std::vector<RiaGrpcCallbackInterface*> RiaGrpcGridService::createCallbacks()
{
typedef RiaGrpcGridService Self;
return {new RiaGrpcUnaryCallback<Self, GridRequest, GridDimensions>( this,
&Self::GetDimensions,
&Self::RequestGetDimensions )};
return {
new RiaGrpcServerToClientStreamCallback<Self, GridRequest, CellCenters, RiaCellCenterStateHandler>( this,
&Self::GetCellCenters,
&Self::RequestGetCellCenters,
new RiaCellCenterStateHandler ),
new RiaGrpcServerToClientStreamCallback<Self, GridRequest, CellCornersArray, RiaCellCenterStateHandler>( this,
&Self::GetCellCorners,
&Self::RequestGetCellCorners,
new RiaCellCenterStateHandler ),
new RiaGrpcUnaryCallback<Self, GridRequest, GridDimensions>( this, &Self::GetDimensions, &Self::RequestGetDimensions )};
}
static bool RiaGrpcGridService_init =

View File

@@ -21,9 +21,53 @@
#include "RiaGrpcServiceInterface.h"
#include <vector>
class RigGridBase;
class RimEclipseCase;
namespace rips
{
class GridRequest;
class CellCenters;
class GridDimensions;
}; // namespace rips
//==================================================================================================
//
// State handler for streaming of active cell info
//
//==================================================================================================
class RiaCellCenterStateHandler
{
typedef grpc::Status Status;
public:
RiaCellCenterStateHandler();
grpc::Status init( const rips::GridRequest* request );
grpc::Status assignReply( rips::CellCenters* reply );
grpc::Status assignCornersReply( rips::CellCornersArray* reply );
protected:
const rips::GridRequest* m_request;
RimEclipseCase* m_eclipseCase;
size_t m_currentCellIdx;
const RigGridBase* m_grid;
};
class RiaGrpcGridService final : public rips::Grid::AsyncService, public RiaGrpcServiceInterface
{
public:
grpc::Status GetCellCenters( grpc::ServerContext* context,
const rips::GridRequest* request,
rips::CellCenters* reply,
RiaCellCenterStateHandler* stateHandler );
grpc::Status GetCellCorners( grpc::ServerContext* context,
const rips::GridRequest* request,
rips::CellCornersArray* reply,
RiaCellCenterStateHandler* stateHandler );
grpc::Status GetDimensions( grpc::ServerContext* context,
const rips::GridRequest* request,
rips::GridDimensions* reply ) override;

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RiaGrpcHelper.h"
//--------------------------------------------------------------------------------------------------
/// Convert internal ResInsight representation of cells with negative depth to positive depth.
//--------------------------------------------------------------------------------------------------
void RiaGrpcHelper::convertVec3dToPositiveDepth( cvf::Vec3d* vec )
{
double& z = vec->z();
z *= -1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaGrpcHelper::setCornerValues( rips::Vec3d* out, const cvf::Vec3d& in )
{
out->set_x( in.x() );
out->set_y( in.y() );
out->set_z( in.z() );
}

View File

@@ -0,0 +1,34 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "Definitions.grpc.pb.h"
#include "cvfVector3.h"
//==================================================================================================
//
// Various gRPC helper methods
//
//==================================================================================================
class RiaGrpcHelper
{
public:
static void convertVec3dToPositiveDepth( cvf::Vec3d* vec );
static void setCornerValues( rips::Vec3d* out, const cvf::Vec3d& in );
};

View File

@@ -35,6 +35,9 @@
#include "Rim3dView.h"
#include "RimEclipseCase.h"
#include "RimEclipseResultDefinition.h"
#include "Riu3dSelectionManager.h"
#include <algorithm>
@@ -263,6 +266,73 @@ private:
std::vector<double>* m_resultValues;
};
class RiaSelectedCellResultsStateHandler : public RiaCellResultsStateHandler
{
public:
RiaSelectedCellResultsStateHandler( bool clientStreamer = false )
: RiaCellResultsStateHandler( clientStreamer )
{
}
protected:
void initResultAccess( RigEclipseCaseData* caseData,
size_t gridIndex,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepIndex,
RigEclipseResultAddress resVarAddr ) override
{
std::vector<RiuSelectionItem*> items;
Riu3dSelectionManager::instance()->selectedItems( items );
// Only eclipse cases are currently supported. Also filter by case.
std::vector<RiuEclipseSelectionItem*> eclipseItems;
for ( auto item : items )
{
RiuEclipseSelectionItem* eclipseItem = dynamic_cast<RiuEclipseSelectionItem*>( item );
if ( eclipseItem && eclipseItem->m_resultDefinition->eclipseCase()->caseId == caseData->ownerCase()->caseId )
{
eclipseItems.push_back( eclipseItem );
}
}
m_cellCount = eclipseItems.size();
if ( m_resultValues.empty() )
{
m_resultValues.resize( m_cellCount );
}
for ( size_t idx = 0; idx < m_cellCount; idx++ )
{
const RiuEclipseSelectionItem* item = eclipseItems[idx];
CVF_ASSERT( item->type() == RiuSelectionItem::ECLIPSE_SELECTION_OBJECT );
size_t cellIndex = item->m_gridLocalCellIndex;
cvf::ref<RigResultAccessor> resultAccessor =
RigResultAccessorFactory::createFromResultAddress( caseData, gridIndex, porosityModel, timeStepIndex, resVarAddr );
if ( resultAccessor.isNull() )
{
continue;
}
double cellValue = resultAccessor->cellScalar( cellIndex );
if ( cellValue == HUGE_VAL )
{
cellValue = 0.0;
}
m_resultValues[idx] = cellValue;
}
}
double cellResult( size_t currentCellIndex ) const override { return m_resultValues[currentCellIndex]; }
void setCellResult( size_t currentCellIndex, double value ) override { m_resultValues[currentCellIndex] = value; }
private:
std::vector<double> m_resultValues;
};
class RiaGridCellResultsStateHandler : public RiaCellResultsStateHandler
{
public:
@@ -339,6 +409,17 @@ grpc::Status RiaGrpcPropertiesService::GetActiveCellProperty( grpc::ServerContex
return stateHandler->assignStreamReply( reply );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcPropertiesService::GetSelectedCellProperty( grpc::ServerContext* context,
const PropertyRequest* request,
PropertyChunk* reply,
RiaSelectedCellResultsStateHandler* stateHandler )
{
return stateHandler->assignStreamReply( reply );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -418,6 +499,15 @@ std::vector<RiaGrpcCallbackInterface*> RiaGrpcPropertiesService::createCallbacks
&Self::GetGridProperty,
&Self::RequestGetGridProperty,
new RiaGridCellResultsStateHandler ) );
callbacks.push_back(
new RiaGrpcServerToClientStreamCallback<Self,
PropertyRequest,
PropertyChunk,
RiaSelectedCellResultsStateHandler>( this,
&Self::GetSelectedCellProperty,
&Self::RequestGetSelectedCellProperty,
new RiaSelectedCellResultsStateHandler ) );
}
return callbacks;
}

View File

@@ -25,6 +25,7 @@
class RiaActiveCellResultsStateHandler;
class RiaGridCellResultsStateHandler;
class RiaSelectedCellResultsStateHandler;
//==================================================================================================
//
@@ -41,6 +42,10 @@ public:
const rips::PropertyRequest* request,
rips::PropertyChunk* reply,
RiaActiveCellResultsStateHandler* stateHandler );
grpc::Status GetSelectedCellProperty( grpc::ServerContext* context,
const rips::PropertyRequest* request,
rips::PropertyChunk* reply,
RiaSelectedCellResultsStateHandler* stateHandler );
grpc::Status GetGridProperty( grpc::ServerContext* context,
const rips::PropertyRequest* request,
rips::PropertyChunk* reply,