/* Copyright 2017 SINTEF Digital, Mathematics and Cybernetics. Copyright 2017 Statoil ASA. Copyright 2018 IRIS This file is part of the Open Porous Media project (OPM). OPM 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. OPM 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 for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Opm { template WellInterfaceFluidSystem:: WellInterfaceFluidSystem(const Well& well, const ParallelWellInfo& parallel_well_info, const int time_step, const RateConverterType& rate_converter, const int pvtRegionIdx, const int num_components, const int num_phases, const int index_of_well, const std::vector& perf_data) : WellInterfaceGeneric(well, parallel_well_info, time_step, pvtRegionIdx, num_components, num_phases, index_of_well, perf_data) , rateConverter_(rate_converter) { } template void WellInterfaceFluidSystem:: calculateReservoirRates(SingleWellState& ws) const { const int fipreg = 0; // not considering the region for now const int np = number_of_phases_; this->rateConverter_ .calcReservoirVoidageRates(fipreg, this->pvtRegionIdx_, ws.surface_rates, ws.reservoir_rates); // Compute total connection reservoir rate CVPR/CVIR auto& perf_data = ws.perf_data; const auto num_perf_well = perf_data.size(); const auto& surf_perf_rates = perf_data.phase_rates; for (auto i = 0*num_perf_well; i < num_perf_well; ++i) { const auto surface_rates_perf = std::vector { surf_perf_rates.begin() + (i + 0)*np , surf_perf_rates.begin() + (i + 1)*np }; std::vector voidage_rates_perf(np, 0.0); this->rateConverter_ .calcReservoirVoidageRates(fipreg, this->pvtRegionIdx_, surface_rates_perf, voidage_rates_perf); perf_data.rates[i] = std::accumulate(voidage_rates_perf.begin(), voidage_rates_perf.end(), 0.0); } } template bool WellInterfaceFluidSystem:: checkIndividualConstraints(SingleWellState& ws, const SummaryState& summaryState, DeferredLogger& deferred_logger) const { auto rRates = [this](const int fipreg, const int pvtRegion, const std::vector& surface_rates, std::vector& voidage_rates) { return rateConverter_.calcReservoirVoidageRates(fipreg, pvtRegion, surface_rates, voidage_rates); }; return WellConstraints(*this). checkIndividualConstraints(ws, summaryState, rRates, this->operability_status_.thp_limit_violated_but_not_switched, deferred_logger); } template bool WellInterfaceFluidSystem:: checkGroupConstraints(WellState& well_state, const GroupState& group_state, const Schedule& schedule, const SummaryState& summaryState, DeferredLogger& deferred_logger) const { if (!this->wellEcl().isAvailableForGroupControl()) return false; auto rCoeff = [this, &group_state](const RegionId id, const int region, const std::optional& prod_gname, std::vector& coeff) { if (prod_gname) this->rateConverter().calcCoeff(id, region, group_state.production_rates(*prod_gname), coeff); else this->rateConverter().calcInjCoeff(id, region, coeff); }; return WellGroupConstraints(*this).checkGroupConstraints(well_state, group_state, schedule, summaryState, rCoeff, deferred_logger); } template bool WellInterfaceFluidSystem:: checkConstraints(WellState& well_state, const GroupState& group_state, const Schedule& schedule, const SummaryState& summaryState, DeferredLogger& deferred_logger) const { const bool ind_broken = checkIndividualConstraints(well_state.well(this->index_of_well_), summaryState, deferred_logger); if (ind_broken) { return true; } else { return checkGroupConstraints(well_state, group_state, schedule, summaryState, deferred_logger); } } template int WellInterfaceFluidSystem:: flowPhaseToEbosPhaseIdx(const int phaseIdx) const { const auto& pu = this->phaseUsage(); if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx) && pu.phase_pos[Water] == phaseIdx) return FluidSystem::waterPhaseIdx; if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) && pu.phase_pos[Oil] == phaseIdx) return FluidSystem::oilPhaseIdx; if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx) && pu.phase_pos[Gas] == phaseIdx) return FluidSystem::gasPhaseIdx; // for other phases return the index return phaseIdx; } template std::optional WellInterfaceFluidSystem:: getGroupInjectionTargetRate(const Group& group, const WellState& well_state, const GroupState& group_state, const Schedule& schedule, const SummaryState& summaryState, const InjectorType& injectorType, double efficiencyFactor, DeferredLogger& deferred_logger) const { auto rCoeff = [this, &group_state](const RegionId id, const int region, const std::optional& prod_gname, std::vector& coeff) { if (prod_gname) this->rateConverter().calcCoeff(id, region, group_state.production_rates(*prod_gname), coeff); else this->rateConverter().calcInjCoeff(id, region, coeff); }; return WellGroupControls(*this).getGroupInjectionTargetRate(group, well_state, group_state, schedule, summaryState, injectorType, rCoeff, efficiencyFactor, deferred_logger); } template double WellInterfaceFluidSystem:: getGroupProductionTargetRate(const Group& group, const WellState& well_state, const GroupState& group_state, const Schedule& schedule, const SummaryState& summaryState, double efficiencyFactor, DeferredLogger& deferred_logger) const { auto rCoeff = [this, &group_state](const RegionId id, const int region, const std::optional& prod_gname, std::vector& coeff) { if (prod_gname) this->rateConverter().calcCoeff(id, region, group_state.production_rates(*prod_gname), coeff); else this->rateConverter().calcInjCoeff(id, region, coeff); }; return WellGroupControls(*this).getGroupProductionTargetRate(group, well_state, group_state, schedule, summaryState, rCoeff, efficiencyFactor, deferred_logger); } template class WellInterfaceFluidSystem>; } // namespace Opm