///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2011- Statoil ASA // Copyright (C) 2013- Ceetron Solutions AS // Copyright (C) 2011-2012 Ceetron AS // // 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 "RiaSocketCommand.h" #include "RiaPreferences.h" #include "RiaSocketServer.h" #include "RiaSocketTools.h" #include "RigActiveCellInfo.h" #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" #include "RigFemPart.h" #include "RigFemPartCollection.h" #include "RigFemPartGrid.h" #include "RigGeoMechCaseData.h" #include "RigMainGrid.h" #include "Rim3dOverlayInfoConfig.h" #include "RimCellEdgeColors.h" #include "RimEclipseCase.h" #include "RimEclipseCellColors.h" #include "RimEclipsePropertyFilterCollection.h" #include "RimEclipseView.h" #include "RimGeoMechCase.h" #include "RimGeoMechView.h" #include "RimReservoirCellResultsStorage.h" #include "RimSimWellInViewCollection.h" #include "Riu3dSelectionManager.h" #include #include "RimGeoMechResultDefinition.h" #include //-------------------------------------------------------------------------------------------------- /// OBSOLETE, to be deleted //-------------------------------------------------------------------------------------------------- class RiaGetMainGridDimensions : public RiaSocketCommand { public: static QString commandName() { return QString( "GetMainGridDimensions" ); } bool interpretCommand( RiaSocketServer* server, const QList& args, QDataStream& socketStream ) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args ); if ( !rimCase ) return true; // Write data back to octave: I, J, K dimensions size_t iCount = 0; size_t jCount = 0; size_t kCount = 0; if ( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() ) { iCount = rimCase->eclipseCaseData()->mainGrid()->cellCountI(); jCount = rimCase->eclipseCaseData()->mainGrid()->cellCountJ(); kCount = rimCase->eclipseCaseData()->mainGrid()->cellCountK(); } socketStream << (quint64)iCount << (quint64)jCount << (quint64)kCount; return true; } }; static bool RiaGetMainGridDimensions_init = RiaSocketCommandFactory::instance()->registerCreator( RiaGetMainGridDimensions::commandName() ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- class RiaGetActiveCellInfo : public RiaSocketCommand { public: static QString commandName() { return QString( "GetActiveCellInfo" ); } bool interpretCommand( RiaSocketServer* server, const QList& args, QDataStream& socketStream ) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args ); if ( !rimCase ) return true; RiaDefines::PorosityModelType porosityModel = RiaDefines::PorosityModelType::MATRIX_MODEL; if ( args.size() > 2 ) { QString prorosityModelString = args[2]; if ( prorosityModelString.toUpper() == "FRACTURE" ) { porosityModel = RiaDefines::PorosityModelType::FRACTURE_MODEL; } } // Write data back to octave: columnCount, bytesPrTimestep, GridNr I J K ParentGridNr PI PJ PK CoarseBoxIdx std::array, 9> activeCellInfo; if ( !( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() ) ) { // No data available socketStream << (quint64)0 << (quint64)0; return true; } calculateMatrixModelActiveCellInfo( rimCase, porosityModel, activeCellInfo[0], activeCellInfo[1], activeCellInfo[2], activeCellInfo[3], activeCellInfo[4], activeCellInfo[5], activeCellInfo[6], activeCellInfo[7], activeCellInfo[8] ); // First write column count quint64 columnCount = (quint64)9; socketStream << columnCount; // then the byte-size of the size of one column size_t timestepResultCount = activeCellInfo[0].size(); quint64 timestepByteCount = (quint64)( timestepResultCount * sizeof( qint32 ) ); socketStream << timestepByteCount; for ( size_t tIdx = 0; tIdx < columnCount; ++tIdx ) { RiaSocketTools::writeBlockData( server, server->currentClient(), (const char*)activeCellInfo[tIdx].data(), timestepByteCount ); } return true; } static void calculateMatrixModelActiveCellInfo( RimEclipseCase* reservoirCase, RiaDefines::PorosityModelType porosityModel, std::vector& gridNumber, std::vector& cellI, std::vector& cellJ, std::vector& cellK, std::vector& parentGridNumber, std::vector& hostCellI, std::vector& hostCellJ, std::vector& hostCellK, std::vector& globalCoarseningBoxIdx ) { gridNumber.clear(); cellI.clear(); cellJ.clear(); cellK.clear(); parentGridNumber.clear(); hostCellI.clear(); hostCellJ.clear(); hostCellK.clear(); globalCoarseningBoxIdx.clear(); if ( !reservoirCase || !reservoirCase->eclipseCaseData() || !reservoirCase->eclipseCaseData()->mainGrid() ) { return; } RigActiveCellInfo* actCellInfo = reservoirCase->eclipseCaseData()->activeCellInfo( porosityModel ); size_t numMatrixModelActiveCells = actCellInfo->reservoirActiveCellCount(); gridNumber.reserve( numMatrixModelActiveCells ); cellI.reserve( numMatrixModelActiveCells ); cellJ.reserve( numMatrixModelActiveCells ); cellK.reserve( numMatrixModelActiveCells ); parentGridNumber.reserve( numMatrixModelActiveCells ); hostCellI.reserve( numMatrixModelActiveCells ); hostCellJ.reserve( numMatrixModelActiveCells ); hostCellK.reserve( numMatrixModelActiveCells ); globalCoarseningBoxIdx.reserve( numMatrixModelActiveCells ); const std::vector& reservoirCells = reservoirCase->eclipseCaseData()->mainGrid()->globalCellArray(); std::vector globalCoarseningBoxIndexStart; { size_t globalCoarseningBoxCount = 0; for ( size_t gridIdx = 0; gridIdx < reservoirCase->eclipseCaseData()->gridCount(); gridIdx++ ) { globalCoarseningBoxIndexStart.push_back( globalCoarseningBoxCount ); RigGridBase* grid = reservoirCase->eclipseCaseData()->grid( gridIdx ); size_t localCoarseningBoxCount = grid->coarseningBoxCount(); globalCoarseningBoxCount += localCoarseningBoxCount; } } for ( size_t cIdx = 0; cIdx < reservoirCells.size(); ++cIdx ) { if ( actCellInfo->isActive( cIdx ) ) { RigGridBase* grid = reservoirCells[cIdx].hostGrid(); CVF_ASSERT( grid != nullptr ); size_t cellIndex = reservoirCells[cIdx].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[cIdx].parentCellIndex(); parentGrid = ( static_cast( grid ) )->parentGrid(); CVF_ASSERT( parentGrid != nullptr ); parentGrid->ijkFromCellIndex( parentCellIdx, &pi, &pj, &pk ); } gridNumber.push_back( static_cast( grid->gridIndex() ) ); cellI.push_back( static_cast( i + 1 ) ); // NB: 1-based index in Octave cellJ.push_back( static_cast( j + 1 ) ); // NB: 1-based index in Octave cellK.push_back( static_cast( k + 1 ) ); // NB: 1-based index in Octave parentGridNumber.push_back( static_cast( parentGrid->gridIndex() ) ); hostCellI.push_back( static_cast( pi + 1 ) ); // NB: 1-based index in Octave hostCellJ.push_back( static_cast( pj + 1 ) ); // NB: 1-based index in Octave hostCellK.push_back( static_cast( pk + 1 ) ); // NB: 1-based index in Octave size_t coarseningIdx = reservoirCells[cIdx].coarseningBoxIndex(); if ( coarseningIdx != cvf::UNDEFINED_SIZE_T ) { size_t globalCoarseningIdx = globalCoarseningBoxIndexStart[grid->gridIndex()] + coarseningIdx; globalCoarseningBoxIdx.push_back( static_cast( globalCoarseningIdx + 1 ) ); // NB: 1-based // index in Octave } else { globalCoarseningBoxIdx.push_back( -1 ); } } } } }; static bool RiaGetActiveCellInfo_init = RiaSocketCommandFactory::instance()->registerCreator( RiaGetActiveCellInfo::commandName() ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- class RiaGetCoarseningInfo : public RiaSocketCommand { public: static QString commandName() { return QString( "GetCoarseningInfo" ); } bool interpretCommand( RiaSocketServer* server, const QList& args, QDataStream& socketStream ) override { int argCaseGroupId = -1; if ( args.size() == 2 ) { argCaseGroupId = args[1].toInt(); } RimEclipseCase* rimCase = server->findReservoir( argCaseGroupId ); if ( !rimCase || !rimCase->eclipseCaseData() || !rimCase->eclipseCaseData()->mainGrid() ) { quint64 byteCount = 0; socketStream << byteCount; return true; } // Write data back to octave: I1, I2, J1, J2, K1, K2 for all coarsening boxes if ( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() ) { size_t globalCoarseningBoxCount = 0; for ( size_t gridIdx = 0; gridIdx < rimCase->eclipseCaseData()->gridCount(); gridIdx++ ) { RigGridBase* grid = rimCase->eclipseCaseData()->grid( gridIdx ); size_t localCoarseningBoxCount = grid->coarseningBoxCount(); globalCoarseningBoxCount += localCoarseningBoxCount; } quint64 byteCount = globalCoarseningBoxCount * 6 * sizeof( qint32 ); socketStream << byteCount; for ( size_t gridIdx = 0; gridIdx < rimCase->eclipseCaseData()->gridCount(); gridIdx++ ) { RigGridBase* grid = rimCase->eclipseCaseData()->grid( gridIdx ); size_t localCoarseningBoxCount = grid->coarseningBoxCount(); for ( size_t boxIdx = 0; boxIdx < localCoarseningBoxCount; boxIdx++ ) { size_t i1, i2, j1, j2, k1, k2; grid->coarseningBox( boxIdx, &i1, &i2, &j1, &j2, &k1, &k2 ); // Write 1-based coordinates for coarsening box socketStream << static_cast( i1 + 1 ); socketStream << static_cast( i2 + 1 ); socketStream << static_cast( j1 + 1 ); socketStream << static_cast( j2 + 1 ); socketStream << static_cast( k1 + 1 ); socketStream << static_cast( k2 + 1 ); } } } return true; } }; static bool RiaGetCoarseningInfo_init = RiaSocketCommandFactory::instance()->registerCreator( RiaGetCoarseningInfo::commandName() ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- class RiaGetGridDimensions : public RiaSocketCommand { public: static QString commandName() { return QString( "GetGridDimensions" ); } bool interpretCommand( RiaSocketServer* server, const QList& args, QDataStream& socketStream ) override { int argCaseGroupId = -1; if ( args.size() == 2 ) { argCaseGroupId = args[1].toInt(); } RimEclipseCase* rimCase = server->findReservoir( argCaseGroupId ); if ( !rimCase || !rimCase->eclipseCaseData() || !rimCase->eclipseCaseData()->mainGrid() ) { quint64 byteCount = 0; socketStream << byteCount; return true; } // Write data back to octave: I, J, K dimensions if ( rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid() ) { std::vector grids; rimCase->eclipseCaseData()->allGrids( &grids ); quint64 byteCount = grids.size() * 3 * sizeof( quint64 ); socketStream << byteCount; for ( size_t i = 0; i < grids.size(); i++ ) { size_t iCount = 0; size_t jCount = 0; size_t kCount = 0; iCount = grids[i]->cellCountI(); jCount = grids[i]->cellCountJ(); kCount = grids[i]->cellCountK(); socketStream << (quint64)iCount << (quint64)jCount << (quint64)kCount; } } return true; } }; static bool RiaGetGridDimensions_init = RiaSocketCommandFactory::instance()->registerCreator( RiaGetGridDimensions::commandName() ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- class RiaGetTimeStepDates : public RiaSocketCommand { public: static QString commandName() { return QString( "GetTimeStepDates" ); } bool interpretCommand( RiaSocketServer* server, const QList& args, QDataStream& socketStream ) override { int argCaseGroupId = -1; if ( args.size() == 2 ) { argCaseGroupId = args[1].toInt(); } RimEclipseCase* rimCase = server->findReservoir( argCaseGroupId ); bool canFetchData = true; if ( !rimCase || !rimCase->eclipseCaseData() ) { canFetchData = false; } RigEclipseResultAddress addrToMaxTimeStepCountResult; if ( rimCase && rimCase->eclipseCaseData() ) { rimCase->eclipseCaseData()->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->maxTimeStepCount( &addrToMaxTimeStepCountResult ); if ( !addrToMaxTimeStepCountResult.isValid() ) { canFetchData = false; } } // Did not find any result to fetch data from, return zero data found if ( !canFetchData ) { quint64 timeStepCount = 0; quint64 byteCount = sizeof( quint64 ); socketStream << byteCount; socketStream << timeStepCount; return true; } std::vector timeStepDates = rimCase->eclipseCaseData() ->results( RiaDefines::PorosityModelType::MATRIX_MODEL ) ->timeStepDates( RigEclipseResultAddress( addrToMaxTimeStepCountResult ) ); quint64 timeStepCount = timeStepDates.size(); quint64 byteCount = sizeof( quint64 ) + 6 * timeStepCount * sizeof( qint32 ); socketStream << byteCount; socketStream << timeStepCount; for ( size_t i = 0; i < timeStepCount; i++ ) { qint32 intValue = 0; intValue = timeStepDates[i].date().year(); socketStream << intValue; intValue = timeStepDates[i].date().month(); socketStream << intValue; intValue = timeStepDates[i].date().day(); socketStream << intValue; intValue = timeStepDates[i].time().hour(); socketStream << intValue; intValue = timeStepDates[i].time().minute(); socketStream << intValue; intValue = timeStepDates[i].time().second(); socketStream << intValue; } return true; } }; static bool RiaGetTimeStepDates_init = RiaSocketCommandFactory::instance()->registerCreator( RiaGetTimeStepDates::commandName() ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- class RiaGetTimeStepDays : public RiaSocketCommand { public: static QString commandName() { return QString( "GetTimeStepDays" ); } bool interpretCommand( RiaSocketServer* server, const QList& args, QDataStream& socketStream ) override { int argCaseGroupId = -1; if ( args.size() == 2 ) { argCaseGroupId = args[1].toInt(); } RimEclipseCase* rimCase = server->findReservoir( argCaseGroupId ); bool canFetchData = true; if ( !rimCase || !rimCase->eclipseCaseData() ) { canFetchData = false; } RigEclipseResultAddress addrToMaxTimeStepCountResult; if ( rimCase && rimCase->eclipseCaseData() ) { rimCase->eclipseCaseData()->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->maxTimeStepCount( &addrToMaxTimeStepCountResult ); if ( !addrToMaxTimeStepCountResult.isValid() ) { canFetchData = false; } } // Did not find any result to fetch data from, return zero data found if ( !canFetchData ) { quint64 timeStepCount = 0; quint64 byteCount = sizeof( quint64 ); socketStream << byteCount; socketStream << timeStepCount; return true; } std::vector daysSinceSimulationStart = rimCase->eclipseCaseData()->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->daysSinceSimulationStart( addrToMaxTimeStepCountResult ); quint64 timeStepCount = daysSinceSimulationStart.size(); quint64 byteCount = sizeof( quint64 ) + timeStepCount * sizeof( qint32 ); socketStream << byteCount; socketStream << timeStepCount; for ( double day : daysSinceSimulationStart ) { socketStream << day; } return true; } }; static bool RiaGetTimeStepDays_init = RiaSocketCommandFactory::instance()->registerCreator( RiaGetTimeStepDays::commandName() ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- class RiaGetSelectedCells : public RiaSocketCommand { public: static QString commandName() { return QString( "GetSelectedCells" ); } bool interpretCommand( RiaSocketServer* server, const QList& args, QDataStream& socketStream ) override { // findCaseFromArgs only returns RimEclipseCase, so geomech cases are not supported because of this. // The rest of the function supports geomech cases, so using a findCaseFromArgs that supports geomech // cases is the only change needed to add geomech support. RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs( server, args ); if ( !rimCase ) return true; // Write data back to octave: column count, bytes per column, caseId, gridNumber, cellI, cellJ, cellK std::array, 5> selectedCellInfo; getSelectedCells( rimCase, selectedCellInfo[0], selectedCellInfo[1], selectedCellInfo[2], selectedCellInfo[3], selectedCellInfo[4] ); // First write column count quint64 columnCount = 5; socketStream << columnCount; // then the byte-size of the size of one column quint64 columnByteCount = (quint64)( selectedCellInfo[0].size() * sizeof( qint32 ) ); socketStream << columnByteCount; // Write back table data for ( size_t tIdx = 0; tIdx < columnCount; ++tIdx ) { RiaSocketTools::writeBlockData( server, server->currentClient(), (const char*)selectedCellInfo[tIdx].data(), columnByteCount ); } return true; } static void getSelectedCells( const RimCase* reservoirCase, std::vector& caseNumber, std::vector& gridNumber, std::vector& cellI, std::vector& cellJ, std::vector& cellK ) { std::vector items; Riu3dSelectionManager::instance()->selectedItems( items ); for ( const RiuSelectionItem* item : items ) { size_t i, j, k; size_t gridIndex; int caseId; bool validIndex = true; if ( item->type() == RiuSelectionItem::ECLIPSE_SELECTION_OBJECT ) { const RiuEclipseSelectionItem* eclipseItem = static_cast( item ); eclipseItem->m_resultDefinition->eclipseCase() ->eclipseCaseData() ->grid( eclipseItem->m_gridIndex ) ->ijkFromCellIndex( eclipseItem->m_gridLocalCellIndex, &i, &j, &k ); gridIndex = eclipseItem->m_gridIndex; caseId = eclipseItem->m_resultDefinition->eclipseCase()->caseId(); } else if ( item->type() == RiuSelectionItem::GEOMECH_SELECTION_OBJECT ) { const RiuGeoMechSelectionItem* geomechItem = static_cast( item ); validIndex = geomechItem->m_resultDefinition->ownerCaseData() ->femParts() ->part( geomechItem->m_gridIndex ) ->getOrCreateStructGrid() ->ijkFromCellIndex( geomechItem->m_cellIndex, &i, &j, &k ); CVF_ASSERT( validIndex ); gridIndex = geomechItem->m_gridIndex; caseId = geomechItem->m_resultDefinition->geoMechCase()->caseId(); } else { continue; } if ( caseId == reservoirCase->caseId() && validIndex ) { caseNumber.push_back( static_cast( caseId ) ); gridNumber.push_back( static_cast( gridIndex ) ); cellI.push_back( static_cast( i + 1 ) ); cellJ.push_back( static_cast( j + 1 ) ); cellK.push_back( static_cast( k + 1 ) ); } } } }; static bool RiaGetSelectedCells_init = RiaSocketCommandFactory::instance()->registerCreator( RiaGetSelectedCells::commandName() );