///////////////////////////////////////////////////////////////////////////////// // // 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. // ///////////////////////////////////////////////////////////////////////////////// #pragma once #include "RigFlowDiagResultAddress.h" #include #include #include #include #include #include #include #include #include #include #include namespace RigFlowDiagInterfaceTools { std::vector getPhases( RigFlowDiagResultAddress::PhaseSelection phaseSelection ) { std::vector phases; if ( phaseSelection & RigFlowDiagResultAddress::PHASE_GAS ) { phases.push_back( Opm::ECLPhaseIndex::Vapour ); } if ( phaseSelection & RigFlowDiagResultAddress::PHASE_OIL ) { phases.push_back( Opm::ECLPhaseIndex::Liquid ); } if ( phaseSelection & RigFlowDiagResultAddress::PHASE_WAT ) { phases.push_back( Opm::ECLPhaseIndex::Aqua ); } return phases; } template inline Opm::FlowDiagnostics::ConnectionValues extractFluxField( const Opm::ECLGraph& G, FluxCalc&& getFlux, std::vector actPh ) { using ConnVals = Opm::FlowDiagnostics::ConnectionValues; auto flux = ConnVals( ConnVals::NumConnections{ G.numConnections() }, ConnVals::NumPhases{ actPh.size() } ); auto phas = ConnVals::PhaseID{ 0 }; for ( const auto& p : actPh ) { const auto pflux = getFlux( p ); if ( !pflux.empty() ) { assert( pflux.size() == flux.numConnections() ); auto conn = ConnVals::ConnID{ 0 }; for ( const auto& v : pflux ) { flux( conn, phas ) = v; conn.id += 1; } } phas.id += 1; } return flux; } inline Opm::FlowDiagnostics::ConnectionValues extractFluxFieldFromRestartFile( const Opm::ECLGraph& G, const Opm::ECLRestartData& rstrt, RigFlowDiagResultAddress::PhaseSelection phaseSelection ) { auto getFlux = [&G, &rstrt]( const Opm::ECLPhaseIndex p ) { return G.flux( rstrt, p ); }; return extractFluxField( G, getFlux, getPhases( phaseSelection ) ); } inline Opm::FlowDiagnostics::ConnectionValues calculateFluxField( const Opm::ECLGraph& G, const Opm::ECLInitFileData& init, const Opm::ECLRestartData& rstrt, RigFlowDiagResultAddress::PhaseSelection phaseSelection ) { auto satfunc = Opm::ECLSaturationFunc( G, init ); Opm::ECLFluxCalc calc( G, init, 9.80665, false ); auto getFlux = [&calc, &rstrt]( const Opm::ECLPhaseIndex p ) { return calc.flux( rstrt, p ); }; return extractFluxField( G, getFlux, getPhases( phaseSelection ) ); } template std::map extractWellFlows( const Opm::ECLGraph& G, const WellFluxes& well_fluxes ) { std::map well_flows; for ( const auto& well : well_fluxes ) { Opm::FlowDiagnostics::CellSetValues& inflow = well_flows[Opm::FlowDiagnostics::CellSetID( well.name )]; for ( const auto& completion : well.completions ) { const auto& gridName = completion.gridName; const auto& ijk = completion.ijk; const int cell_index = G.activeCell( ijk, gridName ); if ( cell_index >= 0 ) { // Since inflow is a std::map, if the key was not // already present operator[] will insert a // value-initialized value (as in T() for a type // T), which is zero for built-in numerical types, // including double. inflow[cell_index] += completion.reservoir_inflow_rate; } } } return well_flows; } } // namespace RigFlowDiagInterfaceTools