diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index c7f2e1cab..0ad6e9d0b 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -104,6 +104,7 @@ list (APPEND MAIN_SOURCE_FILES opm/simulators/wells/VFPProdProperties.cpp opm/simulators/wells/VFPInjProperties.cpp opm/simulators/wells/WellConvergence.cpp + opm/simulators/wells/WellGroupConstraints.cpp opm/simulators/wells/WellGroupControls.cpp opm/simulators/wells/WellGroupHelpers.cpp opm/simulators/wells/WellHelpers.cpp @@ -386,6 +387,7 @@ list (APPEND PUBLIC_HEADER_FILES opm/simulators/wells/VFPProperties.hpp opm/simulators/wells/WellConnectionAuxiliaryModule.hpp opm/simulators/wells/WellConvergence.hpp + opm/simulators/wells/WellGroupConstraints.hpp opm/simulators/wells/WellGroupControls.hpp opm/simulators/wells/WellGroupHelpers.hpp opm/simulators/wells/WellHelpers.hpp diff --git a/opm/simulators/wells/WellGroupConstraints.cpp b/opm/simulators/wells/WellGroupConstraints.cpp new file mode 100644 index 000000000..3bfedfb28 --- /dev/null +++ b/opm/simulators/wells/WellGroupConstraints.cpp @@ -0,0 +1,94 @@ +/* + 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 + +namespace Opm +{ + +std::pair +WellGroupConstraints:: +checkGroupConstraintsInj(const Group& group, + const WellState& well_state, + const GroupState& group_state, + const double efficiencyFactor, + const Schedule& schedule, + const SummaryState& summaryState, + const RateConvFunc& rateConverter, + DeferredLogger& deferred_logger) const +{ + // Translate injector type from control to Phase. + const auto& well_controls = well_.wellEcl().injectionControls(summaryState); + auto injectorType = well_controls.injector_type; + Phase injectionPhase; + switch (injectorType) { + case InjectorType::WATER: + { + injectionPhase = Phase::WATER; + break; + } + case InjectorType::OIL: + { + injectionPhase = Phase::OIL; + break; + } + case InjectorType::GAS: + { + injectionPhase = Phase::GAS; + break; + } + default: + throw("Expected WATER, OIL or GAS as type for injector " + well_.name()); + } + + // Make conversion factors for RESV <-> surface rates. + std::vector resv_coeff(well_.phaseUsage().num_phases, 1.0); + rateConverter(0, well_.pvtRegionIdx(), resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. + + const auto& ws = well_state.well(well_.indexOfWell()); + // Call check for the well's injection phase. + return WellGroupHelpers::checkGroupConstraintsInj(well_.name(), + well_.wellEcl().groupName(), + group, + well_state, + group_state, + well_.currentStep(), + well_.guideRate(), + ws.surface_rates.data(), + injectionPhase, + well_.phaseUsage(), + efficiencyFactor, + schedule, + summaryState, + resv_coeff, + deferred_logger); +} + +} // namespace Opm diff --git a/opm/simulators/wells/WellGroupConstraints.hpp b/opm/simulators/wells/WellGroupConstraints.hpp new file mode 100644 index 000000000..c9739feab --- /dev/null +++ b/opm/simulators/wells/WellGroupConstraints.hpp @@ -0,0 +1,68 @@ +/* + Copyright 2017 SINTEF Digital, Mathematics and Cybernetics. + Copyright 2017 Statoil ASA. + Copyright 2017 IRIS + Copyright 2019 Norce + + 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 . +*/ + + +#ifndef OPM_WELL_GROUP_CONSTRAINTS_HEADER_INCLUDED +#define OPM_WELL_GROUP_CONSTRAINTS_HEADER_INCLUDED + +#include +#include +#include + +namespace Opm +{ + +class DeferredLogger; +class Group; +class GroupState; +enum class InjectorType; +using RegionId = int; +class Schedule; +class SummaryState; +class WellInterfaceGeneric; +class WellState; + +//! \brief Class for computing well group constraints. +class WellGroupConstraints { +public: + //! \brief Constructor sets reference to well. + WellGroupConstraints(const WellInterfaceGeneric& well) : well_(well) {} + + using RateConvFunc = std::function&)>; + + std::pair + checkGroupConstraintsInj(const Group& group, + const WellState& well_state, + const GroupState& group_state, + const double efficiencyFactor, + const Schedule& schedule, + const SummaryState& summaryState, + const RateConvFunc& rateConverter, + DeferredLogger& deferred_logger) const; + +private: + const WellInterfaceGeneric& well_; //!< Reference to well interface +}; + +} + +#endif // OPM_WELL_GROUP_CONSTRAINTS_HEADER_INCLUDED diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.cpp b/opm/simulators/wells/WellInterfaceFluidSystem.cpp index 0ba58228f..0a87a0481 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.cpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.cpp @@ -22,16 +22,19 @@ #include #include -#include +#include #include +#include + #include #include #include #include #include #include +#include #include #include #include @@ -324,64 +327,6 @@ checkIndividualConstraints(SingleWellState& ws, return false; } -template -std::pair -WellInterfaceFluidSystem:: -checkGroupConstraintsInj(const Group& group, - const WellState& well_state, - const GroupState& group_state, - const double efficiencyFactor, - const Schedule& schedule, - const SummaryState& summaryState, - DeferredLogger& deferred_logger) const -{ - // Translate injector type from control to Phase. - const auto& well_controls = this->well_ecl_.injectionControls(summaryState); - auto injectorType = well_controls.injector_type; - Phase injectionPhase; - switch (injectorType) { - case InjectorType::WATER: - { - injectionPhase = Phase::WATER; - break; - } - case InjectorType::OIL: - { - injectionPhase = Phase::OIL; - break; - } - case InjectorType::GAS: - { - injectionPhase = Phase::GAS; - break; - } - default: - throw("Expected WATER, OIL or GAS as type for injector " + name()); - } - - // Make conversion factors for RESV <-> surface rates. - std::vector resv_coeff(phaseUsage().num_phases, 1.0); - rateConverter_.calcInjCoeff(0, pvtRegionIdx_, resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. - - const auto& ws = well_state.well(this->index_of_well_); - // Call check for the well's injection phase. - return WellGroupHelpers::checkGroupConstraintsInj(name(), - well_ecl_.groupName(), - group, - well_state, - group_state, - current_step_, - guide_rate_, - ws.surface_rates.data(), - injectionPhase, - phaseUsage(), - efficiencyFactor, - schedule, - summaryState, - resv_coeff, - deferred_logger); -} - template std::pair WellInterfaceFluidSystem:: @@ -427,6 +372,11 @@ checkGroupConstraints(WellState& well_state, const int well_index = index_of_well_; auto& ws = well_state.well(well_index); + auto rCoeff = [this](const int id, const int region, std::vector& coeff) + { + this->rateConverter().calcCoeff(id, region, coeff); + }; + if (well.isInjector()) { const auto currentControl = ws.injection_cmode; @@ -440,8 +390,15 @@ checkGroupConstraints(WellState& well_state, const auto& group = schedule.getGroup( well.groupName(), current_step_ ); const double efficiencyFactor = well.getEfficiencyFactor(); const std::pair group_constraint = - checkGroupConstraintsInj(group, well_state, group_state, efficiencyFactor, - schedule, summaryState, deferred_logger); + WellGroupConstraints(*this). + checkGroupConstraintsInj(group, + well_state, + group_state, + efficiencyFactor, + schedule, + summaryState, + rCoeff, + deferred_logger); // If a group constraint was broken, we set the current well control to // be GRUP. if (group_constraint.first) { diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.hpp b/opm/simulators/wells/WellInterfaceFluidSystem.hpp index 26dbfd73c..abf8a222f 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.hpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.hpp @@ -89,14 +89,6 @@ protected: const SummaryState& summaryState, DeferredLogger& deferred_logger) const; - std::pair checkGroupConstraintsInj(const Group& group, - const WellState& well_state, - const GroupState& group_state, - const double efficiencyFactor, - const Schedule& schedule, - const SummaryState& summaryState, - DeferredLogger& deferred_logger) const; - std::pair checkGroupConstraintsProd(const Group& group, const WellState& well_state, const GroupState& group_state,