GroupConstraintCalculator.hpp
Go to the documentation of this file.
1/*
2 Copyright 2025 Equinor ASA
3
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef OPM_GROUP_CONSTRAINT_CALCULATOR_HPP
21#define OPM_GROUP_CONSTRAINT_CALCULATOR_HPP
22#include <opm/common/ErrorMacros.hpp>
23#include <opm/input/eclipse/EclipseState/Phase.hpp>
24#include <opm/input/eclipse/Schedule/Schedule.hpp>
25#include <opm/input/eclipse/Schedule/Group/GConSale.hpp>
26#include <opm/input/eclipse/Schedule/Group/Group.hpp>
37
38#include <variant>
39#include <optional>
40#include <vector>
41#include <string>
42
43namespace Opm {
44
54template<class Scalar, class IndexTraits>
56public:
62 using ControlMode = std::variant<
63 std::monostate,
64 Group::InjectionCMode,
65 Group::ProductionCMode
66 >;
71
73 enum class ConstraintType {
74 Target,
75 Limit
76 };
79 Scalar constraint; // Target or limit value
81 };
84 Scalar constraint; // Target or limit value
85 Group::ProductionCMode cmode;
86 };
89 Scalar constraint; // Target
90 Group::InjectionCMode cmode;
91 };
107 Group::ProductionCMode active_cmode;
108 Scalar oil_limit = -1;
109 Scalar water_limit = -1;
110 Scalar gas_limit = -1;
111 Scalar liquid_limit = -1;
112 Scalar resv_limit = -1;
113 };
114
126 public:
127 using TargetCalculatorType = std::variant<std::monostate, TargetCalculator, InjectionTargetCalculator>;
129 GroupConstraintCalculator& calculator,
130 const Group& original_group, // the bottom group we want to calculate the target for
131 std::optional<ReservoirCoupling::Phase> injection_phase = std::nullopt
132 );
136 GroupConstraintCalculator& calculator,
137 const Group& original_group,
138 Group::ProductionCMode explicit_cmode
139 );
140 std::optional<ConstraintInfo> calculateGroupConstraint();
141 ConstraintType constraintType() const { return this->constraint_type_; }
142 DeferredLogger& deferredLogger() { return this->parent_calculator_.deferredLogger(); }
143 // Const overload: allows logging from const methods.
144 DeferredLogger& deferredLogger() const { return this->parent_calculator_.deferredLogger(); }
145 int fipnum() const { return this->parent_calculator_.fipnum(); }
146 const GConSale& gconsale() const {
147 return this->schedule()[this->reportStepIdx()].gconsale();
148 }
149 const GroupState<Scalar>& groupState() const { return this->parent_calculator_.groupState(); }
153 std::optional<ConstraintInfo> getGroupConstraintNoGuideRate(const Group& group);
154 std::optional<Group::ProductionCMode> getProdCmode(const Group& group) const;
155 Group::ProductionCMode getProdCmode() const;
156 const GuideRate& guideRate() const { return this->parent_calculator_.guideRate(); }
157 bool hasGuideRate(const Group& group) const { return this->hasGuideRate(group.name()); }
158 bool hasGuideRate(const std::string& name) const {
159 if (this->isInjectionConstraint()) {
160 return this->guideRate().has(name, this->injectionPhase_());
161 }
162 return this->guideRate().has(name);
163 }
164 bool hasHigherLevelControlOrNoLimit(const Group& group);
166 bool isInjectionConstraint() const { return this->injection_phase_.has_value(); }
167 bool isProductionConstraint() const { return !this->injection_phase_.has_value(); }
168 const Group& originalGroup() const { return this->original_group_; }
169 const PhaseUsageInfo<IndexTraits>& phaseUsage() const { return this->parent_calculator_.phaseUsage(); }
170 int pvtreg() const { return this->parent_calculator_.pvtreg(); }
171 int reportStepIdx() const { return this->parent_calculator_.reportStepIdx(); }
172 const std::vector<Scalar>& resvCoeffsInj() const { return this->parent_calculator_.resvCoeffsInj(); }
173 const std::vector<Scalar>& resvCoeffsProd() const { return this->resv_coeffs_prod_; }
174 const Schedule& schedule() const { return this->parent_calculator_.schedule(); }
175 const SummaryState& summaryState() const { return this->parent_calculator_.summaryState(); }
177 return this->parent_calculator_.wellModel();
178 }
179 const WellState<Scalar, IndexTraits>& wellState() const { return this->parent_calculator_.wellState(); }
180 const GroupStateHelperType& groupStateHelper() const { return this->parent_calculator_.groupStateHelper(); }
181 private:
184 const Group& original_group,
185 std::optional<ReservoirCoupling::Phase> injection_phase, // Only used for injectors
186 std::optional<Group::ProductionCMode> production_cmode,
187 ConstraintType constraint_type
188 );
189 std::optional<ConstraintInfo> calculateGroupConstraintRecursive_(
190 const Group& group, const Scalar efficiency_factor);
191 const Group& parentGroup(const Group& group) const {
192 return this->schedule().getGroup(group.parent(), this->reportStepIdx());
193 }
194 bool parentGroupControlAvailable_(const Group& group);
195 Phase reservoirCouplingToOpmPhase_(ReservoirCoupling::Phase reservoir_coupling_phase) const;
196
197 GroupConstraintCalculator& parent_calculator_;
198 const Group& original_group_; // The bottom group we want to calculate the target for
199 std::optional<ReservoirCoupling::Phase> injection_phase_;
200 ControlMode control_mode_;
201 ConstraintType constraint_type_;
202 std::vector<Scalar> resv_coeffs_prod_;
203 };
204
215 public:
216 using TargetCalculatorType = std::variant<std::monostate, TargetCalculator, InjectionTargetCalculator>;
217
218 constexpr static Scalar TARGET_RATE_TOLERANCE = 1e-12;
219
221 GeneralCalculator& parent_calculator,
222 const Group& top_group,
223 const Group& bottom_group,
224 Scalar efficiency_factor
225 );
226
227 std::optional<ConstraintInfo> calculateGroupConstraint();
228 ConstraintType constraintType() const { return this->parent_calculator_.constraintType(); }
229 DeferredLogger& deferredLogger() { return this->parent_calculator_.deferredLogger(); }
230 // Const overload: allows logging from const methods (logical constness for external logger).
231 DeferredLogger& deferredLogger() const { return this->parent_calculator_.deferredLogger(); }
232 Group::ProductionCMode getProdCmode() const { return this->parent_calculator_.getProdCmode(); }
233 std::optional<Group::ProductionCMode> getProdCmode(const Group& group) const {
234 return this->parent_calculator_.getProdCmode(group);
235 }
236 const GroupState<Scalar>& groupState() const { return this->parent_calculator_.groupState(); }
237 const GuideRate& guideRate() const { return this->parent_calculator_.guideRate(); }
238 bool isInjectionConstraint() const { return this->parent_calculator_.isInjectionConstraint(); }
239 bool isProductionConstraint() const { return this->parent_calculator_.isProductionConstraint(); }
240 const PhaseUsageInfo<IndexTraits>& phaseUsage() const { return this->parent_calculator_.phaseUsage(); }
241 int reportStepIdx() const { return this->parent_calculator_.reportStepIdx(); }
242 const std::vector<Scalar>& resvCoeffsInj() const { return this->parent_calculator_.resvCoeffsInj(); }
243 const std::vector<Scalar>& resvCoeffsProd() const { return this->parent_calculator_.resvCoeffsProd(); }
244 const Schedule& schedule() const { return this->parent_calculator_.schedule(); }
245 const SummaryState& summaryState() const { return this->parent_calculator_.summaryState(); }
246 const WellState<Scalar, IndexTraits>& wellState() const { return this->parent_calculator_.wellState(); }
247 const GroupStateHelperType& groupStateHelper() const { return this->parent_calculator_.groupStateHelper(); }
248
249 private:
250 bool bottomGroupHasIndividualControl_();
251 Scalar computeAddbackEfficiency_(const std::vector<std::string>& chain,
252 const std::size_t local_reduction_level) const;
253 Scalar getBottomGroupCurrentRateAvailable_() const;
254 std::vector<std::string> getGroupChainTopBot_() const;
255 std::size_t getLocalReductionLevel_(const std::vector<std::string>& chain);
256 TargetCalculatorType getProductionTargetCalculator_(const Group& group) const {
257 return this->parent_calculator_.getProductionTargetCalculator(group); }
258 TargetCalculatorType getInjectionTargetCalculator_(const Group& group) const {
259 return this->parent_calculator_.getInjectionTargetCalculator(group); }
260 TargetCalculatorType getInjectionTargetCalculator(const Group& group) const;
261 TargetCalculatorType getProductionTargetCalculator(const Group& group) const;
268 Scalar getSlaveGroupReservoirRate_(const Group& master_group);
269 std::optional<ConstraintInfo> getGroupConstraintNoGuideRate_(const Group& group) const {
270 return this->parent_calculator_.getGroupConstraintNoGuideRate(group);
271 }
272 ControlMode getToplevelControlMode_() const;
273 Scalar getTopLevelTargetOrLimit_();
274 bool hasHigherLevelControlOrNoLimit(const Group& group) {
275 return this->parent_calculator_.hasHigherLevelControlOrNoLimit(group);
276 }
277 bool hasFLDControl_(const Group& group) const;
278 bool hasGuideRate_(const std::string& name) const {
279 return this->parent_calculator_.hasGuideRate(name);
280 }
281 void initForInjector_();
282 void initForProducer_();
283 Phase injectionPhase_() const { return this->parent_calculator_.injectionPhase_(); }
284 bool isProducerAndRESVControl_(const Group& group) const;
285 Scalar localFraction_(const std::string& group_name);
286 Scalar localReduction_(const std::string& group_name);
287
288 GeneralCalculator& parent_calculator_;
289 const Group& top_group_;
290 const Group& bottom_group_;
291 // Accumulated efficiency factor along the chain from top to bottom, excluding the top group.
292 Scalar chain_efficiency_factor_;
293 // Active calculator used for distributing the target along the chain:
294 // either production TargetCalculator or InjectionTargetCalculator.
295 std::variant<std::monostate, TargetCalculator, InjectionTargetCalculator> target_calculator_;
296 // Since FractionCalculator does not have a default constructor, we use std::optional
297 // to conditionally initialize it based on whether we are dealing with an injector or producer.
298 std::optional<FractionCalculator> fraction_calculator_;
299 };
300
306 const GroupStateHelperType& group_state_helper
307 );
308 DeferredLogger& deferredLogger() { return this->group_state_helper_.deferredLogger(); }
309 // Const overload: allows logging from const methods.
310 DeferredLogger& deferredLogger() const { return this->group_state_helper_.deferredLogger(); }
311 int fipnum() const { return this->fipnum_; }
313 std::optional<InjectionConstraintInfo> groupInjectionTarget(
314 const Group& group, ReservoirCoupling::Phase injection_phase
315 );
317 std::optional<ProductionConstraintInfo> groupProductionTarget(const Group& group);
321 std::optional<ProductionConstraintResult> groupProductionConstraints(const Group& group);
322 const GroupState<Scalar>& groupState() const { return this->group_state_; }
323 const GuideRate& guideRate() const { return this->guide_rate_; }
324 const PhaseUsageInfo<IndexTraits>& phaseUsage() const { return this->phase_usage_; }
325 int pvtreg() const { return this->pvtreg_; }
326 int reportStepIdx() const { return this->report_step_idx_; }
327 const std::vector<Scalar>& resvCoeffsInj() const { return this->resv_coeffs_inj_; }
328 const Schedule& schedule() const { return this->schedule_; }
329 const SummaryState& summaryState() const { return this->summary_state_; }
330 const BlackoilWellModelGeneric<Scalar, IndexTraits>& wellModel() const { return this->well_model_; }
331 const WellState<Scalar, IndexTraits>& wellState() const { return this->well_state_; }
332 const GroupStateHelperType& groupStateHelper() const { return this->group_state_helper_; }
333private:
335 const GroupStateHelperType& group_state_helper_;
336 const WellState<Scalar, IndexTraits >& well_state_;
337 const GroupState<Scalar>& group_state_;
338 const Schedule& schedule_;
339 const SummaryState& summary_state_;
340 const PhaseUsageInfo<IndexTraits>& phase_usage_;
341 const GuideRate& guide_rate_;
342 int report_step_idx_;
343 std::vector<Scalar> resv_coeff_;
344 int fipnum_; // FIP region for the groups
345 int pvtreg_; // PVT region for the groups
346 std::vector<Scalar> resv_coeffs_inj_;
347};
348
349} // namespace Opm
350
351#endif // OPM_GROUP_CONSTRAINT_CALCULATOR_HPP
Class for handling the blackoil well model.
Definition: BlackoilWellModelGeneric.hpp:97
Definition: DeferredLogger.hpp:57
Definition: GroupConstraintCalculator.hpp:125
const GroupStateHelperType & groupStateHelper() const
Definition: GroupConstraintCalculator.hpp:180
int reportStepIdx() const
Definition: GroupConstraintCalculator.hpp:171
const std::vector< Scalar > & resvCoeffsProd() const
Definition: GroupConstraintCalculator.hpp:173
Group::ProductionCMode getProdCmode() const
bool isProductionConstraint() const
Definition: GroupConstraintCalculator.hpp:167
const std::vector< Scalar > & resvCoeffsInj() const
Definition: GroupConstraintCalculator.hpp:172
int pvtreg() const
Definition: GroupConstraintCalculator.hpp:170
std::optional< ConstraintInfo > getGroupConstraintNoGuideRate(const Group &group)
bool hasGuideRate(const std::string &name) const
Definition: GroupConstraintCalculator.hpp:158
TargetCalculatorType getTargetCalculator(const Group &group)
bool isInjectionConstraint() const
Definition: GroupConstraintCalculator.hpp:166
std::variant< std::monostate, TargetCalculator, InjectionTargetCalculator > TargetCalculatorType
Definition: GroupConstraintCalculator.hpp:127
ConstraintType constraintType() const
Definition: GroupConstraintCalculator.hpp:141
const BlackoilWellModelGeneric< Scalar, IndexTraits > & wellModel() const
Definition: GroupConstraintCalculator.hpp:176
const Schedule & schedule() const
Definition: GroupConstraintCalculator.hpp:174
const PhaseUsageInfo< IndexTraits > & phaseUsage() const
Definition: GroupConstraintCalculator.hpp:169
DeferredLogger & deferredLogger() const
Definition: GroupConstraintCalculator.hpp:144
const WellState< Scalar, IndexTraits > & wellState() const
Definition: GroupConstraintCalculator.hpp:179
const SummaryState & summaryState() const
Definition: GroupConstraintCalculator.hpp:175
std::optional< ConstraintInfo > calculateGroupConstraint()
bool hasHigherLevelControlOrNoLimit(const Group &group)
TargetCalculatorType getProductionTargetCalculator(const Group &group) const
const GConSale & gconsale() const
Definition: GroupConstraintCalculator.hpp:146
const GroupState< Scalar > & groupState() const
Definition: GroupConstraintCalculator.hpp:149
const Group & originalGroup() const
Definition: GroupConstraintCalculator.hpp:168
std::optional< Group::ProductionCMode > getProdCmode(const Group &group) const
GeneralCalculator(GroupConstraintCalculator &calculator, const Group &original_group, std::optional< ReservoirCoupling::Phase > injection_phase=std::nullopt)
GeneralCalculator(GroupConstraintCalculator &calculator, const Group &original_group, Group::ProductionCMode explicit_cmode)
const GuideRate & guideRate() const
Definition: GroupConstraintCalculator.hpp:156
DeferredLogger & deferredLogger()
Definition: GroupConstraintCalculator.hpp:142
bool hasGuideRate(const Group &group) const
Definition: GroupConstraintCalculator.hpp:157
int fipnum() const
Definition: GroupConstraintCalculator.hpp:145
TargetCalculatorType getInjectionTargetCalculator(const Group &group)
Definition: GroupConstraintCalculator.hpp:214
std::optional< ConstraintInfo > calculateGroupConstraint()
std::optional< Group::ProductionCMode > getProdCmode(const Group &group) const
Definition: GroupConstraintCalculator.hpp:233
const GuideRate & guideRate() const
Definition: GroupConstraintCalculator.hpp:237
bool isProductionConstraint() const
Definition: GroupConstraintCalculator.hpp:239
const std::vector< Scalar > & resvCoeffsProd() const
Definition: GroupConstraintCalculator.hpp:243
const SummaryState & summaryState() const
Definition: GroupConstraintCalculator.hpp:245
const GroupState< Scalar > & groupState() const
Definition: GroupConstraintCalculator.hpp:236
Group::ProductionCMode getProdCmode() const
Definition: GroupConstraintCalculator.hpp:232
DeferredLogger & deferredLogger() const
Definition: GroupConstraintCalculator.hpp:231
const std::vector< Scalar > & resvCoeffsInj() const
Definition: GroupConstraintCalculator.hpp:242
DeferredLogger & deferredLogger()
Definition: GroupConstraintCalculator.hpp:229
std::variant< std::monostate, TargetCalculator, InjectionTargetCalculator > TargetCalculatorType
Definition: GroupConstraintCalculator.hpp:216
TopToBottomCalculator(GeneralCalculator &parent_calculator, const Group &top_group, const Group &bottom_group, Scalar efficiency_factor)
ConstraintType constraintType() const
Definition: GroupConstraintCalculator.hpp:228
static constexpr Scalar TARGET_RATE_TOLERANCE
Definition: GroupConstraintCalculator.hpp:218
const PhaseUsageInfo< IndexTraits > & phaseUsage() const
Definition: GroupConstraintCalculator.hpp:240
const WellState< Scalar, IndexTraits > & wellState() const
Definition: GroupConstraintCalculator.hpp:246
int reportStepIdx() const
Definition: GroupConstraintCalculator.hpp:241
const Schedule & schedule() const
Definition: GroupConstraintCalculator.hpp:244
const GroupStateHelperType & groupStateHelper() const
Definition: GroupConstraintCalculator.hpp:247
bool isInjectionConstraint() const
Definition: GroupConstraintCalculator.hpp:238
Definition: GroupConstraintCalculator.hpp:55
std::optional< InjectionConstraintInfo > groupInjectionTarget(const Group &group, ReservoirCoupling::Phase injection_phase)
int fipnum() const
Definition: GroupConstraintCalculator.hpp:311
const BlackoilWellModelGeneric< Scalar, IndexTraits > & wellModel() const
Definition: GroupConstraintCalculator.hpp:330
const GroupState< Scalar > & groupState() const
Definition: GroupConstraintCalculator.hpp:322
const Schedule & schedule() const
Definition: GroupConstraintCalculator.hpp:328
DeferredLogger & deferredLogger() const
Definition: GroupConstraintCalculator.hpp:310
const WellState< Scalar, IndexTraits > & wellState() const
Definition: GroupConstraintCalculator.hpp:331
int pvtreg() const
Definition: GroupConstraintCalculator.hpp:325
std::optional< ProductionConstraintResult > groupProductionConstraints(const Group &group)
const PhaseUsageInfo< IndexTraits > & phaseUsage() const
Definition: GroupConstraintCalculator.hpp:324
const GuideRate & guideRate() const
Definition: GroupConstraintCalculator.hpp:323
const std::vector< Scalar > & resvCoeffsInj() const
Definition: GroupConstraintCalculator.hpp:327
const GroupStateHelperType & groupStateHelper() const
Definition: GroupConstraintCalculator.hpp:332
std::variant< std::monostate, Group::InjectionCMode, Group::ProductionCMode > ControlMode
Definition: GroupConstraintCalculator.hpp:66
const SummaryState & summaryState() const
Definition: GroupConstraintCalculator.hpp:329
std::optional< ProductionConstraintInfo > groupProductionTarget(const Group &group)
GroupStateHelper< Scalar, IndexTraits > GroupStateHelperType
Definition: GroupConstraintCalculator.hpp:70
int reportStepIdx() const
Definition: GroupConstraintCalculator.hpp:326
DeferredLogger & deferredLogger()
Definition: GroupConstraintCalculator.hpp:308
ConstraintType
Definition: GroupConstraintCalculator.hpp:73
GroupConstraintCalculator(const BlackoilWellModelGeneric< Scalar, IndexTraits > &well_model, const GroupStateHelperType &group_state_helper)
Definition: GroupStateHelper.hpp:55
DeferredLogger & deferredLogger() const
Get the deferred logger.
Definition: GroupStateHelper.hpp:227
Definition: FractionCalculator.hpp:40
Definition: TargetCalculator.hpp:72
Definition: TargetCalculator.hpp:39
Definition: GroupState.hpp:41
Definition: GasLiftGroupInfo.hpp:38
Definition: WellState.hpp:66
Phase
Phase indices for reservoir coupling, we currently only support black-oil phases (oil,...
Definition: ReservoirCoupling.hpp:156
Definition: blackoilbioeffectsmodules.hh:45
Definition: GroupConstraintCalculator.hpp:78
ControlMode cmode
Definition: GroupConstraintCalculator.hpp:80
Scalar constraint
Definition: GroupConstraintCalculator.hpp:79
Definition: GroupConstraintCalculator.hpp:88
Group::InjectionCMode cmode
Definition: GroupConstraintCalculator.hpp:90
Scalar constraint
Definition: GroupConstraintCalculator.hpp:89
Definition: GroupConstraintCalculator.hpp:83
Group::ProductionCMode cmode
Definition: GroupConstraintCalculator.hpp:85
Scalar constraint
Definition: GroupConstraintCalculator.hpp:84
Definition: GroupConstraintCalculator.hpp:105
Scalar active_target
Definition: GroupConstraintCalculator.hpp:106
Group::ProductionCMode active_cmode
Definition: GroupConstraintCalculator.hpp:107
Scalar oil_limit
Definition: GroupConstraintCalculator.hpp:108
Scalar gas_limit
Definition: GroupConstraintCalculator.hpp:110
Scalar liquid_limit
Definition: GroupConstraintCalculator.hpp:111
Scalar water_limit
Definition: GroupConstraintCalculator.hpp:109
Scalar resv_limit
Definition: GroupConstraintCalculator.hpp:112