opm-simulators
Loading...
Searching...
No Matches
GroupConstraintCalculator.hpp
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>
27#include <opm/simulators/flow/rescoup/ReservoirCoupling.hpp>
28#include <opm/simulators/flow/rescoup/ReservoirCouplingMaster.hpp>
29#include <opm/simulators/utils/DeferredLogger.hpp>
30#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
31#include <opm/simulators/wells/BlackoilWellModelGeneric.hpp>
32#include <opm/simulators/wells/FractionCalculator.hpp>
33#include <opm/simulators/wells/GroupState.hpp>
34#include <opm/simulators/wells/TargetCalculator.hpp>
35#include <opm/simulators/wells/GroupStateHelper.hpp>
36#include <opm/simulators/wells/WellState.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 >;
70 using GroupStateHelperType = GroupStateHelper<Scalar, IndexTraits>;
71
73 enum class ConstraintType {
74 Target,
75 Limit
76 };
77
79 Scalar constraint; // Target or limit value
80 ControlMode cmode;
81 };
82
84 Scalar constraint; // Target or limit value
85 Group::ProductionCMode cmode;
86 };
87
89 Scalar constraint; // Target
90 Group::InjectionCMode cmode;
91 };
92
106 Scalar active_target;
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
125 class GeneralCalculator {
126 public:
127 using TargetCalculatorType = std::variant<std::monostate, TargetCalculator, InjectionTargetCalculator>;
128 GeneralCalculator(
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 );
135 GeneralCalculator(
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(); }
150 TargetCalculatorType getInjectionTargetCalculator(const Group& group);
151 TargetCalculatorType getProductionTargetCalculator(const Group& group) const;
152 TargetCalculatorType getTargetCalculator(const Group& group);
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);
165 Phase injectionPhase_() const;
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(); }
176 const BlackoilWellModelGeneric<Scalar, IndexTraits>& wellModel() const {
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:
182 GeneralCalculator(
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
214 class TopToBottomCalculator {
215 public:
216 using TargetCalculatorType = std::variant<std::monostate, TargetCalculator, InjectionTargetCalculator>;
217
218 constexpr static Scalar TARGET_RATE_TOLERANCE = 1e-12;
219
220 TopToBottomCalculator(
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:
334 const BlackoilWellModelGeneric<Scalar, IndexTraits>& well_model_;
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
Shared logic for injector and producer paths.
Definition GroupConstraintCalculator.hpp:125
std::optional< ProductionConstraintResult > groupProductionConstraints(const Group &group)
Compute per-rate-type production constraints for a group.
Definition GroupConstraintCalculator.cpp:96
std::optional< ProductionConstraintInfo > groupProductionTarget(const Group &group)
Compute production target for group.
Definition GroupConstraintCalculator.cpp:78
std::optional< InjectionConstraintInfo > groupInjectionTarget(const Group &group, ReservoirCoupling::Phase injection_phase)
Compute injection target for group in the given injection phase.
Definition GroupConstraintCalculator.cpp:59
std::variant< std::monostate, Group::InjectionCMode, Group::ProductionCMode > ControlMode
Union of control-mode types used by group constraint calculations.
Definition GroupConstraintCalculator.hpp:62
ConstraintType
Type of constraint to calculate: target or limit.
Definition GroupConstraintCalculator.hpp:73
GroupConstraintCalculator(const BlackoilWellModelGeneric< Scalar, IndexTraits > &well_model, const GroupStateHelperType &group_state_helper)
Construct a calculator bound to one report step and simulator state.
Definition GroupConstraintCalculator.cpp:34
Definition GroupStateHelper.hpp:57
DeferredLogger & deferredLogger() const
Get the deferred logger.
Definition GroupStateHelper.hpp:234
Definition FractionCalculator.hpp:40
Based on a group control mode, extract or calculate rates, and provide other conveniences.
Definition TargetCalculator.hpp:72
Based on a group control mode, extract or calculate rates, and provide other conveniences.
Definition TargetCalculator.hpp:39
Definition GroupState.hpp:41
Definition GasLiftGroupInfo.hpp:38
The state of a set of wells, tailored for use by the fully implicit blackoil simulator.
Definition WellState.hpp:66
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition blackoilbioeffectsmodules.hh:45
Generic result for a computed constraint and its control mode.
Definition GroupConstraintCalculator.hpp:78
Result for an injection constraint with its injection control mode.
Definition GroupConstraintCalculator.hpp:88
Result for a production constraint with its production control mode.
Definition GroupConstraintCalculator.hpp:83
Per-rate-type production constraints info for a group.
Definition GroupConstraintCalculator.hpp:105