Files
opm-simulators/opm/simulators/wells/WellGroupConstraints.cpp
T
Håkon Hægland e7461f9332 Refactor: Remove unused DeferredLogger parameter from methods
Remove the DeferredLogger parameter from methods that don't use it.
This simplifies the method signature and call sites.

Part of the DeferredLogger refactoring series for GroupStateHelper.
2026-01-10 07:36:38 +01:00

202 lines
7.9 KiB
C++

/*
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 <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <opm/simulators/wells/WellGroupConstraints.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/material/fluidsystems/BlackOilDefaultFluidSystemIndices.hpp>
#include <opm/simulators/wells/GroupStateHelper.hpp>
#include <opm/simulators/wells/WellInterfaceGeneric.hpp>
#include <opm/simulators/wells/WellState.hpp>
namespace Opm
{
template<typename Scalar, typename IndexTraits>
std::pair<bool, Scalar>
WellGroupConstraints<Scalar, IndexTraits>::
checkGroupConstraintsInj(const Group& group,
const GroupStateHelperType& groupStateHelper,
const Scalar efficiencyFactor,
const SummaryState& summaryState,
const RateConvFunc& rateConverter,
const bool check_guide_rate) const
{
const auto& well_state = groupStateHelper.wellState();
// 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<Scalar> resv_coeff(well_.phaseUsage().numActivePhases(), 1.0);
rateConverter(0, well_.pvtRegionIdx(), group.name(), 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 groupStateHelper.checkGroupConstraintsInj(
well_.name(),
well_.wellEcl().groupName(),
group,
ws.surface_rates.data(),
injectionPhase,
efficiencyFactor,
resv_coeff,
check_guide_rate
);
}
template<typename Scalar, typename IndexTraits>
std::pair<bool, Scalar>
WellGroupConstraints<Scalar, IndexTraits>::
checkGroupConstraintsProd(const Group& group,
const GroupStateHelperType& groupStateHelper,
const Scalar efficiencyFactor,
const RateConvFunc& rateConverter,
const bool check_guide_rate) const
{
const auto& well_state = groupStateHelper.wellState();
// Make conversion factors for RESV <-> surface rates.
std::vector<Scalar> resv_coeff(well_.phaseUsage().numActivePhases(), 1.0);
rateConverter(0, well_.pvtRegionIdx(), group.name(), resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS.
const auto& ws = well_state.well(well_.indexOfWell());
return groupStateHelper.checkGroupConstraintsProd(well_.name(),
well_.wellEcl().groupName(),
group,
ws.surface_rates.data(),
efficiencyFactor,
resv_coeff,
check_guide_rate
);
}
template<typename Scalar, typename IndexTraits>
bool WellGroupConstraints<Scalar, IndexTraits>::
checkGroupConstraints(const GroupStateHelperType& groupStateHelper,
const Schedule& schedule,
const SummaryState& summaryState,
const RateConvFunc& rateConverter,
const bool check_guide_rate,
WellStateType& well_state) const
{
const auto& well = well_.wellEcl();
const int well_index = well_.indexOfWell();
auto& ws = well_state.well(well_index);
if (well.isInjector()) {
const auto currentControl = ws.injection_cmode;
if (currentControl != Well::InjectorCMode::GRUP) {
// This checks only the first encountered group limit,
// in theory there could be several, and then we should
// test all but the one currently applied. At that point,
// this if-statement should be removed and we should always
// check, skipping over only the single group parent whose
// control is the active one for the well (if any).
const auto& group = schedule.getGroup(well.groupName(), well_.currentStep());
const Scalar efficiencyFactor = well.getEfficiencyFactor() *
well_state[well.name()].efficiency_scaling_factor;
const std::pair<bool, Scalar> group_constraint =
this->checkGroupConstraintsInj(group, groupStateHelper, efficiencyFactor,
summaryState,
rateConverter,
check_guide_rate);
// If a group constraint was broken, we set the current well control to
// be GRUP.
if (group_constraint.first) {
ws.injection_cmode = Well::InjectorCMode::GRUP;
const int np = well_state.numPhases();
for (int p = 0; p<np; ++p) {
ws.surface_rates[p] *= group_constraint.second;
}
}
return group_constraint.first;
}
}
if (well.isProducer( )) {
const auto currentControl = ws.production_cmode;
if (currentControl != Well::ProducerCMode::GRUP) {
// This checks only the first encountered group limit,
// in theory there could be several, and then we should
// test all but the one currently applied. At that point,
// this if-statement should be removed and we should always
// check, skipping over only the single group parent whose
// control is the active one for the well (if any).
const auto& group = schedule.getGroup(well.groupName(), well_.currentStep());
const Scalar efficiencyFactor = well.getEfficiencyFactor() *
well_state[well.name()].efficiency_scaling_factor;
const std::pair<bool, Scalar> group_constraint =
this->checkGroupConstraintsProd(group, groupStateHelper,
efficiencyFactor,
rateConverter,
check_guide_rate);
// If a group constraint was broken, we set the current well control to
// be GRUP.
if (group_constraint.first) {
ws.production_cmode = Well::ProducerCMode::GRUP;
const int np = well_state.numPhases();
for (int p = 0; p<np; ++p) {
ws.surface_rates[p] *= group_constraint.second;
}
}
return group_constraint.first;
}
}
return false;
}
template class WellGroupConstraints<double, BlackOilDefaultFluidSystemIndices>;
#if FLOW_INSTANTIATE_FLOAT
template class WellGroupConstraints<float, BlackOilDefaultFluidSystemIndices>;
#endif
} // namespace Opm