mirror of
https://github.com/OPM/ResInsight.git
synced 2026-08-27 13:47:12 -05:00
Add python api for creating corner point grid.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include "Cloud/RiaOsduConnector.h"
|
||||
#include "Cloud/RiaSumoConnector.h"
|
||||
#include "Cloud/RiaSumoDefines.h"
|
||||
#include "KeyValueStore/RiaKeyValueStore.h"
|
||||
#include "RiaOsduDefines.h"
|
||||
|
||||
#include "RiaBaseDefs.h"
|
||||
@@ -178,6 +179,8 @@ RiaApplication::RiaApplication()
|
||||
m_commandRouter = std::make_unique<RimCommandRouter>();
|
||||
m_osduConnector = nullptr;
|
||||
m_sumoConnector = nullptr;
|
||||
|
||||
m_keyValueStore = std::make_unique<RiaKeyValueStore<char>>();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -1758,3 +1761,11 @@ void RiaApplication::initializeDataLoadController()
|
||||
dataLoadController->registerDataLoader( RimWellLogFile::classKeywordStatic(), wellLogKeyword, std::make_unique<RimWellLogFileDataLoader>() );
|
||||
dataLoadController->registerDataLoader( RimOsduWellLog::classKeywordStatic(), wellLogKeyword, std::make_unique<RimOsduWellLogDataLoader>() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaKeyValueStore<char>* RiaApplication::keyValueStore() const
|
||||
{
|
||||
return m_keyValueStore.get();
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "KeyValueStore/RiaKeyValueStore.h"
|
||||
#include "RiaDefines.h"
|
||||
|
||||
#include "cafPdmPointer.h"
|
||||
@@ -199,6 +200,8 @@ public:
|
||||
RiaOsduConnector* makeOsduConnector();
|
||||
RiaSumoConnector* makeSumoConnector();
|
||||
|
||||
RiaKeyValueStore<char>* keyValueStore() const;
|
||||
|
||||
protected:
|
||||
// Protected implementation specific overrides
|
||||
virtual void invokeProcessEvents( QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents ) = 0;
|
||||
@@ -237,6 +240,8 @@ protected:
|
||||
QPointer<RiaSocketServer> m_socketServer;
|
||||
std::unique_ptr<caf::UiProcess> m_workerProcess;
|
||||
|
||||
std::unique_ptr<RiaKeyValueStore<char>> m_keyValueStore;
|
||||
|
||||
// Execute for all settings
|
||||
std::list<int> m_scriptCaseIds;
|
||||
int m_currentScriptCaseId;
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaKeyValueStore.h
|
||||
)
|
||||
set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RiaKeyValueStore.h)
|
||||
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
)
|
||||
set(SOURCE_GROUP_SOURCE_FILES)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
|
||||
|
||||
|
||||
@@ -56,14 +56,6 @@ public:
|
||||
|
||||
static bool hasGridData( const QString& filename );
|
||||
|
||||
private:
|
||||
static void interpretSplitenzData( int nz,
|
||||
float zoffset,
|
||||
float zscale,
|
||||
const std::vector<char>& splitenz,
|
||||
const std::vector<float>& zdata,
|
||||
std::vector<float>& zcornsv );
|
||||
|
||||
static size_t computeActiveCellMatrixIndex( std::vector<int>& activeCells );
|
||||
|
||||
static cvf::Vec3d getCorner( const RigMainGrid& grid,
|
||||
@@ -74,6 +66,14 @@ private:
|
||||
const cvf::Vec3d& offset,
|
||||
const cvf::Vec3d& scale );
|
||||
|
||||
private:
|
||||
static void interpretSplitenzData( int nz,
|
||||
float zoffset,
|
||||
float zscale,
|
||||
const std::vector<char>& splitenz,
|
||||
const std::vector<float>& zdata,
|
||||
std::vector<float>& zcornsv );
|
||||
|
||||
static double interpolate( const cvf::Vec3d& top, const cvf::Vec3d& bottom, double z, int idx );
|
||||
|
||||
static std::vector<double>
|
||||
|
||||
@@ -124,7 +124,8 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCameraPosition.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellTargetMapping.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimRegularGridCase.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimGeometrySelectionItem.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimGeometrySelectionItem.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCornerPointCase.h
|
||||
)
|
||||
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
@@ -250,6 +251,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellTargetMapping.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimRegularGridCase.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimGeometrySelectionItem.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCornerPointCase.cpp
|
||||
)
|
||||
|
||||
if(RESINSIGHT_USE_QT_CHARTS)
|
||||
|
||||
@@ -0,0 +1,329 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RimCornerPointCase.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RifInputPropertyLoader.h"
|
||||
#include "RifRoffFileTools.h"
|
||||
|
||||
#include "RigActiveCellInfo.h"
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
#include "RimEclipseInputProperty.h"
|
||||
#include "RimReservoirCellResultsStorage.h"
|
||||
|
||||
#include "cafPdmObjectScriptingCapability.h"
|
||||
#include "cafProgressInfo.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimCornerPointCase, "RimCornerPointCase" );
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCornerPointCase::RimCornerPointCase()
|
||||
: RimEclipseCase()
|
||||
{
|
||||
CAF_PDM_InitScriptableObject( "RimCornerPointCase", ":/EclipseInput48x48.png" );
|
||||
setReservoirData( new RigEclipseCaseData( this ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCornerPointCase::~RimCornerPointCase()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCornerPointCase::openEclipseGridFile()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<RimCornerPointCase*, QString> RimCornerPointCase::createFromCoordinatesArray( const int nx,
|
||||
const int ny,
|
||||
const int nz,
|
||||
const std::vector<float>& coord,
|
||||
const std::vector<float>& zcorn,
|
||||
const std::vector<float>& actnum )
|
||||
{
|
||||
CAF_ASSERT( nx > 0 );
|
||||
CAF_ASSERT( ny > 0 );
|
||||
CAF_ASSERT( nz > 0 );
|
||||
|
||||
size_t ncoord = ( nx + 1 ) * ( ny + 1 ) * 2 * 3;
|
||||
size_t nzcorn = nx * ny * nz * 8;
|
||||
size_t ntot = nx * ny * nz;
|
||||
|
||||
if ( coord.size() != ncoord )
|
||||
return { nullptr, QString( "Wrong size of coord array. Expected %1, but got %2" ).arg( ncoord ).arg( coord.size() ) };
|
||||
|
||||
if ( zcorn.size() != nzcorn )
|
||||
return { nullptr, QString( "Wrong size of zcorn array. Expected %1, but got %2" ).arg( nzcorn ).arg( zcorn.size() ) };
|
||||
|
||||
if ( actnum.size() != ntot )
|
||||
return { nullptr, QString( "Wrong size of actnum array. Expected %1, but got %2" ).arg( ntot ).arg( actnum.size() ) };
|
||||
|
||||
auto cornerPointCase = new RimCornerPointCase;
|
||||
|
||||
buildGrid( *cornerPointCase->eclipseCaseData(), nx, ny, nz, coord, zcorn, actnum );
|
||||
cornerPointCase->ensureFaultDataIsComputed();
|
||||
|
||||
return { cornerPointCase, "" };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::array<cvf::Vec3d, 8> RimCornerPointCase::getCorners( const RigMainGrid& grid,
|
||||
const std::vector<float>& coord,
|
||||
const std::vector<float>& zcorn,
|
||||
const size_t cellIdx,
|
||||
const cvf::Vec3d& offset,
|
||||
const cvf::Vec3d& scale )
|
||||
{
|
||||
size_t i;
|
||||
size_t j;
|
||||
size_t k;
|
||||
grid.ijkFromCellIndex( cellIdx, &i, &j, &k );
|
||||
|
||||
const size_t nx = grid.cellCountI();
|
||||
const size_t ny = grid.cellCountJ();
|
||||
|
||||
// Get depths from zcorn
|
||||
std::array<size_t, 8> zind;
|
||||
zind[0] = ( k * nx * ny * 8 + j * nx * 4 + i * 2 );
|
||||
zind[1] = ( zind[0] + 1 );
|
||||
zind[2] = ( zind[0] + nx * 2 );
|
||||
zind[3] = ( zind[2] + 1 );
|
||||
|
||||
for ( size_t n = 0; n < 4; n++ )
|
||||
zind[n + 4] = ( zind[n] + nx * ny * 4 );
|
||||
|
||||
std::array<cvf::Vec3d, 8> corners;
|
||||
for ( size_t n = 0; n < 8; n++ )
|
||||
corners[n].z() = zcorn[zind[n]];
|
||||
|
||||
// calculate indices for grid pillars in COORD arrray
|
||||
std::array<size_t, 4> pind;
|
||||
pind[0] = j * ( nx + 1 ) * 6 + i * 6;
|
||||
pind[1] = pind[0] + 6;
|
||||
pind[2] = pind[0] + ( nx + 1 ) * 6;
|
||||
pind[3] = pind[2] + 6;
|
||||
|
||||
for ( size_t n = 0; n < 4; n++ )
|
||||
{
|
||||
const double zt = coord[pind[n] + 2];
|
||||
const double zb = coord[pind[n] + 5];
|
||||
|
||||
const double xt = coord[pind[n]];
|
||||
const double yt = coord[pind[n] + 1];
|
||||
const double xb = coord[pind[n] + 3];
|
||||
const double yb = coord[pind[n] + 4];
|
||||
|
||||
const double diffZ = zt - zb;
|
||||
|
||||
if ( diffZ == 0.0 )
|
||||
{
|
||||
corners[n].x() = xt;
|
||||
corners[n + 4].x() = xt;
|
||||
corners[n].y() = yt;
|
||||
corners[n + 4].y() = yt;
|
||||
}
|
||||
else
|
||||
{
|
||||
corners[n].x() = xt + ( xb - xt ) / diffZ * ( zt - corners[n].z() );
|
||||
corners[n + 4].x() = xt + ( xb - xt ) / diffZ * ( zt - corners[n + 4].z() );
|
||||
corners[n].y() = yt + ( yb - yt ) / diffZ * ( zt - corners[n].z() );
|
||||
corners[n + 4].y() = yt + ( yb - yt ) / diffZ * ( zt - corners[n + 4].z() );
|
||||
}
|
||||
}
|
||||
|
||||
return corners;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCornerPointCase::buildGrid( RigEclipseCaseData& eclipseCaseData,
|
||||
const int nx,
|
||||
const int ny,
|
||||
const int nz,
|
||||
const std::vector<float>& coord,
|
||||
const std::vector<float>& zcorn,
|
||||
const std::vector<float>& actnum )
|
||||
{
|
||||
auto startTime = high_resolution_clock::now();
|
||||
|
||||
RigActiveCellInfo* activeCellInfo = eclipseCaseData.activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||
CVF_ASSERT( activeCellInfo );
|
||||
|
||||
RigActiveCellInfo* fractureActiveCellInfo = eclipseCaseData.activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL );
|
||||
CVF_ASSERT( fractureActiveCellInfo );
|
||||
|
||||
RigMainGrid* mainGrid = eclipseCaseData.mainGrid();
|
||||
CVF_ASSERT( mainGrid );
|
||||
|
||||
cvf::Vec3st gridPointDim( nx + 1, ny + 1, nz + 1 );
|
||||
mainGrid->setGridPointDimensions( gridPointDim );
|
||||
mainGrid->setGridName( "Main grid" );
|
||||
|
||||
size_t totalCellCount = nx * ny * nz;
|
||||
|
||||
activeCellInfo->setGridCount( 1 );
|
||||
fractureActiveCellInfo->setGridCount( 1 );
|
||||
|
||||
activeCellInfo->setReservoirCellCount( totalCellCount );
|
||||
fractureActiveCellInfo->setReservoirCellCount( totalCellCount );
|
||||
|
||||
// Reserve room for the cells and nodes and fill them with data
|
||||
mainGrid->reservoirCells().reserve( totalCellCount );
|
||||
mainGrid->nodes().reserve( 8 * totalCellCount );
|
||||
|
||||
int progTicks = 100;
|
||||
caf::ProgressInfo progInfo( progTicks, "" );
|
||||
|
||||
int cellCount = static_cast<int>( totalCellCount );
|
||||
size_t cellStartIndex = mainGrid->reservoirCells().size();
|
||||
size_t nodeStartIndex = mainGrid->nodes().size();
|
||||
|
||||
RigCell defaultCell;
|
||||
defaultCell.setHostGrid( mainGrid );
|
||||
mainGrid->reservoirCells().resize( cellStartIndex + cellCount, defaultCell );
|
||||
|
||||
mainGrid->nodes().resize( nodeStartIndex + static_cast<size_t>( cellCount ) * 8, cvf::Vec3d( 0, 0, 0 ) );
|
||||
|
||||
const size_t cellMappingECLRi[8] = { 0, 1, 3, 2, 4, 5, 7, 6 };
|
||||
|
||||
cvf::Vec3d offset( 0.0, 0.0, 0.0 );
|
||||
cvf::Vec3d scale( 1.0, 1.0, 1.0 );
|
||||
|
||||
// Convert actnum to integer
|
||||
std::vector<int> activeCells( nx * ny * nz, 0 );
|
||||
CAF_ASSERT( activeCells.size() == actnum.size() );
|
||||
for ( size_t i = 0; i < activeCells.size(); i++ )
|
||||
{
|
||||
activeCells[i] = static_cast<int>( actnum[i] > 0.0 );
|
||||
}
|
||||
|
||||
// Precompute the active cell matrix index
|
||||
size_t numActiveCells = RifRoffFileTools::computeActiveCellMatrixIndex( activeCells );
|
||||
|
||||
// Loop over cells and fill them with data
|
||||
#pragma omp for
|
||||
for ( int gridLocalCellIndex = 0; gridLocalCellIndex < cellCount; ++gridLocalCellIndex )
|
||||
{
|
||||
RigCell& cell = mainGrid->cell( cellStartIndex + gridLocalCellIndex );
|
||||
|
||||
cell.setGridLocalCellIndex( gridLocalCellIndex );
|
||||
|
||||
// Active cell index
|
||||
int matrixActiveIndex = activeCells[gridLocalCellIndex];
|
||||
if ( matrixActiveIndex != -1 )
|
||||
{
|
||||
activeCellInfo->setCellResultIndex( cellStartIndex + gridLocalCellIndex, matrixActiveIndex );
|
||||
}
|
||||
|
||||
cell.setParentCellIndex( cvf::UNDEFINED_SIZE_T );
|
||||
|
||||
std::array<cvf::Vec3d, 8> corners = getCorners( *mainGrid, coord, zcorn, gridLocalCellIndex, offset, scale );
|
||||
|
||||
// Corner coordinates
|
||||
for ( int cIdx = 0; cIdx < 8; ++cIdx )
|
||||
{
|
||||
double* point = mainGrid->nodes()[nodeStartIndex + (size_t)gridLocalCellIndex * 8 + cellMappingECLRi[cIdx]].ptr();
|
||||
|
||||
point[0] = corners[cIdx].x();
|
||||
point[1] = corners[cIdx].y();
|
||||
point[2] = -corners[cIdx].z();
|
||||
|
||||
cell.cornerIndices()[cIdx] = nodeStartIndex + (size_t)gridLocalCellIndex * 8 + cIdx;
|
||||
}
|
||||
|
||||
// Mark inactive long pyramid looking cells as invalid
|
||||
cell.setInvalid( cell.isLongPyramidCell() );
|
||||
}
|
||||
|
||||
activeCellInfo->setGridActiveCellCounts( 0, numActiveCells );
|
||||
fractureActiveCellInfo->setGridActiveCellCounts( 0, 0 );
|
||||
|
||||
mainGrid->initAllSubGridsParentGridPointer();
|
||||
activeCellInfo->computeDerivedData();
|
||||
fractureActiveCellInfo->computeDerivedData();
|
||||
|
||||
auto endTime = high_resolution_clock::now();
|
||||
|
||||
auto totalDuration = duration_cast<milliseconds>( endTime - startTime );
|
||||
RiaLogging::info( QString( "Total: %1 ms" ).arg( totalDuration.count() ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCornerPointCase::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
uiOrdering.add( &m_caseUserDescription );
|
||||
uiOrdering.add( &m_displayNameOption );
|
||||
uiOrdering.add( &m_caseId );
|
||||
uiOrdering.add( &m_caseFileName );
|
||||
|
||||
auto group = uiOrdering.addNewGroup( "Case Options" );
|
||||
group->add( &m_activeFormationNames );
|
||||
group->add( &m_flipXAxis );
|
||||
group->add( &m_flipYAxis );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimCornerPointCase::locationOnDisc() const
|
||||
{
|
||||
if ( gridFileName().isEmpty() ) return QString();
|
||||
|
||||
QFileInfo fi( gridFileName() );
|
||||
return fi.absolutePath();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCornerPointCase::importAsciiInputProperties( const QStringList& fileNames )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RimEclipseCase.h"
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RimCornerPointCase : public RimEclipseCase
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimCornerPointCase();
|
||||
~RimCornerPointCase() override;
|
||||
|
||||
bool openEclipseGridFile() override;
|
||||
|
||||
bool importAsciiInputProperties( const QStringList& fileNames ) override;
|
||||
|
||||
QString locationOnDisc() const override;
|
||||
|
||||
static std::pair<RimCornerPointCase*, QString> createFromCoordinatesArray( const int nx,
|
||||
const int ny,
|
||||
const int nz,
|
||||
const std::vector<float>& coord,
|
||||
const std::vector<float>& zcorn,
|
||||
const std::vector<float>& actnum );
|
||||
|
||||
protected:
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
|
||||
static void buildGrid( RigEclipseCaseData& eclipseCaseData,
|
||||
const int nx,
|
||||
const int ny,
|
||||
const int nz,
|
||||
const std::vector<float>& coord,
|
||||
const std::vector<float>& zcorn,
|
||||
const std::vector<float>& actnum );
|
||||
|
||||
static std::array<cvf::Vec3d, 8> getCorners( const RigMainGrid& grid,
|
||||
const std::vector<float>& coord,
|
||||
const std::vector<float>& zcorn,
|
||||
const size_t cellIdx,
|
||||
const cvf::Vec3d& offset,
|
||||
const cvf::Vec3d& scale );
|
||||
};
|
||||
@@ -20,14 +20,22 @@
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaGuiApplication.h"
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RicImportSummaryCasesFeature.h"
|
||||
|
||||
#include "RimCornerPointCase.h"
|
||||
#include "RimEclipseCaseCollection.h"
|
||||
#include "RimEclipseCellColors.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimFileSummaryCase.h"
|
||||
#include "RimMainPlotCollection.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryCase.h"
|
||||
#include "RimSurfaceCollection.h"
|
||||
|
||||
#include "RiuMainWindow.h"
|
||||
#include "RiuPlotMainWindow.h"
|
||||
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
@@ -220,3 +228,150 @@ bool RimProject_surfaceFolder::isNullptrValidResult() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimProject, RimProject_createGridFromKeyValues, "createGridFromKeyValues" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimProject_createGridFromKeyValues::RimProject_createGridFromKeyValues( caf::PdmObjectHandle* self )
|
||||
: caf::PdmObjectMethod( self )
|
||||
{
|
||||
CAF_PDM_InitObject( "Create grid from key values", "", "", "Create Grid From Key Values" );
|
||||
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_name, "Name", "" );
|
||||
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_nx, "Nx", "" );
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_ny, "Ny", "" );
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_nz, "Nz", "" );
|
||||
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_coordKey, "CoordKey", "" );
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_zcornKey, "ZcornKey", "" );
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_actnumKey, "ActnumKey", "" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmObjectHandle* RimProject_createGridFromKeyValues::execute()
|
||||
{
|
||||
RiaLogging::info( "Creating grid from key values" );
|
||||
|
||||
QString name = m_name();
|
||||
if ( name.isEmpty() )
|
||||
{
|
||||
RiaLogging::error( "Empty name not allowed" );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int nx = m_nx();
|
||||
int ny = m_ny();
|
||||
int nz = m_nz();
|
||||
|
||||
RiaLogging::info( QString( "Grid dimensions: [%1 %2 %3]" ).arg( nx ).arg( ny ).arg( nz ) );
|
||||
RiaLogging::info( QString( "Coord: %1" ).arg( m_coordKey() ) );
|
||||
RiaLogging::info( QString( "Zcorn: %1" ).arg( m_zcornKey() ) );
|
||||
RiaLogging::info( QString( "Actnum: %1" ).arg( m_actnumKey() ) );
|
||||
|
||||
auto keyValueStore = RiaApplication::instance()->keyValueStore();
|
||||
|
||||
auto convertToFloatVector = []( const std::optional<std::vector<char>>& input ) -> std::vector<float>
|
||||
{
|
||||
if ( input && !input->empty() )
|
||||
{
|
||||
// Ensure the byte vector size is a multiple of sizeof(float)
|
||||
if ( input->size() % sizeof( float ) != 0 )
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// Calculate how many floats we'll have
|
||||
size_t float_count = input->size() / sizeof( float );
|
||||
|
||||
// Create a vector of floats with the appropriate size
|
||||
std::vector<float> float_vec( float_count );
|
||||
|
||||
// Copy the binary data from the byte vector to the float vector
|
||||
std::memcpy( float_vec.data(), input->data(), input->size() );
|
||||
|
||||
return float_vec;
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
std::vector<float> coord = convertToFloatVector( keyValueStore->get( m_coordKey().toStdString() ) );
|
||||
std::vector<float> zcorn = convertToFloatVector( keyValueStore->get( m_zcornKey().toStdString() ) );
|
||||
std::vector<float> actnum = convertToFloatVector( keyValueStore->get( m_actnumKey().toStdString() ) );
|
||||
if ( coord.empty() || zcorn.empty() || actnum.empty() )
|
||||
{
|
||||
RiaLogging::error( "Found unexcepted empty coord, zcorn or actnum array." );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto [grid, errorMessage] = RimCornerPointCase::createFromCoordinatesArray( nx, ny, nz, coord, zcorn, actnum );
|
||||
if ( grid )
|
||||
{
|
||||
RimProject* project = RimProject::current();
|
||||
if ( !project ) return nullptr;
|
||||
|
||||
grid->setCustomCaseName( name );
|
||||
project->assignCaseIdToCase( grid );
|
||||
|
||||
RimEclipseCaseCollection* analysisModels = project->activeOilField() ? project->activeOilField()->analysisModels() : nullptr;
|
||||
if ( !analysisModels ) return nullptr;
|
||||
|
||||
analysisModels->cases.push_back( grid );
|
||||
|
||||
RimMainPlotCollection::current()->ensureDefaultFlowPlotsAreCreated();
|
||||
|
||||
RimEclipseView* riv = grid->createAndAddReservoirView();
|
||||
riv->loadDataAndUpdate();
|
||||
|
||||
if ( !riv->cellResult()->hasResult() )
|
||||
{
|
||||
riv->cellResult()->setResultVariable( RiaResultNames::undefinedResultName() );
|
||||
}
|
||||
|
||||
analysisModels->updateConnectedEditors();
|
||||
|
||||
if ( RiaGuiApplication::isRunning() )
|
||||
{
|
||||
if ( RiuMainWindow::instance() ) RiuMainWindow::instance()->selectAsCurrentItem( riv->cellResult() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( QString( "Creating corner point grid failed: %1" ).arg( errorMessage ) );
|
||||
}
|
||||
|
||||
keyValueStore->remove( m_coordKey().toStdString() );
|
||||
keyValueStore->remove( m_zcornKey().toStdString() );
|
||||
keyValueStore->remove( m_actnumKey().toStdString() );
|
||||
|
||||
return grid;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimProject_createGridFromKeyValues::resultIsPersistent() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::unique_ptr<caf::PdmObjectHandle> RimProject_createGridFromKeyValues::defaultResult() const
|
||||
{
|
||||
return std::unique_ptr<caf::PdmObjectHandle>( new RimCornerPointCase );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimProject_createGridFromKeyValues::isNullptrValidResult() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -82,3 +82,28 @@ public:
|
||||
private:
|
||||
caf::PdmField<QString> m_folderName;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimProject_createGridFromKeyValues : public caf::PdmObjectMethod
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimProject_createGridFromKeyValues( caf::PdmObjectHandle* self );
|
||||
|
||||
caf::PdmObjectHandle* execute() override;
|
||||
bool resultIsPersistent() const override;
|
||||
std::unique_ptr<PdmObjectHandle> defaultResult() const override;
|
||||
bool isNullptrValidResult() const override;
|
||||
|
||||
private:
|
||||
caf::PdmField<QString> m_name;
|
||||
caf::PdmField<int> m_nx;
|
||||
caf::PdmField<int> m_ny;
|
||||
caf::PdmField<int> m_nz;
|
||||
caf::PdmField<QString> m_coordKey;
|
||||
caf::PdmField<QString> m_zcornKey;
|
||||
caf::PdmField<QString> m_actnumKey;
|
||||
};
|
||||
|
||||
@@ -123,6 +123,7 @@ protected: // only for use by file readers and internal services. TODO: replace
|
||||
friend class RiaGrpcCaseService;
|
||||
friend class RiaActiveCellInfoStateHandler;
|
||||
friend class RicCreateTemporaryLgrFeature;
|
||||
friend class RimCornerPointCase;
|
||||
std::vector<RigCell>& reservoirCells();
|
||||
const std::vector<RigCell>& reservoirCells() const;
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
RiaGrpcCommandService.h
|
||||
RiaGrpcAppService.h
|
||||
RiaGrpcPropertiesService.h
|
||||
RiaGrpcKeyValueStoreService.h
|
||||
RiaGrpcNNCPropertiesService.h
|
||||
RiaGrpcPdmObjectService.h
|
||||
RiaGrpcApplicationInterface.h
|
||||
@@ -49,6 +50,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
RiaGrpcCommandService.cpp
|
||||
RiaGrpcAppService.cpp
|
||||
RiaGrpcPropertiesService.cpp
|
||||
RiaGrpcKeyValueStoreService.cpp
|
||||
RiaGrpcNNCPropertiesService.cpp
|
||||
RiaGrpcPdmObjectService.cpp
|
||||
RiaGrpcApplicationInterface.cpp)
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package rips;
|
||||
|
||||
import "Definitions.proto";
|
||||
|
||||
service KeyValueStore {
|
||||
rpc SetValue(stream KeyValueStoreInputChunk)
|
||||
returns (ClientToServerStreamReply) {}
|
||||
}
|
||||
|
||||
message KeyValueStoreInputChunk {
|
||||
oneof KeyValueStoreChunkType {
|
||||
KeyValueInputParameters parameters = 1;
|
||||
KeyValueStoreChunk values = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message KeyValueInputParameters {
|
||||
// Name needs to be sent in the first message
|
||||
string name = 1;
|
||||
int64 num_elements = 2;
|
||||
}
|
||||
|
||||
message KeyValueStoreChunk { repeated float values = 1; }
|
||||
@@ -0,0 +1,41 @@
|
||||
######################################################################
|
||||
# This script creates a corner point grid from a Eclipse coord, zcorn
|
||||
# and actnum configuration.
|
||||
######################################################################
|
||||
import rips
|
||||
import xtgeo
|
||||
from xtgeo.grid3d._egrid import EGrid, RockModel
|
||||
from xtgeo.io._file import FileFormat, FileWrapper
|
||||
import numpy as np
|
||||
|
||||
grid_filepath = "/home/resinsight/testdata/01_drogon_ahm/realization-0/iter-0/eclipse/model/DROGON-0.EGRID"
|
||||
|
||||
name = "DROGON-0 from python"
|
||||
|
||||
grid = EGrid.from_file(grid_filepath, fileformat=FileFormat.EGRID)
|
||||
print("Grid: ", grid)
|
||||
print("Grid type: ", type(grid))
|
||||
print("coord: ", grid.coord.shape, grid.coord.dtype)
|
||||
print("zcorn:", grid.zcorn.shape, grid.zcorn.dtype)
|
||||
print("actnum: ", grid.actnum.shape, grid.actnum.dtype)
|
||||
|
||||
resinsight = rips.Instance.find()
|
||||
|
||||
project = resinsight.project
|
||||
|
||||
coord = np.ascontiguousarray(grid.coord, dtype=np.float32)
|
||||
zcorn = np.ascontiguousarray(grid.zcorn, dtype=np.float32)
|
||||
actnum = np.ascontiguousarray(grid.actnum, dtype=np.int32)
|
||||
|
||||
|
||||
print("coordsv: ", len(coord), type(coord[0]))
|
||||
print("zcornsv: ", len(zcorn), type(zcorn[0]))
|
||||
print("actnumsv: ", len(actnum), type(actnum[0]))
|
||||
|
||||
|
||||
print("Grid dimensions: ", grid.dimensions)
|
||||
nx = grid.dimensions.ncol
|
||||
ny = grid.dimensions.nrow
|
||||
nz = grid.dimensions.nlay
|
||||
|
||||
project.create_corner_point_grid(name, nx, ny, nz, coord, zcorn, actnum)
|
||||
@@ -3,8 +3,10 @@
|
||||
"""
|
||||
The ResInsight project module
|
||||
"""
|
||||
|
||||
import builtins
|
||||
import grpc
|
||||
import uuid
|
||||
|
||||
from .case import Case
|
||||
from .gridcasegroup import GridCaseGroup
|
||||
@@ -16,6 +18,9 @@ import Commands_pb2
|
||||
from Definitions_pb2 import Empty
|
||||
import Project_pb2_grpc
|
||||
import Project_pb2
|
||||
import KeyValueStore_pb2_grpc
|
||||
import KeyValueStore_pb2
|
||||
|
||||
import PdmObject_pb2
|
||||
from .resinsight_classes import Project, PlotWindow, WellPath, SummaryCase, Reservoir
|
||||
|
||||
@@ -25,6 +30,12 @@ from typing import Optional, List
|
||||
@add_method(Project)
|
||||
def __custom_init__(self, pb2_object, channel: grpc.Channel) -> None:
|
||||
self._project_stub = Project_pb2_grpc.ProjectStub(self._channel)
|
||||
self.__key_value_store_stub = KeyValueStore_pb2_grpc.KeyValueStoreStub(
|
||||
self._channel
|
||||
)
|
||||
|
||||
# Public properties
|
||||
self.chunk_size = 8160
|
||||
|
||||
|
||||
@add_static_method(Project)
|
||||
@@ -424,3 +435,89 @@ def import_formation_names(self, formation_files=None):
|
||||
formationFiles=formation_files, applyToCaseId=-1
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@add_method(Project)
|
||||
def create_corner_point_grid(
|
||||
self,
|
||||
name: str,
|
||||
nx: int,
|
||||
ny: int,
|
||||
nz: int,
|
||||
coord: List[float],
|
||||
zcorn: List[float],
|
||||
actnum: List[int],
|
||||
):
|
||||
"""Creates a corner point grid from given parameters.
|
||||
|
||||
Arguments:
|
||||
name(str): Name of the grid.
|
||||
nx(int): Number of cells in x direction
|
||||
ny(int): Number of cells in y direction
|
||||
nz(int): Number of cells in z direction
|
||||
coord(list[float]): Coordinate lines as COORD keyword in Eclipse.
|
||||
Each coordinate line is defined by two points (top and bottom).
|
||||
Size: (nx+1) * (ny+1) * 2 * 3. Points are ordered as in Eclipse.
|
||||
zcorn(list[float]): Corner depths as defined by the Eclipse keyword ZCORN.
|
||||
Size: nx * ny * nz * 8
|
||||
actnum(list[int]): Active cell info: cells with values > 0 are active.
|
||||
Size: nx * ny * nz
|
||||
"""
|
||||
|
||||
# Generate unique keys for three arrays
|
||||
coord_key = "{}_{}".format(uuid.uuid4(), "coord")
|
||||
zcorn_key = "{}_{}".format(uuid.uuid4(), "zcorn")
|
||||
actnum_key = "{}_{}".format(uuid.uuid4(), "actnum")
|
||||
|
||||
self.set_key_values(coord_key, coord)
|
||||
self.set_key_values(zcorn_key, zcorn)
|
||||
self.set_key_values(actnum_key, actnum)
|
||||
return self.create_grid_from_key_values(
|
||||
name=name,
|
||||
nx=nx,
|
||||
ny=ny,
|
||||
nz=nz,
|
||||
coord_key=coord_key,
|
||||
zcorn_key=zcorn_key,
|
||||
actnum_key=actnum_key,
|
||||
)
|
||||
|
||||
|
||||
@add_method(Project)
|
||||
def set_key_values(self, key, values):
|
||||
"""Sets values for a given key in the key-value store.
|
||||
|
||||
Arguments:
|
||||
key(str): The key (should be unique).
|
||||
values(list): a list of double precision floating point numbers
|
||||
"""
|
||||
request_iterator = self.__generate_key_value_store_input_chunks(values, key)
|
||||
reply = self.__key_value_store_stub.SetValue(request_iterator)
|
||||
if reply.accepted_value_count < len(values):
|
||||
raise IndexError
|
||||
|
||||
|
||||
@add_method(Project)
|
||||
def __generate_key_value_store_input_chunks(self, array, name):
|
||||
index = -1
|
||||
while index < len(array):
|
||||
chunk = KeyValueStore_pb2.KeyValueStoreInputChunk()
|
||||
if index == -1:
|
||||
parameters = KeyValueStore_pb2.KeyValueInputParameters(
|
||||
name=name, num_elements=len(array)
|
||||
)
|
||||
chunk.parameters.CopyFrom(parameters)
|
||||
index += 1
|
||||
else:
|
||||
actual_chunk_size = min(len(array) - index + 1, self.chunk_size)
|
||||
chunk.values.CopyFrom(
|
||||
KeyValueStore_pb2.KeyValueStoreChunk(
|
||||
values=array[index : index + actual_chunk_size]
|
||||
)
|
||||
)
|
||||
index += actual_chunk_size
|
||||
|
||||
yield chunk
|
||||
# Final empty message to signal completion
|
||||
chunk = KeyValueStore_pb2.KeyValueStoreInputChunk()
|
||||
yield chunk
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RiaGrpcKeyValueStoreService.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaGrpcCallbacks.h"
|
||||
#include "RiaGrpcCaseService.h"
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "cafAssert.h"
|
||||
|
||||
using namespace rips;
|
||||
|
||||
#define NUM_CONCURRENT_CLIENT_TO_SERVER_STREAMS 10
|
||||
|
||||
class RiaKeyValueStoreStateHandler
|
||||
{
|
||||
using Status = grpc::Status;
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaKeyValueStoreStateHandler( bool clientStreamer = false )
|
||||
: m_streamedValueCount( 0u )
|
||||
, m_cellCount( 0u )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t totalValueCount() const { return m_cellCount; }
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t streamedValueCount() const { return m_streamedValueCount; }
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Status init( const std::string& name, size_t numElements )
|
||||
{
|
||||
RiaLogging::debug(
|
||||
QString( "Initializing stream: %1 size: %2" ).arg( QString::fromStdString( name ) ).arg( numElements ) );
|
||||
|
||||
m_name = name;
|
||||
m_cellCount = numElements;
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Client streamers need to be initialised with the encapsulated parameters
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Status init( const KeyValueStoreInputChunk* chunk )
|
||||
{
|
||||
CAF_ASSERT( chunk );
|
||||
|
||||
if ( chunk->has_parameters() )
|
||||
{
|
||||
return init( chunk->parameters().name(), chunk->parameters().num_elements() );
|
||||
}
|
||||
return grpc::Status( grpc::INVALID_ARGUMENT, "Need to have parameters in first message" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Status receiveStreamRequest( const KeyValueStoreInputChunk* request, ClientToServerStreamReply* reply )
|
||||
{
|
||||
CAF_ASSERT( request );
|
||||
CAF_ASSERT( reply );
|
||||
|
||||
if ( request->has_values() )
|
||||
{
|
||||
auto values = request->values().values();
|
||||
if ( !values.empty() )
|
||||
{
|
||||
size_t currentCellIdx = m_streamedValueCount;
|
||||
m_streamedValueCount += values.size();
|
||||
|
||||
if ( !values.empty() )
|
||||
{
|
||||
m_data.insert( m_data.end(), values.begin(), values.end() );
|
||||
}
|
||||
|
||||
if ( m_streamedValueCount > m_cellCount )
|
||||
{
|
||||
return grpc::Status( grpc::OUT_OF_RANGE, "Attempting to write out of bounds" );
|
||||
}
|
||||
|
||||
RiaLogging::debug( QString( "Received stream request. Start index: %1. Size after request: %2" )
|
||||
.arg( currentCellIdx )
|
||||
.arg( m_data.size() ) );
|
||||
reply->set_accepted_value_count( static_cast<int64_t>( m_data.size() ) );
|
||||
return Status::OK;
|
||||
}
|
||||
}
|
||||
return Status::OK;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void finish()
|
||||
{
|
||||
RiaLogging::debug(
|
||||
QString( "Stream finished: name=%1 size=%2" ).arg( QString::fromStdString( m_name ) ).arg( m_data.size() ) );
|
||||
if ( !m_name.empty() && !m_data.empty() )
|
||||
{
|
||||
auto convertFromFloatVectorToBytes = []( const std::vector<float>& float_vec ) -> std::vector<char>
|
||||
{
|
||||
if ( float_vec.empty() )
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// Calculate the total size needed for the byte array
|
||||
size_t size_in_bytes = float_vec.size() * sizeof( float );
|
||||
|
||||
// Create a vector of bytes with the appropriate size
|
||||
std::vector<char> byte_vec( size_in_bytes );
|
||||
|
||||
// Copy the binary data from the float vector to the byte vector
|
||||
std::memcpy( byte_vec.data(), float_vec.data(), size_in_bytes );
|
||||
|
||||
return byte_vec;
|
||||
};
|
||||
|
||||
RiaApplication::instance()->keyValueStore()->set( m_name, convertFromFloatVectorToBytes( m_data ) );
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t m_streamedValueCount;
|
||||
size_t m_cellCount;
|
||||
std::string m_name;
|
||||
std::vector<float> m_data;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaGrpcKeyValueStoreService::SetValue( grpc::ServerContext* context,
|
||||
const rips::KeyValueStoreInputChunk* request,
|
||||
rips::ClientToServerStreamReply* reply,
|
||||
RiaKeyValueStoreStateHandler* stateHandler )
|
||||
{
|
||||
return stateHandler->receiveStreamRequest( request, reply );
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RiaGrpcCallbackInterface*> RiaGrpcKeyValueStoreService::createCallbacks()
|
||||
{
|
||||
typedef RiaGrpcKeyValueStoreService Self;
|
||||
|
||||
std::vector<RiaGrpcCallbackInterface*> callbacks;
|
||||
callbacks = {
|
||||
new RiaGrpcClientToServerStreamCallback<Self,
|
||||
KeyValueStoreInputChunk,
|
||||
ClientToServerStreamReply,
|
||||
RiaKeyValueStoreStateHandler>( this,
|
||||
&Self::SetValue,
|
||||
&Self::RequestSetValue,
|
||||
new RiaKeyValueStoreStateHandler( true ) ) };
|
||||
return callbacks;
|
||||
}
|
||||
|
||||
static bool RiaGrpcKeyValueStoreService_init =
|
||||
RiaGrpcServiceFactory::instance()->registerCreator<RiaGrpcKeyValueStoreService>(
|
||||
typeid( RiaGrpcKeyValueStoreService ).hash_code() );
|
||||
@@ -0,0 +1,42 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RiaGrpcServiceInterface.h"
|
||||
|
||||
#include "KeyValueStore.grpc.pb.h"
|
||||
|
||||
#include <grpcpp/grpcpp.h>
|
||||
|
||||
class RiaKeyValueStoreStateHandler;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// gRPC-service answering requests about property information for a given case and time step
|
||||
//
|
||||
//==================================================================================================
|
||||
class RiaGrpcKeyValueStoreService final : public rips::KeyValueStore::AsyncService, public RiaGrpcServiceInterface
|
||||
{
|
||||
public:
|
||||
grpc::Status SetValue( grpc::ServerContext* context,
|
||||
const rips::KeyValueStoreInputChunk* chunk,
|
||||
rips::ClientToServerStreamReply* reply,
|
||||
RiaKeyValueStoreStateHandler* stateHandler );
|
||||
|
||||
std::vector<RiaGrpcCallbackInterface*> createCallbacks() override;
|
||||
};
|
||||
Reference in New Issue
Block a user