bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); QString porosityModelName; porosityModelName = args[2]; RiaDefines::PorosityModelType porosityModelEnum = RiaDefines::MATRIX_MODEL; if (porosityModelName.toUpper() == "FRACTURE") { porosityModelEnum = RiaDefines::FRACTURE_MODEL; } if (!rimCase || !rimCase->eclipseCaseData() ) { // No data available socketStream << (quint64)0 << (quint64)0 ; return true; } RigActiveCellInfo* actCellInfo = rimCase->eclipseCaseData()->activeCellInfo(porosityModelEnum); RigMainGrid* mainGrid = rimCase->eclipseCaseData()->mainGrid(); size_t activeCellCount = actCellInfo->reservoirActiveCellCount(); size_t doubleValueCount = activeCellCount * 3 * 8; socketStream << (quint64)activeCellCount; quint64 byteCount = doubleValueCount * sizeof(double); socketStream << byteCount; // This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is // defined by the ordering of the receiving NDArray // // See riGetCellCorners // // dim_vector dv; // dv.resize(3); // dv(0) = coordCount; // dv(1) = 8; // dv(2) = 3; cvf::Vec3d cornerVerts[8]; size_t blockByteCount = activeCellCount * sizeof(double); std::vector<double> doubleValues(blockByteCount); for (int coordIdx = 0; coordIdx < 3; coordIdx++) { for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) { size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; quint64 valueIndex = 0; for (size_t reservoirCellIndex = 0; reservoirCellIndex < mainGrid->globalCellArray().size(); reservoirCellIndex++) { if (!actCellInfo->isActive(reservoirCellIndex)) continue; mainGrid->cellCornerVertices(reservoirCellIndex, cornerVerts); doubleValues[valueIndex++] = getCellCornerWithPositiveDepth(cornerVerts, cornerIndexMapping, coordIdx); } CVF_ASSERT(valueIndex == activeCellCount); RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); } } return true; }
virtual bool interpretMore(RiaSocketServer* server, QTcpSocket* currentClient) { // std::cout << "RiaSetActiveCellProperty, interpretMore: scalarIndex : " << m_currentScalarIndex; if (m_invalidActiveCellCountDetected) return true; // If nothing should be read, or we already have read everything, do nothing if ((m_timeStepCountToRead == 0) || (m_currentTimeStepNumberToRead >= m_timeStepCountToRead) ) return true; if (!currentClient->bytesAvailable()) return false; if (m_timeStepCountToRead != m_requestedTimesteps.size()) { CVF_ASSERT(false); } // Check if a complete timestep is available, return and whait for readyRead() if not if (currentClient->bytesAvailable() < (int)m_bytesPerTimeStepToRead) return false; size_t cellCountFromOctave = m_bytesPerTimeStepToRead / sizeof(double); RigActiveCellInfo* activeCellInfo = m_currentReservoir->reservoirData()->activeCellInfo(m_porosityModelEnum); size_t globalActiveCellCount = activeCellInfo->globalActiveCellCount(); size_t totalCellCount = activeCellInfo->globalCellCount(); size_t globalCellResultCount = activeCellInfo->globalCellResultCount(); bool isCoarseningActive = globalCellResultCount != globalActiveCellCount; if (cellCountFromOctave != globalActiveCellCount ) { server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("The number of cells in the data coming from octave does not match the case") + ":\"" + m_currentReservoir->caseUserDescription() + "\"\n" " Octave: " + QString::number(cellCountFromOctave) + "\n" " " + m_currentReservoir->caseUserDescription() + ": Active cell count: " + QString::number(globalActiveCellCount) + " Total cell count: " + QString::number(totalCellCount)) ; cellCountFromOctave = 0; m_invalidActiveCellCountDetected = true; currentClient->abort(); return true; } // Make sure the size of the retreiving container is correct. // If it is, this is noops for (size_t tIdx = 0; tIdx < m_timeStepCountToRead; ++tIdx) { size_t tsId = m_requestedTimesteps[tIdx]; m_scalarResultsToAdd->at(tsId).resize(globalCellResultCount, HUGE_VAL); } std::vector<double> readBuffer; double * internalMatrixData = NULL; if (isCoarseningActive) { readBuffer.resize(cellCountFromOctave, HUGE_VAL); internalMatrixData = readBuffer.data(); } QDataStream socketStream(currentClient); socketStream.setVersion(riOctavePlugin::qtDataStreamVersion); // Read available complete timestepdata while ((currentClient->bytesAvailable() >= (int)m_bytesPerTimeStepToRead) && (m_currentTimeStepNumberToRead < m_timeStepCountToRead)) { qint64 bytesRead = 0; if ( !isCoarseningActive) { internalMatrixData = m_scalarResultsToAdd->at(m_requestedTimesteps[m_currentTimeStepNumberToRead]).data(); } #if 1 // Use raw data transfer. Faster. bytesRead = currentClient->read((char*)(internalMatrixData), m_bytesPerTimeStepToRead); #else for (size_t cIdx = 0; cIdx < cellCountFromOctave; ++cIdx) { socketStream >> internalMatrixData[cIdx]; if (socketStream.status() == QDataStream::Ok) bytesRead += sizeof(double); } #endif // Map data from active to result index based container ( Coarsening is active) if (isCoarseningActive) { size_t acIdx = 0; for (size_t gcIdx = 0; gcIdx < totalCellCount; ++gcIdx) { if (activeCellInfo->isActive(gcIdx)) { m_scalarResultsToAdd->at(m_requestedTimesteps[m_currentTimeStepNumberToRead])[activeCellInfo->cellResultIndex(gcIdx)] = readBuffer[acIdx]; ++acIdx; } } } if ((int)m_bytesPerTimeStepToRead != bytesRead) { server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not read binary double data properly from socket")); } ++m_currentTimeStepNumberToRead; } // If we have read all the data, refresh the views if (m_currentTimeStepNumberToRead == m_timeStepCountToRead) { if (m_currentReservoir != NULL) { // Create a new input property if we have an input reservoir RimInputCase* inputRes = dynamic_cast<RimInputCase*>(m_currentReservoir); if (inputRes) { RimInputProperty* inputProperty = NULL; inputProperty = inputRes->m_inputPropertyCollection->findInputProperty(m_currentPropertyName); if (!inputProperty) { inputProperty = new RimInputProperty; inputProperty->resultName = m_currentPropertyName; inputProperty->eclipseKeyword = ""; inputProperty->fileName = ""; inputRes->m_inputPropertyCollection->inputProperties.push_back(inputProperty); RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); treeModel->updateUiSubTree(inputRes->m_inputPropertyCollection()); } inputProperty->resolvedState = RimInputProperty::RESOLVED_NOT_SAVED; } if( m_currentScalarIndex != cvf::UNDEFINED_SIZE_T && m_currentReservoir->reservoirData() && m_currentReservoir->reservoirData()->results(m_porosityModelEnum) ) { m_currentReservoir->reservoirData()->results(m_porosityModelEnum)->recalculateMinMax(m_currentScalarIndex); } for (size_t i = 0; i < m_currentReservoir->reservoirViews.size(); ++i) { if (m_currentReservoir->reservoirViews[i]) { // As new result might have been introduced, update all editors connected m_currentReservoir->reservoirViews[i]->cellResult->updateConnectedEditors(); // It is usually not needed to create new display model, but if any derived geometry based on generated data (from Octave) // a full display model rebuild is required m_currentReservoir->reservoirViews[i]->scheduleCreateDisplayModelAndRedraw(); } } } return true; } return false; }