///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2017- Statoil ASA // // 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 "RigTofAccumulatedPhaseFractionsCalculator.h" #include "RiaDefines.h" #include "RiaPorosityModel.h" #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" #include "RigFlowDiagResultAddress.h" #include "RigFlowDiagResults.h" #include "RigResultAccessor.h" #include "RigResultAccessorFactory.h" #include "RimEclipseResultCase.h" #include "RimFlowDiagSolution.h" #include "RimReservoirCellResultsStorage.h" #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigTofAccumulatedPhaseFractionsCalculator::RigTofAccumulatedPhaseFractionsCalculator( RimEclipseResultCase* caseToApply, QString wellname, size_t timestep ) { RigEclipseCaseData* eclipseCaseData = caseToApply->eclipseCaseData(); if ( !eclipseCaseData ) return; const std::vector* swatResults = eclipseCaseData->resultValues( RiaDefines::PorosityModelType::MATRIX_MODEL, RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SWAT", timestep ); const std::vector* soilResults = eclipseCaseData->resultValues( RiaDefines::PorosityModelType::MATRIX_MODEL, RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SOIL", timestep ); const std::vector* sgasResults = eclipseCaseData->resultValues( RiaDefines::PorosityModelType::MATRIX_MODEL, RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SGAS", timestep ); const std::vector* porvResults = eclipseCaseData->resultValues( RiaDefines::PorosityModelType::MATRIX_MODEL, RiaDefines::ResultCatType::STATIC_NATIVE, "PORV", 0 ); RimFlowDiagSolution* flowDiagSolution = caseToApply->defaultFlowDiagSolution(); std::string resultNameTof = "TOF"; const std::vector* tofData = flowDiagSolution->flowDiagResults() ->resultValues( RigFlowDiagResultAddress( resultNameTof, RigFlowDiagResultAddress::PhaseSelection::PHASE_ALL, wellname.toStdString() ), timestep ); std::string resultNameFraction = "Fraction"; const std::vector* fractionData = flowDiagSolution->flowDiagResults() ->resultValues( RigFlowDiagResultAddress( resultNameFraction, RigFlowDiagResultAddress::PhaseSelection::PHASE_ALL, wellname.toStdString() ), timestep ); sortTofAndCalculateAccPhaseFraction( tofData, fractionData, porvResults, swatResults, soilResults, sgasResults, m_tofInIncreasingOrder, m_accumulatedPhaseFractionSwat, m_accumulatedPhaseFractionSoil, m_accumulatedPhaseFractionSgas ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigTofAccumulatedPhaseFractionsCalculator::sortTofAndCalculateAccPhaseFraction( const std::vector* tofData, const std::vector* fractionData, const std::vector* porvResults, const std::vector* swatResults, const std::vector* soilResults, const std::vector* sgasResults, std::vector& tofInIncreasingOrder, std::vector& accumulatedPhaseFractionSwat, std::vector& accumulatedPhaseFractionSoil, std::vector& accumulatedPhaseFractionSgas ) { if ( tofData == nullptr || fractionData == nullptr ) { return; } std::map> tofAndIndexMap; for ( int i = 0; i < static_cast( tofData->size() ); i++ ) { if ( ( *tofData )[i] == HUGE_VAL ) continue; std::vector vectorOfIndexes; vectorOfIndexes.push_back( i ); auto iteratorBoolFromInsertToMap = tofAndIndexMap.insert( std::make_pair( tofData->at( i ), vectorOfIndexes ) ); if ( !iteratorBoolFromInsertToMap.second ) { // Element exist already, was not inserted iteratorBoolFromInsertToMap.first->second.push_back( i ); } } double fractionPorvSum = 0.0; double fractionPorvPhaseSumSwat = 0.0; double fractionPorvPhaseSumSoil = 0.0; double fractionPorvPhaseSumSgas = 0.0; for ( const auto& element : tofAndIndexMap ) { double tofValue = element.first; for ( int index : element.second ) { fractionPorvSum += fractionData->at( index ) * porvResults->at( index ); if ( swatResults != nullptr ) { fractionPorvPhaseSumSwat += fractionData->at( index ) * porvResults->at( index ) * swatResults->at( index ); } if ( soilResults != nullptr ) { fractionPorvPhaseSumSoil += fractionData->at( index ) * porvResults->at( index ) * soilResults->at( index ); } if ( sgasResults != nullptr ) { fractionPorvPhaseSumSgas += fractionData->at( index ) * porvResults->at( index ) * sgasResults->at( index ); } } tofInIncreasingOrder.push_back( tofValue ); accumulatedPhaseFractionSwat.push_back( fractionPorvPhaseSumSwat / fractionPorvSum ); accumulatedPhaseFractionSoil.push_back( fractionPorvPhaseSumSoil / fractionPorvSum ); accumulatedPhaseFractionSgas.push_back( fractionPorvPhaseSumSgas / fractionPorvSum ); } }