void buildResultInfoString(RigReservoir* reservoir, RifReaderInterface::PorosityModelResultType porosityModel, RimDefines::ResultCatType resultType)
{
    RigCaseCellResultsData* matrixResults = reservoir->results(porosityModel);
    {
        QStringList resultNames = matrixResults->resultNames(resultType);

        for (size_t i = 0 ; i < resultNames.size(); i++)
        {
            std::vector<double> values;
            size_t scalarResultIndex = matrixResults->findOrLoadScalarResult(resultType, resultNames[i]);
            EXPECT_TRUE(scalarResultIndex != cvf::UNDEFINED_SIZE_T);

            QString resultText = QString("%1").arg(resultNames[i], 8);
            std::vector< std::vector<double> > & resultValues = matrixResults->cellScalarResults(scalarResultIndex);
            for (size_t timeStepIdx = 0; timeStepIdx < matrixResults->timeStepCount(scalarResultIndex); timeStepIdx++)
            {
                size_t resultValueCount = resultValues[timeStepIdx].size();
                resultText += QString(" %1").arg(resultValueCount);
            }

            qDebug() << resultText;
        }
        qDebug() << "Number of items : " << resultNames.size();
    }
}
示例#2
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
bool RifReaderMockModel::open(const QString& fileName, RigCaseData* eclipseCase)
{
    m_reservoirBuilder.populateReservoir(eclipseCase);
  
    m_reservoir = eclipseCase;

    RigCaseCellResultsData* cellResults = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS);


    std::vector<QDateTime> dates;

    for (int i = 0; i < static_cast<int>(m_reservoirBuilder.timeStepCount()); i++)
    {
        dates.push_back(QDateTime(QDate(2012+i, 6, 1)));
    }

    for (size_t i = 0; i < m_reservoirBuilder.resultCount(); i++)
    {
        size_t resIdx = cellResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, QString("Dynamic_Result_%1").arg(i), false);
        cellResults->setTimeStepDates(resIdx, dates);
    }

    if (m_reservoirBuilder.timeStepCount() == 0) return true;

    std::vector<QDateTime> staticDates;
    staticDates.push_back(dates[0]);
    for (int i = 0; i < static_cast<int>(m_reservoirBuilder.resultCount()); i++)
    {
        QString varEnd;
        if (i == 0) varEnd = "X";
        if (i == 1) varEnd = "Y";
        int resIndex = 0;
        if (i > 1) resIndex = i;

        size_t resIdx = cellResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, QString("Static_Result_%1%2").arg(resIndex).arg(varEnd), false);
        cellResults->setTimeStepDates(resIdx, staticDates);
    }


