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(); } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- 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(); } } } } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- 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); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- 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; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- 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(); } } } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- 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); } }