From 7ccd0ed477c3ef501d38202d9deba9db29559c94 Mon Sep 17 00:00:00 2001 From: Jon Jenssen Date: Wed, 17 Dec 2025 18:18:01 +0100 Subject: [PATCH 01/11] Work in progress --- .../ReservoirDataModel/RigFault.cpp | 23 +++++++++++++++++++ .../ReservoirDataModel/RigFault.h | 2 ++ .../ReservoirDataModel/RigMainGrid.cpp | 22 ++++++++++++++++++ .../ReservoirDataModel/RigMainGrid.h | 4 ++++ 4 files changed, 51 insertions(+) diff --git a/ApplicationLibCode/ReservoirDataModel/RigFault.cpp b/ApplicationLibCode/ReservoirDataModel/RigFault.cpp index 626b2c106d4..9620470faa3 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigFault.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigFault.cpp @@ -231,3 +231,26 @@ void RigFaultsPrCellAccumulator::setFaultIdx( size_t reservoirCellIndex, cvf::St { m_faultIdxForCellFace[reservoirCellIndex][face] = faultIdx; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair RigFault::minimumDistanceToPoint( const cvf::Vec3d& point, const RigMainGrid* mainGrid ) const +{ + double minDistance = std::numeric_limits::max(); + cvf::StructGridInterface::FaceType minFace = cvf::StructGridInterface::NO_FACE; + for ( const FaultFace& ff : m_faultFaces ) + { + const RigCell& cell = mainGrid->cell( ff.m_nativeReservoirCellIndex ); + if ( cell.isInvalid() ) continue; + + auto faceCenter = cell.faceCenter( ff.m_nativeFace ); + double distance = ( faceCenter - point ).length(); + if ( distance < minDistance ) + { + minDistance = distance; + minFace = ff.m_nativeFace; + } + } + return std::make_pair( minDistance, minFace ); +} diff --git a/ApplicationLibCode/ReservoirDataModel/RigFault.h b/ApplicationLibCode/ReservoirDataModel/RigFault.h index cb60a9188a1..10dc51a3203 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigFault.h +++ b/ApplicationLibCode/ReservoirDataModel/RigFault.h @@ -97,6 +97,8 @@ class RigFault : public cvf::Object static bool ordering( CellAndFace first, CellAndFace second ); + std::pair minimumDistanceToPoint( const cvf::Vec3d& point, const RigMainGrid* mainGrid ) const; + private: QString m_name; diff --git a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.cpp b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.cpp index a4ad490e91c..05a47e62e78 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.cpp @@ -809,6 +809,28 @@ const RigFault* RigMainGrid::findFaultFromCellIndexAndCellFace( size_t reservoir return nullptr; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::tuple RigMainGrid::minimumDistanceFaultToPoint( const cvf::Vec3d& point ) const +{ + double minDistance = std::numeric_limits::max(); + cvf::StructGridInterface::FaceType minFace = cvf::StructGridInterface::FaceType::NO_FACE; + QString minFaultName; + for ( const auto& fault : m_faults ) + { + auto [faultMinDistance, faultMinFace] = fault->minimumDistanceToPoint( point, this ); + + if ( faultMinDistance < minDistance ) + { + minDistance = faultMinDistance; + minFace = faultMinFace; + minFaultName = fault->name(); + } + } + return { minDistance, minFace, minFaultName }; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h index 1df5dcd042a..620e59096f9 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h +++ b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h @@ -27,6 +27,8 @@ #include "cvfBoundingBox.h" #include "cvfCollection.h" +#include + #include class RigActiveCellInfo; @@ -116,6 +118,8 @@ class RigMainGrid : public RigGridBase // invalidate all cells with I > iLimit (0 based index) void invalidateCellsAboveI( size_t iLimit ); + std::tuple minimumDistanceFaultToPoint( const cvf::Vec3d& point ) const; + protected: // only for use by file readers and internal services. TODO: replace with a better API friend class RigGridBase; friend class RigReservoirBuilder; From 5d03950f899d009dac74de09888c7817001e2910 Mon Sep 17 00:00:00 2001 From: jonjenssen Date: Fri, 19 Dec 2025 15:14:02 +0100 Subject: [PATCH 02/11] Add python interface for distance to closest fault Split up some older code into multiple files. --- .../ReservoirDataModel/RigFault.cpp | 12 +- .../ReservoirDataModel/RigMainGrid.h | 2 +- GrpcInterface/CMakeLists.txt | 4 + GrpcInterface/GrpcProtos/Case.proto | 12 + .../fault_distance.py | 30 + GrpcInterface/Python/rips/case.py | 13 + .../RiaGrpcActiveCellInfoStateHandler.cpp | 359 ++++++++++++ .../RiaGrpcActiveCellInfoStateHandler.h | 78 +++ GrpcInterface/RiaGrpcCaseService.cpp | 536 +++--------------- GrpcInterface/RiaGrpcCaseService.h | 104 +--- GrpcInterface/RiaGrpcHelper.cpp | 22 + GrpcInterface/RiaGrpcHelper.h | 3 + .../RiaGrpcSelectedCellsStateHandler.cpp | 155 +++++ .../RiaGrpcSelectedCellsStateHandler.h | 55 ++ 14 files changed, 826 insertions(+), 559 deletions(-) create mode 100644 GrpcInterface/Python/rips/PythonExamples/case_and_grid_operations/fault_distance.py create mode 100644 GrpcInterface/RiaGrpcActiveCellInfoStateHandler.cpp create mode 100644 GrpcInterface/RiaGrpcActiveCellInfoStateHandler.h create mode 100644 GrpcInterface/RiaGrpcSelectedCellsStateHandler.cpp create mode 100644 GrpcInterface/RiaGrpcSelectedCellsStateHandler.h diff --git a/ApplicationLibCode/ReservoirDataModel/RigFault.cpp b/ApplicationLibCode/ReservoirDataModel/RigFault.cpp index 9620470faa3..ec1b8245e02 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigFault.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigFault.cpp @@ -244,12 +244,14 @@ std::pair RigFault::minimumDistanceT const RigCell& cell = mainGrid->cell( ff.m_nativeReservoirCellIndex ); if ( cell.isInvalid() ) continue; - auto faceCenter = cell.faceCenter( ff.m_nativeFace ); - double distance = ( faceCenter - point ).length(); - if ( distance < minDistance ) + for ( auto& c : cell.faceCorners( ff.m_nativeFace ) ) { - minDistance = distance; - minFace = ff.m_nativeFace; + double distance = ( c - point ).length(); + if ( distance < minDistance ) + { + minDistance = distance; + minFace = ff.m_nativeFace; + } } } return std::make_pair( minDistance, minFace ); diff --git a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h index 620e59096f9..4d1414bb326 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h +++ b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h @@ -128,7 +128,7 @@ class RigMainGrid : public RigGridBase friend class RifReaderEclipseOutput; friend class RifReaderOpmCommon; friend class RiaGrpcCaseService; - friend class RiaActiveCellInfoStateHandler; + friend class RiaGrpcActiveCellInfoStateHandler; friend class RicCreateTemporaryLgrFeature; friend class RimCornerPointCase; std::vector& reservoirCells(); diff --git a/GrpcInterface/CMakeLists.txt b/GrpcInterface/CMakeLists.txt index 703bc9ca7cd..8c2bdb3a358 100644 --- a/GrpcInterface/CMakeLists.txt +++ b/GrpcInterface/CMakeLists.txt @@ -39,6 +39,8 @@ set(SOURCE_GROUP_HEADER_FILES RiaGrpcApplicationInterface.h RiaGrpcWellPathService.h RiaWellPathDataToGrpcConverter.h + RiaGrpcActiveCellInfoStateHandler.h + RiaGrpcSelectedCellsStateHandler.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -58,6 +60,8 @@ set(SOURCE_GROUP_SOURCE_FILES RiaGrpcApplicationInterface.cpp RiaGrpcWellPathService.cpp RiaWellPathDataToGrpcConverter.cpp + RiaGrpcActiveCellInfoStateHandler.cpp + RiaGrpcSelectedCellsStateHandler.cpp ) # Find Protobuf installation Looks for protobuf-config.cmake file installed by diff --git a/GrpcInterface/GrpcProtos/Case.proto b/GrpcInterface/GrpcProtos/Case.proto index 076028612ff..148d40d11ca 100644 --- a/GrpcInterface/GrpcProtos/Case.proto +++ b/GrpcInterface/GrpcProtos/Case.proto @@ -21,6 +21,7 @@ service Case { rpc GetCaseInfo(CaseRequest) returns (CaseInfo) {} rpc GetPdmObject(CaseRequest) returns (PdmObject) {} rpc GetReservoirBoundingBox(CaseRequest) returns (BoundingBox) {} + rpc GetDistanceToClosestFault(ClosestFaultRequest) returns (ClosestFault) {} } message CaseRequest { int32 id = 1; } @@ -103,3 +104,14 @@ message SelectedCell { } message SelectedCells { repeated SelectedCell cells = 1; } + +message ClosestFaultRequest { + CaseRequest case_request = 1; + Vec3d point = 2; +} + +message ClosestFault { + string fault_name = 1; + double distance = 2; + string face_name = 3; +} diff --git a/GrpcInterface/Python/rips/PythonExamples/case_and_grid_operations/fault_distance.py b/GrpcInterface/Python/rips/PythonExamples/case_and_grid_operations/fault_distance.py new file mode 100644 index 00000000000..c33ff378979 --- /dev/null +++ b/GrpcInterface/Python/rips/PythonExamples/case_and_grid_operations/fault_distance.py @@ -0,0 +1,30 @@ +################################################################################### +# This example prints the distance to and the name of the fault closest to a point +################################################################################### + +import rips + +resinsight = rips.Instance.find() +if resinsight is None: + exit(1) + +cases = resinsight.project.cases() +if len(cases) == 0: + exit(1) + +case = cases[0] +print("Using case: " + case.name) + +# random test point (positive Z for depth) +point_x = 5039.84 +point_y = 6303.76 +point_z = 4144.21 + +print("Looking for closest fault to point %f, %f, %f:" % (point_x, point_y, point_z)) + +distance, faultname, facename = case.distance_to_closest_fault(point_x, point_y, point_z) + +if facename == "": + print("- No fault found!") +else: + print("- Distance to closest fault %s is %f, closest face direction is %s" % (faultname, distance, facename)) diff --git a/GrpcInterface/Python/rips/case.py b/GrpcInterface/Python/rips/case.py index 6fd49c26088..29e9732800e 100644 --- a/GrpcInterface/Python/rips/case.py +++ b/GrpcInterface/Python/rips/case.py @@ -43,6 +43,7 @@ import Case_pb2_grpc import Commands_pb2 as Cmd import PdmObject_pb2 as PdmObject_pb2 +import Definitions_pb2 import Properties_pb2 import Properties_pb2_grpc @@ -299,6 +300,18 @@ def reservoir_boundingbox(self): """ return self.__case_stub.GetReservoirBoundingBox(self.__request()) +@add_method(Case) +def distance_to_closest_fault(self, x: float, y: float, z: float): + """Find the closest fault to the given point and return the distance, fault name and fault face + """ + request = Case_pb2.ClosestFaultRequest( + case_request=self.__request(), + point=Definitions_pb2.Vec3d(x=x, y=y, z=z) + ) + reply = self.__case_stub.GetDistanceToClosestFault(request) + + return (reply.distance, reply.fault_name, reply.face_name) + @add_method(Case) def reservoir_depth_range(self) -> Tuple[float, float]: diff --git a/GrpcInterface/RiaGrpcActiveCellInfoStateHandler.cpp b/GrpcInterface/RiaGrpcActiveCellInfoStateHandler.cpp new file mode 100644 index 00000000000..23ee35e6a9e --- /dev/null +++ b/GrpcInterface/RiaGrpcActiveCellInfoStateHandler.cpp @@ -0,0 +1,359 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2025 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 +// for more details. +// +////////////////////////////////////////////////////////////////////////////////// +#include "RiaGrpcActiveCellInfoStateHandler.h" + +#include "RiaGrpcCallbacks.h" +#include "RiaGrpcHelper.h" +#include "RiaSocketTools.h" + +#include "RigActiveCellInfo.h" +#include "RigCaseCellResultsData.h" +#include "RigEclipseCaseData.h" +#include "RigEclipseResultAddress.h" +#include "RigMainGrid.h" + +#include "RimEclipseCase.h" +#include "RimEclipseResultDefinition.h" + +#include "Riu3dSelectionManager.h" + +#include + +using namespace rips; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaGrpcActiveCellInfoStateHandler::RiaGrpcActiveCellInfoStateHandler() + : m_request( nullptr ) + , m_eclipseCase( nullptr ) + , m_activeCellInfo( nullptr ) + , m_currentCellIdx( 0u ) + , m_porosityModel( RiaDefines::PorosityModelType::MATRIX_MODEL ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +grpc::Status RiaGrpcActiveCellInfoStateHandler::init( const rips::CellInfoRequest* request ) +{ + CAF_ASSERT( request ); + m_request = request; + + m_porosityModel = RiaDefines::PorosityModelType( m_request->porosity_model() ); + RimCase* rimCase = RiaGrpcHelper::findCase( m_request->case_request().id() ); + m_eclipseCase = dynamic_cast( 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" ); + } + + m_activeCellInfo = m_eclipseCase->eclipseCaseData()->activeCellInfo( m_porosityModel ); + + if ( !m_activeCellInfo ) + { + return grpc::Status( grpc::NOT_FOUND, "Active Cell Info not found" ); + } + + size_t globalCoarseningBoxCount = 0; + + for ( size_t gridIdx = 0; gridIdx < m_eclipseCase->eclipseCaseData()->gridCount(); gridIdx++ ) + { + m_globalCoarseningBoxIndexStart.push_back( globalCoarseningBoxCount ); + + RigGridBase* grid = m_eclipseCase->eclipseCaseData()->grid( gridIdx ); + + size_t localCoarseningBoxCount = grid->coarseningBoxCount(); + globalCoarseningBoxCount += localCoarseningBoxCount; + } + + return grpc::Status::OK; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +grpc::Status RiaGrpcActiveCellInfoStateHandler::assignNextActiveCellInfoData( rips::CellInfo* cellInfo ) +{ + const std::vector& reservoirCells = m_eclipseCase->eclipseCaseData()->mainGrid()->reservoirCells(); + + while ( m_currentCellIdx < reservoirCells.size() ) + { + size_t cellIdxToTry = m_currentCellIdx++; + if ( m_activeCellInfo->isActive( cellIdxToTry ) ) + { + assignCellInfoData( cellInfo, 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 RiaGrpcActiveCellInfoStateHandler::assignCellInfoData( rips::CellInfo* cellInfo, + const std::vector& reservoirCells, + size_t cellIdx ) +{ + RigGridBase* grid = reservoirCells[cellIdx].hostGrid(); + CVF_ASSERT( grid != nullptr ); + size_t cellIndex = reservoirCells[cellIdx].gridLocalCellIndex(); + + size_t i, j, k; + grid->ijkFromCellIndex( cellIndex, &i, &j, &k ); + + size_t pi, pj, pk; + RigGridBase* parentGrid = nullptr; + + if ( grid->isMainGrid() ) + { + pi = i; + pj = j; + pk = k; + parentGrid = grid; + } + else + { + size_t parentCellIdx = reservoirCells[cellIdx].parentCellIndex(); + parentGrid = ( static_cast( grid ) )->parentGrid(); + CVF_ASSERT( parentGrid != nullptr ); + parentGrid->ijkFromCellIndex( parentCellIdx, &pi, &pj, &pk ); + } + + cellInfo->set_grid_index( (int)grid->gridIndex() ); + cellInfo->set_parent_grid_index( (int)parentGrid->gridIndex() ); + + size_t coarseningIdx = reservoirCells[cellIdx].coarseningBoxIndex(); + if ( coarseningIdx != cvf::UNDEFINED_SIZE_T ) + { + size_t globalCoarseningIdx = m_globalCoarseningBoxIndexStart[grid->gridIndex()] + coarseningIdx; + cellInfo->set_coarsening_box_index( (int)globalCoarseningIdx ); + } + else + { + cellInfo->set_coarsening_box_index( -1 ); + } + { + rips::Vec3i* local_ijk = new rips::Vec3i; + local_ijk->set_i( (int)i ); + local_ijk->set_j( (int)j ); + local_ijk->set_k( (int)k ); + cellInfo->set_allocated_local_ijk( local_ijk ); + } + { + rips::Vec3i* parent_ijk = new rips::Vec3i; + parent_ijk->set_i( (int)pi ); + parent_ijk->set_j( (int)pj ); + parent_ijk->set_k( (int)pk ); + cellInfo->set_allocated_parent_ijk( parent_ijk ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigActiveCellInfo* RiaGrpcActiveCellInfoStateHandler::activeCellInfo() const +{ + return m_activeCellInfo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RiaGrpcActiveCellInfoStateHandler::reservoirCells() const +{ + const std::vector& reservoirCells = m_eclipseCase->eclipseCaseData()->mainGrid()->reservoirCells(); + return reservoirCells; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +grpc::Status RiaGrpcActiveCellInfoStateHandler::assignReply( rips::CellInfoArray* reply ) +{ + const size_t packageSize = RiaGrpcHelper::numberOfDataUnitsInPackage( sizeof( rips::CellInfo ) ); + size_t indexInPackage = 0u; + reply->mutable_data()->Reserve( (int)packageSize ); + + // Stream until you've reached the package size or total cell count. Whatever comes first. + // If you've reached the package size you'll come back for another round. + for ( ; indexInPackage < packageSize && m_currentCellIdx < m_activeCellInfo->reservoirCellCount(); ++indexInPackage ) + { + rips::CellInfo singleCellInfo; + grpc::Status singleCellInfoStatus = assignNextActiveCellInfoData( &singleCellInfo ); + if ( singleCellInfoStatus.ok() ) + { + rips::CellInfo* allocCellInfo = reply->add_data(); + *allocCellInfo = singleCellInfo; + } + 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 RiaGrpcActiveCellInfoStateHandler::assignNextActiveCellCenter( rips::Vec3d* cellCenter ) +{ + const std::vector& reservoirCells = m_eclipseCase->eclipseCaseData()->mainGrid()->reservoirCells(); + + 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 RiaGrpcActiveCellInfoStateHandler::assignCellCenter( rips::Vec3d* cellCenter, + const std::vector& reservoirCells, + size_t cellIdx ) + +{ + cvf::Vec3d center = reservoirCells[cellIdx].center(); + + RiaGrpcHelper::convertVec3dToPositiveDepth( ¢er ); + + cellCenter->set_x( center.x() ); + cellCenter->set_y( center.y() ); + cellCenter->set_z( center.z() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +grpc::Status RiaGrpcActiveCellInfoStateHandler::assignCellCentersReply( rips::CellCenters* reply ) +{ + const size_t packageSize = RiaGrpcHelper::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 RiaGrpcActiveCellInfoStateHandler::assignNextActiveCellCorners( rips::CellCorners* cellCorners ) +{ + const std::vector& reservoirCells = m_eclipseCase->eclipseCaseData()->mainGrid()->reservoirCells(); + + 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 RiaGrpcActiveCellInfoStateHandler::assignCellCorners( rips::CellCorners* corners, + const std::vector& reservoirCells, + size_t cellIdx ) +{ + RigGridBase* grid = m_eclipseCase->eclipseCaseData()->mainGrid(); + std::array cornerVerts = grid->cellCornerVertices( cellIdx ); + 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 RiaGrpcActiveCellInfoStateHandler::assignCellCornersReply( rips::CellCornersArray* reply ) +{ + const size_t packageSize = RiaGrpcHelper::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" ); +} diff --git a/GrpcInterface/RiaGrpcActiveCellInfoStateHandler.h b/GrpcInterface/RiaGrpcActiveCellInfoStateHandler.h new file mode 100644 index 00000000000..9831fa921e6 --- /dev/null +++ b/GrpcInterface/RiaGrpcActiveCellInfoStateHandler.h @@ -0,0 +1,78 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2025 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 +// for more details. +// +////////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "Case.grpc.pb.h" + +// #include "RiaGrpcServiceInterface.h" +#include "RiaPorosityModel.h" + +#include + +// namespace rips +//{ +// class CaseRequest; +// class PdmObject; +// } // namespace rips + +// class RiaGrpcCallbackInterface; +class RigCell; +class RigActiveCellInfo; +class RimEclipseCase; +// class RiuEclipseSelectionItem; + +//================================================================================================== +// +// State handler for streaming of active cell info +// +//================================================================================================== +class RiaGrpcActiveCellInfoStateHandler +{ + using Status = grpc::Status; + +public: + RiaGrpcActiveCellInfoStateHandler(); + + Status init( const rips::CellInfoRequest* request ); + + RigActiveCellInfo* activeCellInfo() const; + const std::vector& reservoirCells() const; + + // For cell info: + Status assignNextActiveCellInfoData( rips::CellInfo* cellInfo ); + void assignCellInfoData( rips::CellInfo* cellInfo, const std::vector& reservoirCells, size_t cellIdx ); + Status assignReply( rips::CellInfoArray* reply ); + + // For cell centers: + Status assignNextActiveCellCenter( rips::Vec3d* cellCenter ); + void assignCellCenter( rips::Vec3d* cellCenter, const std::vector& 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& reservoirCells, size_t cellIdx ); + Status assignCellCornersReply( rips::CellCornersArray* reply ); + +protected: + const rips::CellInfoRequest* m_request; + RimEclipseCase* m_eclipseCase; + RiaDefines::PorosityModelType m_porosityModel; + RigActiveCellInfo* m_activeCellInfo; + std::vector m_globalCoarseningBoxIndexStart; + size_t m_currentCellIdx; +}; diff --git a/GrpcInterface/RiaGrpcCaseService.cpp b/GrpcInterface/RiaGrpcCaseService.cpp index fcf789d1190..6604297d87d 100644 --- a/GrpcInterface/RiaGrpcCaseService.cpp +++ b/GrpcInterface/RiaGrpcCaseService.cpp @@ -17,8 +17,10 @@ ////////////////////////////////////////////////////////////////////////////////// #include "RiaGrpcCaseService.h" +#include "RiaGrpcActiveCellInfoStateHandler.h" #include "RiaGrpcCallbacks.h" #include "RiaGrpcHelper.h" +#include "RiaGrpcSelectedCellsStateHandler.h" #include "RiaSocketTools.h" #include "RigActiveCellInfo.h" @@ -36,327 +38,6 @@ using namespace rips; -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RiaActiveCellInfoStateHandler::RiaActiveCellInfoStateHandler() - : m_request( nullptr ) - , m_eclipseCase( nullptr ) - , m_activeCellInfo( nullptr ) - , m_currentCellIdx( 0u ) -{ -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -grpc::Status RiaActiveCellInfoStateHandler::init( const rips::CellInfoRequest* request ) -{ - CAF_ASSERT( request ); - m_request = request; - - m_porosityModel = RiaDefines::PorosityModelType( m_request->porosity_model() ); - RimCase* rimCase = RiaGrpcHelper::findCase( m_request->case_request().id() ); - m_eclipseCase = dynamic_cast( 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" ); - } - - m_activeCellInfo = m_eclipseCase->eclipseCaseData()->activeCellInfo( m_porosityModel ); - - if ( !m_activeCellInfo ) - { - return grpc::Status( grpc::NOT_FOUND, "Active Cell Info not found" ); - } - - size_t globalCoarseningBoxCount = 0; - - for ( size_t gridIdx = 0; gridIdx < m_eclipseCase->eclipseCaseData()->gridCount(); gridIdx++ ) - { - m_globalCoarseningBoxIndexStart.push_back( globalCoarseningBoxCount ); - - RigGridBase* grid = m_eclipseCase->eclipseCaseData()->grid( gridIdx ); - - size_t localCoarseningBoxCount = grid->coarseningBoxCount(); - globalCoarseningBoxCount += localCoarseningBoxCount; - } - - return grpc::Status::OK; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -grpc::Status RiaActiveCellInfoStateHandler::assignNextActiveCellInfoData( rips::CellInfo* cellInfo ) -{ - const std::vector& reservoirCells = m_eclipseCase->eclipseCaseData()->mainGrid()->reservoirCells(); - - while ( m_currentCellIdx < reservoirCells.size() ) - { - size_t cellIdxToTry = m_currentCellIdx++; - if ( m_activeCellInfo->isActive( cellIdxToTry ) ) - { - assignCellInfoData( cellInfo, 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::assignCellInfoData( rips::CellInfo* cellInfo, - const std::vector& reservoirCells, - size_t cellIdx ) -{ - RigGridBase* grid = reservoirCells[cellIdx].hostGrid(); - CVF_ASSERT( grid != nullptr ); - size_t cellIndex = reservoirCells[cellIdx].gridLocalCellIndex(); - - size_t i, j, k; - grid->ijkFromCellIndex( cellIndex, &i, &j, &k ); - - size_t pi, pj, pk; - RigGridBase* parentGrid = nullptr; - - if ( grid->isMainGrid() ) - { - pi = i; - pj = j; - pk = k; - parentGrid = grid; - } - else - { - size_t parentCellIdx = reservoirCells[cellIdx].parentCellIndex(); - parentGrid = ( static_cast( grid ) )->parentGrid(); - CVF_ASSERT( parentGrid != nullptr ); - parentGrid->ijkFromCellIndex( parentCellIdx, &pi, &pj, &pk ); - } - - cellInfo->set_grid_index( (int)grid->gridIndex() ); - cellInfo->set_parent_grid_index( (int)parentGrid->gridIndex() ); - - size_t coarseningIdx = reservoirCells[cellIdx].coarseningBoxIndex(); - if ( coarseningIdx != cvf::UNDEFINED_SIZE_T ) - { - size_t globalCoarseningIdx = m_globalCoarseningBoxIndexStart[grid->gridIndex()] + coarseningIdx; - cellInfo->set_coarsening_box_index( (int)globalCoarseningIdx ); - } - else - { - cellInfo->set_coarsening_box_index( -1 ); - } - { - rips::Vec3i* local_ijk = new rips::Vec3i; - local_ijk->set_i( (int)i ); - local_ijk->set_j( (int)j ); - local_ijk->set_k( (int)k ); - cellInfo->set_allocated_local_ijk( local_ijk ); - } - { - rips::Vec3i* parent_ijk = new rips::Vec3i; - parent_ijk->set_i( (int)pi ); - parent_ijk->set_j( (int)pj ); - parent_ijk->set_k( (int)pk ); - cellInfo->set_allocated_parent_ijk( parent_ijk ); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigActiveCellInfo* RiaActiveCellInfoStateHandler::activeCellInfo() const -{ - return m_activeCellInfo; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const std::vector& RiaActiveCellInfoStateHandler::reservoirCells() const -{ - const std::vector& reservoirCells = m_eclipseCase->eclipseCaseData()->mainGrid()->reservoirCells(); - return reservoirCells; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -grpc::Status RiaActiveCellInfoStateHandler::assignReply( rips::CellInfoArray* reply ) -{ - const size_t packageSize = RiaGrpcHelper::numberOfDataUnitsInPackage( sizeof( rips::CellInfo ) ); - size_t indexInPackage = 0u; - reply->mutable_data()->Reserve( (int)packageSize ); - - // Stream until you've reached the package size or total cell count. Whatever comes first. - // If you've reached the package size you'll come back for another round. - for ( ; indexInPackage < packageSize && m_currentCellIdx < m_activeCellInfo->reservoirCellCount(); ++indexInPackage ) - { - rips::CellInfo singleCellInfo; - grpc::Status singleCellInfoStatus = assignNextActiveCellInfoData( &singleCellInfo ); - if ( singleCellInfoStatus.ok() ) - { - rips::CellInfo* allocCellInfo = reply->add_data(); - *allocCellInfo = singleCellInfo; - } - 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 RiaActiveCellInfoStateHandler::assignNextActiveCellCenter( rips::Vec3d* cellCenter ) -{ - const std::vector& reservoirCells = m_eclipseCase->eclipseCaseData()->mainGrid()->reservoirCells(); - - 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& reservoirCells, - size_t cellIdx ) - -{ - cvf::Vec3d center = reservoirCells[cellIdx].center(); - - RiaGrpcHelper::convertVec3dToPositiveDepth( ¢er ); - - 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 = RiaGrpcHelper::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& reservoirCells = m_eclipseCase->eclipseCaseData()->mainGrid()->reservoirCells(); - - 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& reservoirCells, - size_t cellIdx ) -{ - RigGridBase* grid = m_eclipseCase->eclipseCaseData()->mainGrid(); - std::array cornerVerts = grid->cellCornerVertices( cellIdx ); - 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 = RiaGrpcHelper::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" ); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -502,10 +183,10 @@ grpc::Status RiaGrpcCaseService::GetPdmObject( grpc::ServerContext* context, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -grpc::Status RiaGrpcCaseService::GetCellInfoForActiveCells( grpc::ServerContext* context, - const rips::CellInfoRequest* request, - rips::CellInfoArray* reply, - RiaActiveCellInfoStateHandler* stateHandler ) +grpc::Status RiaGrpcCaseService::GetCellInfoForActiveCells( grpc::ServerContext* context, + const rips::CellInfoRequest* request, + rips::CellInfoArray* reply, + RiaGrpcActiveCellInfoStateHandler* stateHandler ) { return stateHandler->assignReply( reply ); } @@ -513,10 +194,10 @@ grpc::Status RiaGrpcCaseService::GetCellInfoForActiveCells( grpc::ServerContext* //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -grpc::Status RiaGrpcCaseService::GetCellCenterForActiveCells( grpc::ServerContext* context, - const rips::CellInfoRequest* request, - rips::CellCenters* reply, - RiaActiveCellInfoStateHandler* stateHandler ) +grpc::Status RiaGrpcCaseService::GetCellCenterForActiveCells( grpc::ServerContext* context, + const rips::CellInfoRequest* request, + rips::CellCenters* reply, + RiaGrpcActiveCellInfoStateHandler* stateHandler ) { return stateHandler->assignCellCentersReply( reply ); } @@ -524,10 +205,10 @@ grpc::Status RiaGrpcCaseService::GetCellCenterForActiveCells( grpc::ServerContex //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -grpc::Status RiaGrpcCaseService::GetCellCornersForActiveCells( grpc::ServerContext* context, - const rips::CellInfoRequest* request, - rips::CellCornersArray* reply, - RiaActiveCellInfoStateHandler* stateHandler ) +grpc::Status RiaGrpcCaseService::GetCellCornersForActiveCells( grpc::ServerContext* context, + const rips::CellInfoRequest* request, + rips::CellCornersArray* reply, + RiaGrpcActiveCellInfoStateHandler* stateHandler ) { return stateHandler->assignCellCornersReply( reply ); } @@ -535,128 +216,10 @@ grpc::Status RiaGrpcCaseService::GetCellCornersForActiveCells( grpc::ServerConte //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -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 = RiaGrpcHelper::findCase( m_request->id() ); - m_eclipseCase = dynamic_cast( 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& 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 items; - Riu3dSelectionManager::instance()->selectedItems( items ); - - // Only eclipse cases are currently supported. Also filter by case. - std::vector eclipseItems; - for ( auto item : items ) - { - RiuEclipseSelectionItem* eclipseItem = dynamic_cast( item ); - if ( eclipseItem && eclipseItem->m_resultDefinition->eclipseCase()->caseId() == m_request->id() ) - { - eclipseItems.push_back( eclipseItem ); - } - } - - const size_t packageSize = RiaGrpcHelper::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 ) +grpc::Status RiaGrpcCaseService::GetSelectedCells( grpc::ServerContext* context, + const rips::CaseRequest* request, + rips::SelectedCells* reply, + RiaGrpcSelectedCellsStateHandler* stateHandler ) { return stateHandler->assignReply( reply ); } @@ -723,6 +286,31 @@ grpc::Status RiaGrpcCaseService::GetCoarseningInfoArray( grpc::ServerContext* return Status( grpc::NOT_FOUND, "Case not found" ); } +grpc::Status RiaGrpcCaseService::GetDistanceToClosestFault( grpc::ServerContext* context, + const rips::ClosestFaultRequest* request, + rips::ClosestFault* reply ) +{ + RimCase* rimCase = RiaGrpcHelper::findCase( request->case_request().id() ); + if ( auto eCase = dynamic_cast( rimCase ) ) + { + cvf::Vec3d point( request->point() ); + point.z() = -point.z(); // Convert to internal coordinate system + + double distance = 0.0; + cvf::StructGridInterface::FaceType faceType; + QString faultName; + + std::tie( distance, faceType, faultName ) = eCase->mainGrid()->minimumDistanceFaultToPoint( point ); + + reply->set_distance( distance ); + reply->set_face_name( RiaGrpcHelper::faceTypeToString( faceType ) ); + reply->set_fault_name( faultName.toStdString() ); + + return grpc::Status::OK; + } + return Status( grpc::NOT_FOUND, "Case not found" ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -741,38 +329,42 @@ std::vector RiaGrpcCaseService::createCallbacks() new RiaGrpcServerToClientStreamCallback( this, - &Self::GetCellInfoForActiveCells, - &Self::RequestGetCellInfoForActiveCells, - new RiaActiveCellInfoStateHandler ), + RiaGrpcActiveCellInfoStateHandler>( this, + &Self::GetCellInfoForActiveCells, + &Self::RequestGetCellInfoForActiveCells, + new RiaGrpcActiveCellInfoStateHandler ), new RiaGrpcServerToClientStreamCallback( this, - &Self::GetCellCenterForActiveCells, - &Self::RequestGetCellCenterForActiveCells, - new RiaActiveCellInfoStateHandler ), + RiaGrpcActiveCellInfoStateHandler>( this, + &Self::GetCellCenterForActiveCells, + &Self::RequestGetCellCenterForActiveCells, + new RiaGrpcActiveCellInfoStateHandler ), new RiaGrpcServerToClientStreamCallback( this, - &Self::GetCellCornersForActiveCells, - &Self::RequestGetCellCornersForActiveCells, - new RiaActiveCellInfoStateHandler ), + RiaGrpcActiveCellInfoStateHandler>( this, + &Self::GetCellCornersForActiveCells, + &Self::RequestGetCellCornersForActiveCells, + new RiaGrpcActiveCellInfoStateHandler ), new RiaGrpcServerToClientStreamCallback( this, - &Self::GetSelectedCells, - &Self::RequestGetSelectedCells, - new RiaSelectedCellsStateHandler ), + RiaGrpcSelectedCellsStateHandler>( this, + &Self::GetSelectedCells, + &Self::RequestGetSelectedCells, + new RiaGrpcSelectedCellsStateHandler ), new RiaGrpcUnaryCallback( this, &Self::GetReservoirBoundingBox, &Self::RequestGetReservoirBoundingBox ), new RiaGrpcUnaryCallback( this, &Self::GetCoarseningInfoArray, - &Self::RequestGetCoarseningInfoArray ) }; + &Self::RequestGetCoarseningInfoArray ), + + new RiaGrpcUnaryCallback( this, + &Self::GetDistanceToClosestFault, + &Self::RequestGetDistanceToClosestFault ) }; } static bool RiaGrpcCaseService_init = diff --git a/GrpcInterface/RiaGrpcCaseService.h b/GrpcInterface/RiaGrpcCaseService.h index f21b3ef29cb..53a868651ae 100644 --- a/GrpcInterface/RiaGrpcCaseService.h +++ b/GrpcInterface/RiaGrpcCaseService.h @@ -28,77 +28,15 @@ namespace rips { class CaseRequest; class PdmObject; +class CaseInfo; } // namespace rips class RiaGrpcCallbackInterface; class RigCell; class RigActiveCellInfo; class RimEclipseCase; -class RiuEclipseSelectionItem; - -//================================================================================================== -// -// State handler for streaming of active cell info -// -//================================================================================================== -class RiaActiveCellInfoStateHandler -{ - using Status = grpc::Status; - -public: - RiaActiveCellInfoStateHandler(); - - Status init( const rips::CellInfoRequest* request ); - - RigActiveCellInfo* activeCellInfo() const; - const std::vector& reservoirCells() const; - - // For cell info: - Status assignNextActiveCellInfoData( rips::CellInfo* cellInfo ); - void assignCellInfoData( rips::CellInfo* cellInfo, const std::vector& reservoirCells, size_t cellIdx ); - Status assignReply( rips::CellInfoArray* reply ); - - // For cell centers: - Status assignNextActiveCellCenter( rips::Vec3d* cellCenter ); - void assignCellCenter( rips::Vec3d* cellCenter, const std::vector& 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& reservoirCells, size_t cellIdx ); - Status assignCellCornersReply( rips::CellCornersArray* reply ); - -protected: - const rips::CellInfoRequest* m_request; - RimEclipseCase* m_eclipseCase; - RiaDefines::PorosityModelType m_porosityModel; - RigActiveCellInfo* m_activeCellInfo; - std::vector m_globalCoarseningBoxIndexStart; - size_t m_currentCellIdx; -}; - -//================================================================================================== -// -// State handler for streaming of selected cells -// -//================================================================================================== -class RiaSelectedCellsStateHandler -{ - using Status = grpc::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& items ); - -protected: - const rips::CaseRequest* m_request; - RimEclipseCase* m_eclipseCase; - size_t m_currentItem; -}; +class RiaGrpcActiveCellInfoStateHandler; +class RiaGrpcSelectedCellsStateHandler; //================================================================================================== // @@ -122,22 +60,22 @@ class RiaGrpcCaseService final : public rips::Case::AsyncService, public RiaGrpc grpc::Status GetCaseInfo( grpc::ServerContext* context, const rips::CaseRequest* request, rips::CaseInfo* reply ) override; grpc::Status GetPdmObject( grpc::ServerContext* context, const rips::CaseRequest* request, rips::PdmObject* reply ) override; - grpc::Status GetCellInfoForActiveCells( grpc::ServerContext* context, - 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 GetCellInfoForActiveCells( grpc::ServerContext* context, + const rips::CellInfoRequest* request, + rips::CellInfoArray* reply, + RiaGrpcActiveCellInfoStateHandler* stateHandler ); + grpc::Status GetCellCenterForActiveCells( grpc::ServerContext* context, + const rips::CellInfoRequest* request, + rips::CellCenters* reply, + RiaGrpcActiveCellInfoStateHandler* stateHandler ); + grpc::Status GetCellCornersForActiveCells( grpc::ServerContext* context, + const rips::CellInfoRequest* request, + rips::CellCornersArray* reply, + RiaGrpcActiveCellInfoStateHandler* stateHandler ); + grpc::Status GetSelectedCells( grpc::ServerContext* context, + const rips::CaseRequest* request, + rips::SelectedCells* reply, + RiaGrpcSelectedCellsStateHandler* stateHandler ); grpc::Status GetReservoirBoundingBox( grpc::ServerContext* context, const rips::CaseRequest* request, rips::BoundingBox* reply ) override; @@ -145,5 +83,9 @@ class RiaGrpcCaseService final : public rips::Case::AsyncService, public RiaGrpc const rips::CaseRequest* request, rips::CoarseningInfoArray* reply ) override; + grpc::Status GetDistanceToClosestFault( grpc::ServerContext* context, + const rips::ClosestFaultRequest* request, + rips::ClosestFault* reply ) override; + std::vector createCallbacks() override; }; diff --git a/GrpcInterface/RiaGrpcHelper.cpp b/GrpcInterface/RiaGrpcHelper.cpp index 2775706663c..6e9a1f80cae 100644 --- a/GrpcInterface/RiaGrpcHelper.cpp +++ b/GrpcInterface/RiaGrpcHelper.cpp @@ -105,3 +105,25 @@ RimCase* RiaGrpcHelper::findCase( int caseId ) } return nullptr; } + +std::string RiaGrpcHelper::faceTypeToString( cvf::StructGridInterface::FaceType faceType ) +{ + switch ( faceType ) + { + case cvf::StructGridInterface::POS_I: + return "I+"; + case cvf::StructGridInterface::NEG_I: + return "I-"; + case cvf::StructGridInterface::POS_J: + return "J+"; + case cvf::StructGridInterface::NEG_J: + return "J-"; + case cvf::StructGridInterface::POS_K: + return "K+"; + case cvf::StructGridInterface::NEG_K: + return "K-"; + default: + break; + } + return ""; +} diff --git a/GrpcInterface/RiaGrpcHelper.h b/GrpcInterface/RiaGrpcHelper.h index b027876fd60..545e1810767 100644 --- a/GrpcInterface/RiaGrpcHelper.h +++ b/GrpcInterface/RiaGrpcHelper.h @@ -19,6 +19,7 @@ #include "Definitions.grpc.pb.h" +#include "cvfStructGrid.h" #include "cvfVector3.h" #include @@ -51,4 +52,6 @@ class RiaGrpcHelper static size_t numberOfDataUnitsInPackage( size_t dataUnitSize, size_t packageByteCount = 64 * 1024u ); static RimCase* findCase( int caseId ); + + static std::string faceTypeToString( cvf::StructGridInterface::FaceType ); }; diff --git a/GrpcInterface/RiaGrpcSelectedCellsStateHandler.cpp b/GrpcInterface/RiaGrpcSelectedCellsStateHandler.cpp new file mode 100644 index 00000000000..cf1c7b0ca0b --- /dev/null +++ b/GrpcInterface/RiaGrpcSelectedCellsStateHandler.cpp @@ -0,0 +1,155 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +////////////////////////////////////////////////////////////////////////////////// +#include "RiaGrpcSelectedCellsStateHandler.h" + +#include "RiaGrpcCallbacks.h" +#include "RiaGrpcHelper.h" +#include "RiaSocketTools.h" + +#include "RigActiveCellInfo.h" +#include "RigCaseCellResultsData.h" +#include "RigEclipseCaseData.h" +#include "RigEclipseResultAddress.h" +#include "RigMainGrid.h" + +#include "RimEclipseCase.h" +#include "RimEclipseResultDefinition.h" + +#include "Riu3dSelectionManager.h" + +#include + +using namespace rips; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaGrpcSelectedCellsStateHandler::RiaGrpcSelectedCellsStateHandler() + : m_request( nullptr ) + , m_eclipseCase( nullptr ) + , m_currentItem( 0u ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Status RiaGrpcSelectedCellsStateHandler::init( const rips::CaseRequest* request ) +{ + CAF_ASSERT( request ); + m_request = request; + + RimCase* rimCase = RiaGrpcHelper::findCase( m_request->id() ); + m_eclipseCase = dynamic_cast( 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 RiaGrpcSelectedCellsStateHandler::assignNextSelectedCell( rips::SelectedCell* cell, + const std::vector& 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 RiaGrpcSelectedCellsStateHandler::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 RiaGrpcSelectedCellsStateHandler::assignReply( rips::SelectedCells* reply ) +{ + std::vector items; + Riu3dSelectionManager::instance()->selectedItems( items ); + + // Only eclipse cases are currently supported. Also filter by case. + std::vector eclipseItems; + for ( auto item : items ) + { + RiuEclipseSelectionItem* eclipseItem = dynamic_cast( item ); + if ( eclipseItem && eclipseItem->m_resultDefinition->eclipseCase()->caseId() == m_request->id() ) + { + eclipseItems.push_back( eclipseItem ); + } + } + + const size_t packageSize = RiaGrpcHelper::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" ); +} diff --git a/GrpcInterface/RiaGrpcSelectedCellsStateHandler.h b/GrpcInterface/RiaGrpcSelectedCellsStateHandler.h new file mode 100644 index 00000000000..d850d34a9f0 --- /dev/null +++ b/GrpcInterface/RiaGrpcSelectedCellsStateHandler.h @@ -0,0 +1,55 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2025 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 +// for more details. +// +////////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "Case.grpc.pb.h" + +#include "RiaGrpcServiceInterface.h" + +#include + +namespace rips +{ +class CaseRequest; +} // namespace rips + +class RimEclipseCase; +class RiuEclipseSelectionItem; + +//================================================================================================== +// +// State handler for streaming of selected cells +// +//================================================================================================== +class RiaGrpcSelectedCellsStateHandler +{ + using Status = grpc::Status; + +public: + RiaGrpcSelectedCellsStateHandler(); + + 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& items ); + +protected: + const rips::CaseRequest* m_request; + RimEclipseCase* m_eclipseCase; + size_t m_currentItem; +}; From 93c5d952a842d96407eba57071fab1459b7f2408 Mon Sep 17 00:00:00 2001 From: jonjenssen <69144954+jonjenssen@users.noreply.github.com> Date: Fri, 19 Dec 2025 14:14:56 +0000 Subject: [PATCH 03/11] Python code linting changes detected by black --- .../case_and_grid_operations/fault_distance.py | 9 +++++++-- GrpcInterface/Python/rips/case.py | 7 +++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/GrpcInterface/Python/rips/PythonExamples/case_and_grid_operations/fault_distance.py b/GrpcInterface/Python/rips/PythonExamples/case_and_grid_operations/fault_distance.py index c33ff378979..dd12e052ee5 100644 --- a/GrpcInterface/Python/rips/PythonExamples/case_and_grid_operations/fault_distance.py +++ b/GrpcInterface/Python/rips/PythonExamples/case_and_grid_operations/fault_distance.py @@ -22,9 +22,14 @@ print("Looking for closest fault to point %f, %f, %f:" % (point_x, point_y, point_z)) -distance, faultname, facename = case.distance_to_closest_fault(point_x, point_y, point_z) +distance, faultname, facename = case.distance_to_closest_fault( + point_x, point_y, point_z +) if facename == "": print("- No fault found!") else: - print("- Distance to closest fault %s is %f, closest face direction is %s" % (faultname, distance, facename)) + print( + "- Distance to closest fault %s is %f, closest face direction is %s" + % (faultname, distance, facename) + ) diff --git a/GrpcInterface/Python/rips/case.py b/GrpcInterface/Python/rips/case.py index 29e9732800e..518f457d6bb 100644 --- a/GrpcInterface/Python/rips/case.py +++ b/GrpcInterface/Python/rips/case.py @@ -300,13 +300,12 @@ def reservoir_boundingbox(self): """ return self.__case_stub.GetReservoirBoundingBox(self.__request()) + @add_method(Case) def distance_to_closest_fault(self, x: float, y: float, z: float): - """Find the closest fault to the given point and return the distance, fault name and fault face - """ + """Find the closest fault to the given point and return the distance, fault name and fault face""" request = Case_pb2.ClosestFaultRequest( - case_request=self.__request(), - point=Definitions_pb2.Vec3d(x=x, y=y, z=z) + case_request=self.__request(), point=Definitions_pb2.Vec3d(x=x, y=y, z=z) ) reply = self.__case_stub.GetDistanceToClosestFault(request) From 3b9f9bc47a8990c78e4a876dc2ac51be2bf9f71e Mon Sep 17 00:00:00 2001 From: jonjenssen Date: Fri, 19 Dec 2025 15:51:16 +0100 Subject: [PATCH 04/11] Clean up --- GrpcInterface/GrpcProtos/Case.proto | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GrpcInterface/GrpcProtos/Case.proto b/GrpcInterface/GrpcProtos/Case.proto index 148d40d11ca..77aedf1174f 100644 --- a/GrpcInterface/GrpcProtos/Case.proto +++ b/GrpcInterface/GrpcProtos/Case.proto @@ -111,7 +111,7 @@ message ClosestFaultRequest { } message ClosestFault { - string fault_name = 1; - double distance = 2; - string face_name = 3; + string fault_name = 1; + double distance = 2; + string face_name = 3; } From 2e9ef381fab9b040965abb067bbc636ee26b450d Mon Sep 17 00:00:00 2001 From: jonjenssen Date: Fri, 19 Dec 2025 17:29:04 +0100 Subject: [PATCH 05/11] Add python test --- .../Python/rips/tests/test_faults.py | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 GrpcInterface/Python/rips/tests/test_faults.py diff --git a/GrpcInterface/Python/rips/tests/test_faults.py b/GrpcInterface/Python/rips/tests/test_faults.py new file mode 100644 index 00000000000..77d5ae9cd80 --- /dev/null +++ b/GrpcInterface/Python/rips/tests/test_faults.py @@ -0,0 +1,36 @@ +import sys +import os +import math +import pytest + +sys.path.insert(1, os.path.join(sys.path[0], "../../")) +import rips + +import dataroot + +def test_faultDistance(rips_instance, initialize_test): + case = rips_instance.project.load_case( + dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" + ) + + # a test point + point_x = 5039.84 + point_y = 6303.76 + point_z = 4144.21 + + distance, faultname, facename = case.distance_to_closest_fault( point_x, point_y, point_z) + + assert faultname == "Undefined Grid Faults" + assert facename == "J+" + assert math.isclose(distance, 533.57, abs_tol=0.1) + + # another test point + point_x = 4656.43 + point_y = 4713.60 + point_z = 4147.21 + + distance, faultname, facename = case.distance_to_closest_fault( point_x, point_y, point_z) + + assert faultname == "Undefined Grid Faults" + assert facename == "J+" + assert math.isclose(distance, 225.28, abs_tol=0.1) From 98e23d9db6061c3eb65af4c768c40fa5a0442819 Mon Sep 17 00:00:00 2001 From: jonjenssen <69144954+jonjenssen@users.noreply.github.com> Date: Fri, 19 Dec 2025 16:29:28 +0000 Subject: [PATCH 06/11] Python code linting changes detected by black --- GrpcInterface/Python/rips/tests/test_faults.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/GrpcInterface/Python/rips/tests/test_faults.py b/GrpcInterface/Python/rips/tests/test_faults.py index 77d5ae9cd80..2063a4b1e4e 100644 --- a/GrpcInterface/Python/rips/tests/test_faults.py +++ b/GrpcInterface/Python/rips/tests/test_faults.py @@ -8,6 +8,7 @@ import dataroot + def test_faultDistance(rips_instance, initialize_test): case = rips_instance.project.load_case( dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" @@ -18,7 +19,9 @@ def test_faultDistance(rips_instance, initialize_test): point_y = 6303.76 point_z = 4144.21 - distance, faultname, facename = case.distance_to_closest_fault( point_x, point_y, point_z) + distance, faultname, facename = case.distance_to_closest_fault( + point_x, point_y, point_z + ) assert faultname == "Undefined Grid Faults" assert facename == "J+" @@ -29,7 +32,9 @@ def test_faultDistance(rips_instance, initialize_test): point_y = 4713.60 point_z = 4147.21 - distance, faultname, facename = case.distance_to_closest_fault( point_x, point_y, point_z) + distance, faultname, facename = case.distance_to_closest_fault( + point_x, point_y, point_z + ) assert faultname == "Undefined Grid Faults" assert facename == "J+" From e75b59253daca466eb90cab7185fe0539ee68b62 Mon Sep 17 00:00:00 2001 From: jonjenssen Date: Fri, 19 Dec 2025 17:50:37 +0100 Subject: [PATCH 07/11] Clean up parameter order --- ApplicationLibCode/ReservoirDataModel/RigMainGrid.cpp | 6 +++--- ApplicationLibCode/ReservoirDataModel/RigMainGrid.h | 2 +- .../case_and_grid_operations/fault_distance.py | 2 +- GrpcInterface/Python/rips/case.py | 2 +- GrpcInterface/Python/rips/tests/test_faults.py | 4 ++-- GrpcInterface/RiaGrpcCaseService.cpp | 9 ++++----- 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.cpp b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.cpp index 05a47e62e78..89901737cc3 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.cpp @@ -810,9 +810,9 @@ const RigFault* RigMainGrid::findFaultFromCellIndexAndCellFace( size_t reservoir } //-------------------------------------------------------------------------------------------------- -/// +/// Returns the name of the closest fault, the distance to the fault, and the face type of the closest face //-------------------------------------------------------------------------------------------------- -std::tuple RigMainGrid::minimumDistanceFaultToPoint( const cvf::Vec3d& point ) const +std::tuple RigMainGrid::minimumDistanceFaultToPoint( const cvf::Vec3d& point ) const { double minDistance = std::numeric_limits::max(); cvf::StructGridInterface::FaceType minFace = cvf::StructGridInterface::FaceType::NO_FACE; @@ -828,7 +828,7 @@ std::tuple RigMainGrid::min minFaultName = fault->name(); } } - return { minDistance, minFace, minFaultName }; + return { minFaultName, minDistance, minFace }; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h index 4d1414bb326..dc401f997ee 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h +++ b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h @@ -118,7 +118,7 @@ class RigMainGrid : public RigGridBase // invalidate all cells with I > iLimit (0 based index) void invalidateCellsAboveI( size_t iLimit ); - std::tuple minimumDistanceFaultToPoint( const cvf::Vec3d& point ) const; + std::tuple minimumDistanceFaultToPoint( const cvf::Vec3d& point ) const; protected: // only for use by file readers and internal services. TODO: replace with a better API friend class RigGridBase; diff --git a/GrpcInterface/Python/rips/PythonExamples/case_and_grid_operations/fault_distance.py b/GrpcInterface/Python/rips/PythonExamples/case_and_grid_operations/fault_distance.py index dd12e052ee5..27014746e23 100644 --- a/GrpcInterface/Python/rips/PythonExamples/case_and_grid_operations/fault_distance.py +++ b/GrpcInterface/Python/rips/PythonExamples/case_and_grid_operations/fault_distance.py @@ -22,7 +22,7 @@ print("Looking for closest fault to point %f, %f, %f:" % (point_x, point_y, point_z)) -distance, faultname, facename = case.distance_to_closest_fault( +faultname, distance, facename = case.distance_to_closest_fault( point_x, point_y, point_z ) diff --git a/GrpcInterface/Python/rips/case.py b/GrpcInterface/Python/rips/case.py index 518f457d6bb..9123c369a27 100644 --- a/GrpcInterface/Python/rips/case.py +++ b/GrpcInterface/Python/rips/case.py @@ -309,7 +309,7 @@ def distance_to_closest_fault(self, x: float, y: float, z: float): ) reply = self.__case_stub.GetDistanceToClosestFault(request) - return (reply.distance, reply.fault_name, reply.face_name) + return (reply.fault_name, reply.distance, reply.face_name) @add_method(Case) diff --git a/GrpcInterface/Python/rips/tests/test_faults.py b/GrpcInterface/Python/rips/tests/test_faults.py index 2063a4b1e4e..2cf79f1a71f 100644 --- a/GrpcInterface/Python/rips/tests/test_faults.py +++ b/GrpcInterface/Python/rips/tests/test_faults.py @@ -19,7 +19,7 @@ def test_faultDistance(rips_instance, initialize_test): point_y = 6303.76 point_z = 4144.21 - distance, faultname, facename = case.distance_to_closest_fault( + faultname, distance, facename = case.distance_to_closest_fault( point_x, point_y, point_z ) @@ -32,7 +32,7 @@ def test_faultDistance(rips_instance, initialize_test): point_y = 4713.60 point_z = 4147.21 - distance, faultname, facename = case.distance_to_closest_fault( + faultname, distance, facename = case.distance_to_closest_fault( point_x, point_y, point_z ) diff --git a/GrpcInterface/RiaGrpcCaseService.cpp b/GrpcInterface/RiaGrpcCaseService.cpp index 6604297d87d..42710eabfa8 100644 --- a/GrpcInterface/RiaGrpcCaseService.cpp +++ b/GrpcInterface/RiaGrpcCaseService.cpp @@ -286,6 +286,9 @@ grpc::Status RiaGrpcCaseService::GetCoarseningInfoArray( grpc::ServerContext* return Status( grpc::NOT_FOUND, "Case not found" ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- grpc::Status RiaGrpcCaseService::GetDistanceToClosestFault( grpc::ServerContext* context, const rips::ClosestFaultRequest* request, rips::ClosestFault* reply ) @@ -296,11 +299,7 @@ grpc::Status RiaGrpcCaseService::GetDistanceToClosestFault( grpc::ServerContext* cvf::Vec3d point( request->point() ); point.z() = -point.z(); // Convert to internal coordinate system - double distance = 0.0; - cvf::StructGridInterface::FaceType faceType; - QString faultName; - - std::tie( distance, faceType, faultName ) = eCase->mainGrid()->minimumDistanceFaultToPoint( point ); + auto [faultName, distance, faceType] = eCase->mainGrid()->minimumDistanceFaultToPoint( point ); reply->set_distance( distance ); reply->set_face_name( RiaGrpcHelper::faceTypeToString( faceType ) ); From 9d11e9449254190a81004534561f96a5a296b853 Mon Sep 17 00:00:00 2001 From: jonjenssen Date: Fri, 19 Dec 2025 17:57:39 +0100 Subject: [PATCH 08/11] Some cleanup --- GrpcInterface/RiaGrpcActiveCellInfoStateHandler.h | 9 --------- GrpcInterface/RiaGrpcCaseService.cpp | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/GrpcInterface/RiaGrpcActiveCellInfoStateHandler.h b/GrpcInterface/RiaGrpcActiveCellInfoStateHandler.h index 9831fa921e6..5566ae981eb 100644 --- a/GrpcInterface/RiaGrpcActiveCellInfoStateHandler.h +++ b/GrpcInterface/RiaGrpcActiveCellInfoStateHandler.h @@ -19,22 +19,13 @@ #include "Case.grpc.pb.h" -// #include "RiaGrpcServiceInterface.h" #include "RiaPorosityModel.h" #include -// namespace rips -//{ -// class CaseRequest; -// class PdmObject; -// } // namespace rips - -// class RiaGrpcCallbackInterface; class RigCell; class RigActiveCellInfo; class RimEclipseCase; -// class RiuEclipseSelectionItem; //================================================================================================== // diff --git a/GrpcInterface/RiaGrpcCaseService.cpp b/GrpcInterface/RiaGrpcCaseService.cpp index 42710eabfa8..1e74209dbed 100644 --- a/GrpcInterface/RiaGrpcCaseService.cpp +++ b/GrpcInterface/RiaGrpcCaseService.cpp @@ -307,7 +307,7 @@ grpc::Status RiaGrpcCaseService::GetDistanceToClosestFault( grpc::ServerContext* return grpc::Status::OK; } - return Status( grpc::NOT_FOUND, "Case not found" ); + return Status( grpc::NOT_FOUND, "Eclipse Case not found" ); } //-------------------------------------------------------------------------------------------------- From 8a3b85c17b53235234aa41e5f3769813f6c5e06b Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Sat, 20 Dec 2025 08:51:08 +0100 Subject: [PATCH 09/11] Skips unstable fault name check The fault name is unstable between grid readers, so the check is skipped. This avoids false positives during testing. --- GrpcInterface/Python/rips/tests/test_faults.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/GrpcInterface/Python/rips/tests/test_faults.py b/GrpcInterface/Python/rips/tests/test_faults.py index 2cf79f1a71f..70661f9e465 100644 --- a/GrpcInterface/Python/rips/tests/test_faults.py +++ b/GrpcInterface/Python/rips/tests/test_faults.py @@ -23,7 +23,9 @@ def test_faultDistance(rips_instance, initialize_test): point_x, point_y, point_z ) - assert faultname == "Undefined Grid Faults" + # Fault name is unstable between grid readers, so we skip this check + # assert faultname == "Undefined Grid Faults" + assert facename == "J+" assert math.isclose(distance, 533.57, abs_tol=0.1) @@ -36,6 +38,8 @@ def test_faultDistance(rips_instance, initialize_test): point_x, point_y, point_z ) - assert faultname == "Undefined Grid Faults" + # Fault name is unstable between grid readers, so we skip this check + # assert faultname == "Undefined Grid Faults" + assert facename == "J+" assert math.isclose(distance, 225.28, abs_tol=0.1) From d2ec32711cbbf14e1e754f0b25f9b9a7d9cea63e Mon Sep 17 00:00:00 2001 From: magnesj <1793152+magnesj@users.noreply.github.com> Date: Sat, 20 Dec 2025 07:51:34 +0000 Subject: [PATCH 10/11] Python code linting changes detected by black --- GrpcInterface/Python/rips/tests/test_faults.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GrpcInterface/Python/rips/tests/test_faults.py b/GrpcInterface/Python/rips/tests/test_faults.py index 70661f9e465..3dc02fa32f2 100644 --- a/GrpcInterface/Python/rips/tests/test_faults.py +++ b/GrpcInterface/Python/rips/tests/test_faults.py @@ -25,7 +25,7 @@ def test_faultDistance(rips_instance, initialize_test): # Fault name is unstable between grid readers, so we skip this check # assert faultname == "Undefined Grid Faults" - + assert facename == "J+" assert math.isclose(distance, 533.57, abs_tol=0.1) @@ -40,6 +40,6 @@ def test_faultDistance(rips_instance, initialize_test): # Fault name is unstable between grid readers, so we skip this check # assert faultname == "Undefined Grid Faults" - + assert facename == "J+" assert math.isclose(distance, 225.28, abs_tol=0.1) From 0f44fc615fe5cf5671ee09b71658e79575eddb5d Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Sat, 20 Dec 2025 09:31:34 +0100 Subject: [PATCH 11/11] fix test --- .../Python/rips/tests/test_faults.py | 25 ++++--------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/GrpcInterface/Python/rips/tests/test_faults.py b/GrpcInterface/Python/rips/tests/test_faults.py index 3dc02fa32f2..ff2a31087fb 100644 --- a/GrpcInterface/Python/rips/tests/test_faults.py +++ b/GrpcInterface/Python/rips/tests/test_faults.py @@ -15,9 +15,9 @@ def test_faultDistance(rips_instance, initialize_test): ) # a test point - point_x = 5039.84 - point_y = 6303.76 - point_z = 4144.21 + point_x = 4817.84 + point_y = 5204.76 + point_z = 4137.21 faultname, distance, facename = case.distance_to_closest_fault( point_x, point_y, point_z @@ -26,20 +26,5 @@ def test_faultDistance(rips_instance, initialize_test): # Fault name is unstable between grid readers, so we skip this check # assert faultname == "Undefined Grid Faults" - assert facename == "J+" - assert math.isclose(distance, 533.57, abs_tol=0.1) - - # another test point - point_x = 4656.43 - point_y = 4713.60 - point_z = 4147.21 - - faultname, distance, facename = case.distance_to_closest_fault( - point_x, point_y, point_z - ) - - # Fault name is unstable between grid readers, so we skip this check - # assert faultname == "Undefined Grid Faults" - - assert facename == "J+" - assert math.isclose(distance, 225.28, abs_tol=0.1) + assert facename == "I+" + assert math.isclose(distance, 53.84, abs_tol=0.1)