Example #1
0
    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;

    }