#define ADD_INPUT_PROPERTY(Name) \
    { \
        size_t resIdx; \
        QString resultName(Name); \
        resIdx = cellResults->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, resultName, false); \
        cellResults->setTimeStepDates(resIdx, staticDates); \
        cellResults->cellScalarResults(resIdx).resize(1); \
        std::vector<double>& values = cellResults->cellScalarResults(resIdx)[0]; \
        this->inputProperty(resultName, &values); \
    }

    ADD_INPUT_PROPERTY("PORO");
    ADD_INPUT_PROPERTY("PERM");
    ADD_INPUT_PROPERTY("MULTX");
   
    return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSaturationPressurePlot*>
    RicCreateSaturationPressurePlotsFeature::createPlots(RimEclipseResultCase* eclipseResultCase)
{
    std::vector<RimSaturationPressurePlot*> plots;

    if (!eclipseResultCase)
    {
        RiaLogging::error(
            "RicCreateSaturationPressurePlotsFeature:: No case specified for creation of saturation pressure plots");

        return plots;
    }

    RimProject* project = RiaApplication::instance()->project();

    RimSaturationPressurePlotCollection* collection = project->mainPlotCollection()->saturationPressurePlotCollection();

    if (eclipseResultCase && eclipseResultCase->ensureReservoirCaseIsOpen())
    {
        eclipseResultCase->ensureDeckIsParsedForEquilData();

        RigEclipseCaseData* eclipseCaseData = eclipseResultCase->eclipseCaseData();

        bool requiredInputDataPresent = false;
        if (!eclipseCaseData->equilData().empty())
        {
            if (eclipseCaseData && eclipseCaseData->results(RiaDefines::MATRIX_MODEL))
            {
                RigCaseCellResultsData* resultData = eclipseCaseData->results(RiaDefines::MATRIX_MODEL);

                if (resultData->hasResultEntry(RigEclipseResultAddress(RiaDefines::DYNAMIC_NATIVE, "PRESSURE")) &&
                    resultData->hasResultEntry(RigEclipseResultAddress(RiaDefines::DYNAMIC_NATIVE, "PDEW")) &&
                    resultData->hasResultEntry(RigEclipseResultAddress(RiaDefines::DYNAMIC_NATIVE, "PBUB")))
                {
                    requiredInputDataPresent = true;
                }
            }
        }

        if (requiredInputDataPresent)
        {
            plots = collection->createSaturationPressurePlots(eclipseResultCase);
            for (auto plot : plots)
            {
                plot->loadDataAndUpdate();
                plot->zoomAll();
                plot->updateConnectedEditors();
            }
        }
    }

    return plots;
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RimEclipseInputProperty::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
    if (changedField == &resultName)
    {
        RimEclipseInputCase* rimCase = nullptr;
        this->firstAncestorOrThisOfType(rimCase);
        if (rimCase)
        {
            bool anyNameUpdated = false;

            QString oldName = oldValue.toString();
            QString newName = newValue.toString();

            RigCaseCellResultsData* matrixResults = rimCase->reservoirData()->results(RifReaderInterface::MATRIX_RESULTS);
            if (matrixResults)
            {
                if (matrixResults->updateResultName(RimDefines::INPUT_PROPERTY, oldName, newName))
                {
                    anyNameUpdated = true;
                }
            }

            RigCaseCellResultsData* fracResults = rimCase->reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS);
            if (fracResults)
            {
                if (fracResults->updateResultName(RimDefines::INPUT_PROPERTY, oldName, newName))
                {
                    anyNameUpdated = true;
                }
            }

            if (anyNameUpdated)
            {
                std::vector<RimEclipseResultDefinition*> resDefs;
                rimCase->descendantsIncludingThisOfType(resDefs);

                for (auto it : resDefs)             
                {
                    if (it->resultVariable() == oldName)
                    {
                        it->setResultVariable(newName);
                    }

                    it->updateResultNameHasChanged();
                    it->updateAnyFieldHasChanged();
                }
            }
        }
    }
}
示例#5
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RigFlowDiagVisibleCellsStatCalc::mobileVolumeWeightedMean(size_t timeStepIndex, double &result)
{
    RimEclipseResultCase* eclCase = nullptr;
    m_resultsData->flowDiagSolution()->firstAncestorOrThisOfType(eclCase);
    if (!eclCase) return;

    RigCaseCellResultsData* caseCellResultsData = eclCase->results(RiaDefines::MATRIX_MODEL);

    size_t mobPVResultIndex = caseCellResultsData->findOrLoadScalarResult(RiaDefines::ResultCatType::STATIC_NATIVE, RiaDefines::mobilePoreVolumeName());
    
    const std::vector<double>& weights = caseCellResultsData->cellScalarResults(mobPVResultIndex, 0);
    const std::vector<double>* values = m_resultsData->resultValues(m_resVarAddr, timeStepIndex);

    const RigActiveCellInfo* actCellInfo = m_resultsData->activeCellInfo(m_resVarAddr);

    RigWeightedMeanCalc::weightedMeanOverCells(&weights, values, m_cellVisibilities.p(), true, actCellInfo, true, &result);
}
示例#6
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
bool RiuRelativePermeabilityPlotUpdater::queryDataAndUpdatePlot(const RimEclipseView& eclipseView, size_t gridIndex, size_t gridLocalCellIndex, RiuRelativePermeabilityPlotPanel* plotPanel)
{
    CVF_ASSERT(plotPanel);

    RimEclipseResultCase* eclipseResultCase = dynamic_cast<RimEclipseResultCase*>(eclipseView.eclipseCase());
    RigEclipseCaseData* eclipseCaseData = eclipseResultCase ? eclipseResultCase->eclipseCaseData() : nullptr;
    if (eclipseResultCase && eclipseCaseData && eclipseResultCase->flowDiagSolverInterface())
    {
        size_t activeCellIndex = CellLookupHelper::mapToActiveCellIndex(eclipseCaseData, gridIndex, gridLocalCellIndex);
        if (activeCellIndex != cvf::UNDEFINED_SIZE_T)
        {
            //cvf::Trace::show("Updating RelPerm plot for active cell index: %d", static_cast<int>(activeCellIndex));

            std::vector<RigFlowDiagSolverInterface::RelPermCurve> relPermCurveArr = eclipseResultCase->flowDiagSolverInterface()->calculateRelPermCurves(activeCellIndex);

            // Make sure we load the results that we'll query below
            RigCaseCellResultsData* cellResultsData = eclipseCaseData->results(RiaDefines::MATRIX_MODEL);
            cellResultsData->findOrLoadScalarResult(RiaDefines::DYNAMIC_NATIVE, "SWAT");
            cellResultsData->findOrLoadScalarResult(RiaDefines::DYNAMIC_NATIVE, "SGAS");
            cellResultsData->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "SATNUM");

            // Fetch SWAT and SGAS cell values for the selected cell
            const size_t timeStepIndex = static_cast<size_t>(eclipseView.currentTimeStep());
            cvf::ref<RigResultAccessor> swatAccessor = RigResultAccessorFactory::createFromNameAndType(eclipseCaseData, gridIndex, RiaDefines::MATRIX_MODEL, timeStepIndex, "SWAT", RiaDefines::DYNAMIC_NATIVE);
            cvf::ref<RigResultAccessor> sgasAccessor = RigResultAccessorFactory::createFromNameAndType(eclipseCaseData, gridIndex, RiaDefines::MATRIX_MODEL, timeStepIndex, "SGAS", RiaDefines::DYNAMIC_NATIVE);
            cvf::ref<RigResultAccessor> satnumAccessor = RigResultAccessorFactory::createFromNameAndType(eclipseCaseData, gridIndex, RiaDefines::MATRIX_MODEL, timeStepIndex, "SATNUM", RiaDefines::STATIC_NATIVE);
            const double cellSWAT = swatAccessor.notNull() ? swatAccessor->cellScalar(gridLocalCellIndex) : HUGE_VAL;
            const double cellSGAS = sgasAccessor.notNull() ? sgasAccessor->cellScalar(gridLocalCellIndex) : HUGE_VAL;
            const double cellSATNUM = satnumAccessor.notNull() ? satnumAccessor->cellScalar(gridLocalCellIndex) : HUGE_VAL;
            //cvf::Trace::show("cellSWAT = %f  cellSGAS = %f  cellSATNUM = %f", cellSWAT, cellSGAS, cellSATNUM);

            QString cellRefText = constructCellReferenceText(eclipseCaseData, gridIndex, gridLocalCellIndex, cellSATNUM);
            QString caseName = eclipseResultCase->caseUserDescription;

            plotPanel->setPlotData(eclipseCaseData->unitsType(), relPermCurveArr, cellSWAT, cellSGAS, caseName, cellRefText);

            return true;
        }
    }

    return false;
}
示例#7
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RimCase::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
    if (changedField == &releaseResultMemory)
    {
        if (this->reservoirData())
        {
            for (size_t i = 0; i < reservoirViews().size(); i++)
            {
                RimReservoirView* reservoirView = reservoirViews()[i];
                CVF_ASSERT(reservoirView);

                RimResultSlot* result = reservoirView->cellResult;
                CVF_ASSERT(result);

                result->setResultVariable(RimDefines::undefinedResultName());
                result->loadResult();

                RimCellEdgeResultSlot* cellEdgeResult = reservoirView->cellEdgeResult;
                CVF_ASSERT(cellEdgeResult);

                cellEdgeResult->resultVariable.v() = RimDefines::undefinedResultName();
                cellEdgeResult->loadResult();

                reservoirView->createDisplayModelAndRedraw();
            }

            RigCaseCellResultsData* matrixModelResults = reservoirData()->results(RifReaderInterface::MATRIX_RESULTS);
            if (matrixModelResults)
            {
                matrixModelResults->clearAllResults();
            }

            RigCaseCellResultsData* fractureModelResults = reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS);
            if (fractureModelResults)
            {
                fractureModelResults->clearAllResults();
            }
        }

        releaseResultMemory = oldValue.toBool();
    }
    else if (changedField == &flipXAxis || changedField == &flipYAxis)
    {
        RigCaseData* rigEclipseCase = reservoirData();
        if (rigEclipseCase)
        {
            rigEclipseCase->mainGrid()->setFlipAxis(flipXAxis, flipYAxis);

            computeCachedData();

            for (size_t i = 0; i < reservoirViews().size(); i++)
            {
                RimReservoirView* reservoirView = reservoirViews()[i];

                reservoirView->scheduleReservoirGridGeometryRegen();
                reservoirView->schedulePipeGeometryRegen();
                reservoirView->createDisplayModelAndRedraw();
            }
        }
    }
}
示例#8
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RimEclipseCellColors::updateLegendData(RimEclipseCase*         rimEclipseCase, 
                                            int                     currentTimeStep,
                                            RimRegularLegendConfig* legendConfig, 
                                            RimTernaryLegendConfig* ternaryLegendConfig)
{
    if (!legendConfig) legendConfig = this->legendConfig();
    if (!ternaryLegendConfig) ternaryLegendConfig = this->m_ternaryLegendConfig();

    if ( this->hasResult() )
    {
        if ( this->isFlowDiagOrInjectionFlooding() )
        {
            CVF_ASSERT(currentTimeStep >= 0);

            double globalMin, globalMax;
            double globalPosClosestToZero, globalNegClosestToZero;
            RigFlowDiagResults* flowResultsData = this->flowDiagSolution()->flowDiagResults();
            RigFlowDiagResultAddress resAddr = this->flowDiagResAddress();

            flowResultsData->minMaxScalarValues(resAddr, currentTimeStep, &globalMin, &globalMax);
            flowResultsData->posNegClosestToZero(resAddr, currentTimeStep, &globalPosClosestToZero, &globalNegClosestToZero);

            double localMin, localMax;
            double localPosClosestToZero, localNegClosestToZero;
            if ( this->hasDynamicResult() )
            {
                flowResultsData->minMaxScalarValues(resAddr, currentTimeStep, &localMin, &localMax);
                flowResultsData->posNegClosestToZero(resAddr, currentTimeStep, &localPosClosestToZero, &localNegClosestToZero);
            }
            else
            {
                localMin = globalMin;
                localMax = globalMax;

                localPosClosestToZero = globalPosClosestToZero;
                localNegClosestToZero = globalNegClosestToZero;
            }

            CVF_ASSERT(legendConfig);

            legendConfig->disableAllTimeStepsRange(true);
            legendConfig->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, 
                                                         localPosClosestToZero, localNegClosestToZero);
            legendConfig->setAutomaticRanges(globalMin, globalMax, localMin, localMax);

            if ( this->hasCategoryResult() && m_reservoirView)
            {
                std::set<std::tuple<QString, int, cvf::Color3ub>, TupleCompare > categories;
                //std::set<std::tuple<QString, int, cvf::Color3ub> > categories;

                std::vector<QString> tracerNames = this->flowDiagSolution()->tracerNames();
                int tracerIndex = 0;
                for ( const auto& tracerName : tracerNames )
                {
                    RimSimWellInView* well = m_reservoirView->wellCollection()->findWell(RimFlowDiagSolution::removeCrossFlowEnding(tracerName));
                    cvf::Color3ub color(cvf::Color3::GRAY);
                    if ( well ) color = cvf::Color3ub(well->wellPipeColor());

                    categories.insert(std::make_tuple(tracerName, tracerIndex, color));
                    ++tracerIndex;
                }

                std::vector<std::tuple<QString, int, cvf::Color3ub>> reverseCategories;
                for ( auto tupIt = categories.rbegin(); tupIt != categories.rend(); ++tupIt )
                {
                    reverseCategories.push_back(*tupIt);
                }

                legendConfig->setCategoryItems(reverseCategories);
            }
        }
        else
        {
            CVF_ASSERT(rimEclipseCase);
            if ( !rimEclipseCase ) return;

            RigEclipseCaseData* eclipseCase = rimEclipseCase->eclipseCaseData();
            CVF_ASSERT(eclipseCase);
            if ( !eclipseCase ) return;

            RigCaseCellResultsData* cellResultsData = eclipseCase->results(this->porosityModel());
            CVF_ASSERT(cellResultsData);

            double globalMin, globalMax;
            double globalPosClosestToZero, globalNegClosestToZero;

            cellResultsData->minMaxCellScalarValues(this->eclipseResultAddress(), globalMin, globalMax);
            cellResultsData->posNegClosestToZero(this->eclipseResultAddress(), globalPosClosestToZero, globalNegClosestToZero);

            double localMin, localMax;
            double localPosClosestToZero, localNegClosestToZero;
            if ( this->hasDynamicResult() && currentTimeStep >= 0)
            {
                cellResultsData->minMaxCellScalarValues(this->eclipseResultAddress(), currentTimeStep, localMin, localMax);
                cellResultsData->posNegClosestToZero(this->eclipseResultAddress(), currentTimeStep, localPosClosestToZero, localNegClosestToZero);
            }
            else
            {
                localMin = globalMin;
                localMax = globalMax;

                localPosClosestToZero = globalPosClosestToZero;
                localNegClosestToZero = globalNegClosestToZero;
            }

            CVF_ASSERT(legendConfig);

            legendConfig->disableAllTimeStepsRange(false);
            legendConfig->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero);
            legendConfig->setAutomaticRanges(globalMin, globalMax, localMin, localMax);

            if ( this->hasCategoryResult() )
            {
                if ( this->resultType() == RiaDefines::FORMATION_NAMES )
                {
                    const std::vector<QString>& fnVector = eclipseCase->activeFormationNames()->formationNames();
                    legendConfig->setNamedCategoriesInverse(fnVector);
                }
                else if ( this->resultType() == RiaDefines::DYNAMIC_NATIVE && this->resultVariable() == RiaDefines::completionTypeResultName() )
                {   
                    const std::vector<int>& visibleCategories = cellResultsData->uniqueCellScalarValues(this->eclipseResultAddress());

                    std::vector<RiaDefines::WellPathComponentType> supportedCompletionTypes =
                        { RiaDefines::WELL_PATH, RiaDefines::FISHBONES, RiaDefines::PERFORATION_INTERVAL, RiaDefines::FRACTURE };
                    
                    RiaColorTables::WellPathComponentColors colors = RiaColorTables::wellPathComponentColors();
                    
                    std::vector< std::tuple<QString, int, cvf::Color3ub> > categories;
                    for (auto completionType : supportedCompletionTypes)
                    {
                        if (std::find(visibleCategories.begin(), visibleCategories.end(), completionType) != visibleCategories.end())
                        {
                            QString categoryText = caf::AppEnum<RiaDefines::WellPathComponentType>::uiText(completionType);
                            categories.push_back(std::make_tuple(categoryText, completionType, colors[completionType]));
                        }
                    }

                    legendConfig->setCategoryItems(categories);
                }
                else
                {
                    legendConfig->setIntegerCategories(cellResultsData->uniqueCellScalarValues(this->eclipseResultAddress()));
                }
            }
        }
    }

    // Ternary legend update
    {
        CVF_ASSERT(rimEclipseCase);
        if ( !rimEclipseCase ) return;

        RigEclipseCaseData* eclipseCase = rimEclipseCase->eclipseCaseData();
        CVF_ASSERT(eclipseCase);
        if ( !eclipseCase ) return;


        RigCaseCellResultsData* cellResultsData = eclipseCase->results(this->porosityModel());

        size_t maxTimeStepCount = cellResultsData->maxTimeStepCount();
        if ( this->isTernarySaturationSelected() && maxTimeStepCount > 1 )
        {
            RigCaseCellResultsData* gridCellResults = this->currentGridCellResults();
            {
                RigEclipseResultAddress resAddr(RiaDefines::DYNAMIC_NATIVE, "SOIL");

                if ( gridCellResults->ensureKnownResultLoaded(resAddr) )
                {
                    double globalMin = 0.0;
                    double globalMax = 1.0;
                    double localMin = 0.0;
                    double localMax = 1.0;

                    cellResultsData->minMaxCellScalarValues(resAddr, globalMin, globalMax);
                    cellResultsData->minMaxCellScalarValues(resAddr, currentTimeStep, localMin, localMax);

                    ternaryLegendConfig->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SOIL_IDX, globalMin, globalMax, localMin, localMax);
                }
            }

            {
                RigEclipseResultAddress resAddr(RiaDefines::DYNAMIC_NATIVE, "SGAS");
                
                if ( gridCellResults->ensureKnownResultLoaded(resAddr) )
                {
                    double globalMin = 0.0;
                    double globalMax = 1.0;
                    double localMin = 0.0;
                    double localMax = 1.0;

                    cellResultsData->minMaxCellScalarValues(resAddr, globalMin, globalMax);
                    cellResultsData->minMaxCellScalarValues(resAddr, currentTimeStep, localMin, localMax);

                    ternaryLegendConfig->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SGAS_IDX, globalMin, globalMax, localMin, localMax);
                }
            }

            {
                RigEclipseResultAddress resAddr(RiaDefines::DYNAMIC_NATIVE, "SWAT");

                if ( gridCellResults->ensureKnownResultLoaded(resAddr) )
                {
                    double globalMin = 0.0;
                    double globalMax = 1.0;
                    double localMin = 0.0;
                    double localMax = 1.0;

                    cellResultsData->minMaxCellScalarValues(resAddr, globalMin, globalMax);
                    cellResultsData->minMaxCellScalarValues(resAddr, currentTimeStep, localMin, localMax);

                    ternaryLegendConfig->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SWAT_IDX, globalMin, globalMax, localMin, localMax);
                }
            }
        }
    }
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCaseEvaluator::evaluateForResults(const QList<ResSpec>& resultSpecification)
{
    CVF_ASSERT(m_destinationCase);
    
    // First build the destination result data structures to receive the statistics

    for (int i = 0; i < resultSpecification.size(); i++)
    {
        RifReaderInterface::PorosityModelResultType poroModel = resultSpecification[i].m_poroModel;
        RimDefines::ResultCatType resultType = resultSpecification[i].m_resType;
        QString resultName = resultSpecification[i].m_resVarName;

        size_t activeCellCount = m_destinationCase->activeCellInfo(poroModel)->reservoirActiveCellCount();
        RigCaseCellResultsData* destCellResultsData = m_destinationCase->results(poroModel);

        // Placeholder data used to be created here,
        // this is now moved to RimIdenticalGridCaseGroup::loadMainCaseAndActiveCellInfo()


        // Create new result data structures to contain the statistical values
        std::vector<QString> statisticalResultNames;

        statisticalResultNames.push_back(createResultNameMin(resultName));
        statisticalResultNames.push_back(createResultNameMax(resultName));
        statisticalResultNames.push_back(createResultNameMean(resultName));
        statisticalResultNames.push_back(createResultNameDev(resultName));
        statisticalResultNames.push_back(createResultNameRange(resultName));

        if (m_statisticsConfig.m_calculatePercentiles)
        {
            statisticalResultNames.push_back(createResultNamePVal(resultName, m_statisticsConfig.m_pMinPos));
            statisticalResultNames.push_back(createResultNamePVal(resultName, m_statisticsConfig.m_pMidPos));
            statisticalResultNames.push_back(createResultNamePVal(resultName, m_statisticsConfig.m_pMaxPos));
        }

        if (activeCellCount > 0)
        {
            for (size_t i = 0; i < statisticalResultNames.size(); ++i)
            {
                addNamedResult(destCellResultsData, resultType, statisticalResultNames[i], activeCellCount);
            }
        }
    }

    // Start the loop that calculates the statistics

    caf::ProgressInfo progressInfo(m_timeStepIndices.size(), "Computing Statistics");

    for (size_t timeIndicesIdx = 0; timeIndicesIdx < m_timeStepIndices.size(); timeIndicesIdx++)
    {
        size_t timeStepIdx = m_timeStepIndices[timeIndicesIdx];

        for (size_t gridIdx = 0; gridIdx < m_destinationCase->gridCount(); gridIdx++)
        {
            RigGridBase* grid = m_destinationCase->grid(gridIdx);

            for (int resSpecIdx = 0; resSpecIdx < resultSpecification.size(); resSpecIdx++)
            {
                RifReaderInterface::PorosityModelResultType poroModel = resultSpecification[resSpecIdx].m_poroModel;
                RimDefines::ResultCatType resultType = resultSpecification[resSpecIdx].m_resType;
                QString resultName = resultSpecification[resSpecIdx].m_resVarName;

                size_t activeCellCount = m_destinationCase->activeCellInfo(poroModel)->reservoirActiveCellCount();

                if (activeCellCount == 0) continue;

                RigCaseCellResultsData* destCellResultsData = m_destinationCase->results(poroModel);

                size_t dataAccessTimeStepIndex = timeStepIdx;

                // Always evaluate statistics once, and always use time step index zero
                if (resultType == RimDefines::STATIC_NATIVE)
                {
                    if (timeIndicesIdx > 0) continue;

                    dataAccessTimeStepIndex = 0;
                }

                // Build data access objects for source scalar results

                cvf::Collection<RigResultAccessor> sourceDataAccessList;
                for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++)
                {
                    RimEclipseCase* sourceCase = m_sourceCases.at(caseIdx);

                    // Trigger loading of dataset
                    sourceCase->results(poroModel)->findOrLoadScalarResultForTimeStep(resultType, resultName, dataAccessTimeStepIndex);

                    cvf::ref<RigResultAccessor> resultAccessor = RigResultAccessorFactory::createResultAccessor(sourceCase->reservoirData(), gridIdx, poroModel, dataAccessTimeStepIndex, resultName, resultType);
                    if (resultAccessor.notNull())
                    {
                        sourceDataAccessList.push_back(resultAccessor.p());
                    }
                }

                // Build data access objects for destination scalar results
                // Find the created result container, if any, and put its resultAccessor into the enum indexed destination collection

                cvf::Collection<RigResultModifier> destinationDataAccessList;
                std::vector<QString> statisticalResultNames(STAT_PARAM_COUNT);

                statisticalResultNames[MIN] = createResultNameMin(resultName);
                statisticalResultNames[MAX] = createResultNameMax(resultName);
                statisticalResultNames[RANGE] = createResultNameRange(resultName);
                statisticalResultNames[MEAN] = createResultNameMean(resultName);
                statisticalResultNames[STDEV] = createResultNameDev(resultName);
                statisticalResultNames[PMIN] = createResultNamePVal(resultName, m_statisticsConfig.m_pMinPos);
                statisticalResultNames[PMID] = createResultNamePVal(resultName, m_statisticsConfig.m_pMidPos);
                statisticalResultNames[PMAX] = createResultNamePVal(resultName, m_statisticsConfig.m_pMaxPos);

                for (size_t stIdx = 0; stIdx < statisticalResultNames.size(); ++stIdx)
                {
                    size_t scalarResultIndex = destCellResultsData->findScalarResultIndex(resultType, statisticalResultNames[stIdx]);

                    cvf::ref<RigResultModifier> resultModifier = RigResultModifierFactory::createResultModifier(m_destinationCase, grid->gridIndex(), poroModel, dataAccessTimeStepIndex, scalarResultIndex);
                    destinationDataAccessList.push_back(resultModifier.p());
                }

                 std::vector<double> statParams(STAT_PARAM_COUNT, HUGE_VAL);
                 std::vector<double> values(sourceDataAccessList.size(), HUGE_VAL);
                // Loop over the cells in the grid, get the case values, and calculate the cell statistics 
#pragma omp parallel for schedule(dynamic) firstprivate(statParams, values)
                for (int cellIdx = 0; static_cast<size_t>(cellIdx) < grid->cellCount(); cellIdx++)
                {

                    size_t reservoirCellIndex = grid->reservoirCellIndex(cellIdx);
                    if (m_destinationCase->activeCellInfo(poroModel)->isActive(reservoirCellIndex))
                    {
                        // Extract the cell values from each of the cases and assemble them into one vector

                        

                        bool foundAnyValidValues = false;
                        for (size_t caseIdx = 0; caseIdx < sourceDataAccessList.size(); caseIdx++)
                        {
                            double val = sourceDataAccessList.at(caseIdx)->cellScalar(cellIdx);
                            values[caseIdx] = val;

                            if (val != HUGE_VAL)
                            {
                                foundAnyValidValues = true;
                            }
                        }

                        // Do the real statistics calculations
                       

                        if (foundAnyValidValues)
                        {
                            RigStatisticsMath::calculateBasicStatistics(values, &statParams[MIN], &statParams[MAX], &statParams[RANGE], &statParams[MEAN], &statParams[STDEV]);

                            // Calculate percentiles
                            if (m_statisticsConfig.m_calculatePercentiles )
                            {
                                if (m_statisticsConfig.m_pValMethod == RimEclipseStatisticsCase::NEAREST_OBSERVATION)
                                {
                                    std::vector<double> pValPoss;
                                    pValPoss.push_back(m_statisticsConfig.m_pMinPos);
                                    pValPoss.push_back(m_statisticsConfig.m_pMidPos);
                                    pValPoss.push_back(m_statisticsConfig.m_pMaxPos);
                                    std::vector<double> pVals = RigStatisticsMath::calculateNearestRankPercentiles(values, pValPoss);
                                    statParams[PMIN] = pVals[0];
                                    statParams[PMID] = pVals[1];
                                    statParams[PMAX] = pVals[2];
                                }
                                else if (m_statisticsConfig.m_pValMethod == RimEclipseStatisticsCase::HISTOGRAM_ESTIMATED)
                                {
                                    std::vector<size_t> histogram;
                                    RigHistogramCalculator histCalc(statParams[MIN], statParams[MAX], 100, &histogram);
                                    histCalc.addData(values);
                                    statParams[PMIN] = histCalc.calculatePercentil(m_statisticsConfig.m_pMinPos);
                                    statParams[PMID] = histCalc.calculatePercentil(m_statisticsConfig.m_pMidPos);
                                    statParams[PMAX] = histCalc.calculatePercentil(m_statisticsConfig.m_pMaxPos);
                                }
                                else if (m_statisticsConfig.m_pValMethod == RimEclipseStatisticsCase::INTERPOLATED_OBSERVATION)
                                {
                                    std::vector<double> pValPoss;
                                    pValPoss.push_back(m_statisticsConfig.m_pMinPos);
                                    pValPoss.push_back(m_statisticsConfig.m_pMidPos);
                                    pValPoss.push_back(m_statisticsConfig.m_pMaxPos);
                                    std::vector<double> pVals = RigStatisticsMath::calculateInterpolatedPercentiles(values, pValPoss);
                                    statParams[PMIN] = pVals[0];
                                    statParams[PMID] = pVals[1];
                                    statParams[PMAX] = pVals[2];
                                }
                                else
                                {
                                    CVF_ASSERT(false);
                                }
                            }
                        }

                        // Set the results into the results data structures

                        for (size_t stIdx = 0; stIdx < statParams.size(); ++stIdx)
                        {
                            if (destinationDataAccessList[stIdx].notNull())
                            {
                                destinationDataAccessList[stIdx]->setCellScalar(cellIdx, statParams[stIdx]);
                            }
                        }
                    }
                }
            }
        }

        // When one time step is completed, free memory and clean up
        // Microsoft note: On Windows, the maximum number of files open at the same time is 512
        // http://msdn.microsoft.com/en-us/library/kdfaxaay%28vs.71%29.aspx

        for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++)
        {
            RimEclipseCase* eclipseCase = m_sourceCases.at(caseIdx);

            if (!eclipseCase->reservoirViews.size())
            {
                eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->freeAllocatedResultsData();
                eclipseCase->results(RifReaderInterface::FRACTURE_RESULTS)->cellResults()->freeAllocatedResultsData();
            }

            // Todo : These calls really do nothing right now the access actually closes automatically in ert i belive ...
            eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->readerInterface()->close();
            eclipseCase->results(RifReaderInterface::FRACTURE_RESULTS)->readerInterface()->close();
        }

        progressInfo.setProgress(timeIndicesIdx);
    }
}